]> git.mxchange.org Git - simgear.git/blobdiff - simgear/hla/RTI13Federate.cxx
hla: Route failures in message processing into the HLA layer.
[simgear.git] / simgear / hla / RTI13Federate.cxx
index 08dbdd8616f43ec600d93b348973971548c5f2a6..9ceb828332938cfdb4b77f56f651a779f615ef5b 100644 (file)
@@ -1,4 +1,4 @@
-// Copyright (C) 2009 - 2011  Mathias Froehlich - Mathias.Froehlich@web.de
+// Copyright (C) 2009 - 2012  Mathias Froehlich - Mathias.Froehlich@web.de
 //
 // This library is free software; you can redistribute it and/or
 // modify it under the terms of the GNU Library General Public
 // Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
 //
 
+#ifdef HAVE_CONFIG_H
+#  include <simgear_config.h>
+#endif
+
+#include <simgear/compiler.h>
+
 #include "RTI13Federate.hxx"
 
 #include "RTI13Ambassador.hxx"
@@ -222,7 +228,7 @@ struct RTI13Federate::FederateAmbassador : public RTI::FederateAmbassador {
             return;
         if (!i->second.valid())
             return;
-        SGSharedPtr<RTI13ObjectInstance> objectInstance = new RTI13ObjectInstance(objectHandle, 0, i->second, _rtiAmbassador.get(), false);
+        SGSharedPtr<RTI13ObjectInstance> objectInstance = new RTI13ObjectInstance(objectHandle, 0, i->second, _rtiAmbassador.get());
         _objectInstanceMap[objectHandle] = objectInstance;
         i->second->discoverInstance(objectInstance.get(), tag);
     }
@@ -278,7 +284,7 @@ struct RTI13Federate::FederateAmbassador : public RTI::FederateAmbassador {
             return;
         if (!i->second.valid())
             return;
-        i->second->reflectAttributeValues(attributeHandleDataPairList, timeStamp, tag);
+        i->second->reflectAttributeValues(attributeHandleDataPairList, timeStamp, tag, _indexPool);
     }
 
     class ReflectAttributeValuesCallback : public TagQueueCallback {
@@ -327,7 +333,7 @@ struct RTI13Federate::FederateAmbassador : public RTI::FederateAmbassador {
             return;
         if (!i->second.valid())
             return;
-        i->second->reflectAttributeValues(attributeHandleDataPairList, tag);
+        i->second->reflectAttributeValues(attributeHandleDataPairList, tag, _indexPool);
     }
 
     virtual void receiveInteraction(RTI::InteractionClassHandle interactionClassHandle, const RTI::ParameterHandleValuePairSet& parameters,
@@ -855,6 +861,9 @@ struct RTI13Federate::FederateAmbassador : public RTI::FederateAmbassador {
     void freeAttributeHandleDataPairList(RTI13AttributeHandleDataPairList& attributeHandleDataPairList)
     { _attributeHandleDataPairPool.splice(_attributeHandleDataPairPool.end(), attributeHandleDataPairList); }
 
+    // For attribute reflection, pool or indices
+    HLAIndexList _indexPool;
+
     // Top level information for dispatching federate object attribute updates
     typedef std::map<RTI::ObjectHandle, SGSharedPtr<RTI13ObjectInstance> > ObjectInstanceMap;
     // Map of all available objects
@@ -864,6 +873,10 @@ struct RTI13Federate::FederateAmbassador : public RTI::FederateAmbassador {
     typedef std::map<RTI::ObjectClassHandle, SGSharedPtr<RTI13ObjectClass> > ObjectClassMap;
     ObjectClassMap _objectClassMap;
 
+    // Top level information for dispatching creation of federate objects
+    typedef std::map<RTI::InteractionClassHandle, SGSharedPtr<RTI13InteractionClass> > InteractionClassMap;
+    InteractionClassMap _interactionClassMap;
+
     bool _timeRegulationEnabled;
     bool _timeConstrainedEnabled;
     bool _timeAdvancePending;
@@ -1550,29 +1563,80 @@ RTI13Federate::queryLITS(SGTimeStamp& timeStamp)
     return true;
 }
 
-bool
+RTI13Federate::ProcessMessageResult
 RTI13Federate::processMessage()
 {
-    bool result = _ambassador->tick();
+    ProcessMessageResult result = _tick();
     _federateAmbassador->processQueues();
     return result;
 }
 
-bool
+RTI13Federate::ProcessMessageResult
 RTI13Federate::processMessages(const double& minimum, const double& maximum)
 {
-    bool result = _ambassador->tick(minimum, 0);
+    ProcessMessageResult result = _tick(minimum, 0);
     _federateAmbassador->processQueues();
-    if (!result)
-        return false;
+    if (result != ProcessMessagePending)
+        return result;
     SGTimeStamp timeStamp = SGTimeStamp::now() + SGTimeStamp::fromSec(maximum);
     do {
-        result = _ambassador->tick(0, 0);
+        result = _tick(0, 0);
         _federateAmbassador->processQueues();
-    } while (result && SGTimeStamp::now() <= timeStamp);
+    } while (result == ProcessMessagePending && SGTimeStamp::now() <= timeStamp);
     return result;
 }
 
+RTI13Federate::ProcessMessageResult
+RTI13Federate::_tick()
+{
+    if (!_ambassador.valid()) {
+        SG_LOG(SG_NETWORK, SG_WARN, "RTI: Ambassador is zero while calling _tick().");
+        return ProcessMessageFatal;
+    }
+
+    try {
+        if (_ambassador->tick())
+            return ProcessMessagePending;
+        return ProcessMessageLast;
+    } catch (RTI::SpecifiedSaveLabelDoesNotExist& e) {
+        SG_LOG(SG_NETWORK, SG_WARN, "RTI: Specified save label does not exist: " << e._name << " " << e._reason);
+        return ProcessMessageFatal;
+    } catch (RTI::ConcurrentAccessAttempted& e) {
+        SG_LOG(SG_NETWORK, SG_WARN, "RTI: Concurrent access attempted: " << e._name << " " << e._reason);
+        return ProcessMessageFatal;
+    } catch (RTI::RTIinternalError& e) {
+        SG_LOG(SG_NETWORK, SG_WARN, "RTI: Internal error: " << e._name << " " << e._reason);
+        return ProcessMessageFatal;
+    }
+    return ProcessMessageFatal;
+}
+
+RTI13Federate::ProcessMessageResult
+RTI13Federate::_tick(const double& minimum, const double& maximum)
+{
+    if (!_ambassador.valid()) {
+        SG_LOG(SG_NETWORK, SG_WARN, "RTI: Ambassador is zero while calling _tick().");
+        return ProcessMessageFatal;
+    }
+
+    try {
+        if (_ambassador->tick(minimum, maximum))
+            return ProcessMessagePending;
+        return ProcessMessageLast;
+    } catch (RTI::SpecifiedSaveLabelDoesNotExist& e) {
+        SG_LOG(SG_NETWORK, SG_WARN, "RTI: Specified save label does not exist: " << e._name << " " << e._reason);
+        return ProcessMessageFatal;
+    } catch (RTI::ConcurrentAccessAttempted& e) {
+        SG_LOG(SG_NETWORK, SG_WARN, "RTI: Concurrent access attempted: " << e._name << " " << e._reason);
+        return ProcessMessageFatal;
+    } catch (RTI::RTIinternalError& e) {
+        SG_LOG(SG_NETWORK, SG_WARN, "RTI: Internal error: " << e._name << " " << e._reason);
+        return ProcessMessageFatal;
+    }
+    return ProcessMessageFatal;
+}
+
+
 RTI13ObjectClass*
 RTI13Federate::createObjectClass(const std::string& objectClassName, HLAObjectClass* hlaObjectClass)
 {
@@ -1602,6 +1666,35 @@ RTI13Federate::createObjectClass(const std::string& objectClassName, HLAObjectCl
     }
 }
 
+RTI13InteractionClass*
+RTI13Federate::createInteractionClass(const std::string& interactionClassName, HLAInteractionClass* interactionClass)
+{
+    try {
+        RTI::InteractionClassHandle interactionClassHandle;
+        interactionClassHandle = _ambassador->getInteractionClassHandle(interactionClassName);
+        if (_federateAmbassador->_interactionClassMap.find(interactionClassHandle) != _federateAmbassador->_interactionClassMap.end()) {
+            SG_LOG(SG_NETWORK, SG_WARN, "RTI: Could not create interaction class, interaction class already exists!");
+            return 0;
+        }
+        RTI13InteractionClass* rtiInteractionClass;
+        rtiInteractionClass = new RTI13InteractionClass(interactionClass, interactionClassHandle, _ambassador.get());
+        _federateAmbassador->_interactionClassMap[interactionClassHandle] = rtiInteractionClass;
+        return rtiInteractionClass;
+    } catch (RTI::NameNotFound& e) {
+        SG_LOG(SG_NETWORK, SG_WARN, "RTI: Could not get interaction class: " << e._name << " " << e._reason);
+        return 0;
+    } catch (RTI::FederateNotExecutionMember& e) {
+        SG_LOG(SG_NETWORK, SG_WARN, "RTI: Could not get interaction class: " << e._name << " " << e._reason);
+        return 0;
+    } catch (RTI::ConcurrentAccessAttempted& e) {
+        SG_LOG(SG_NETWORK, SG_WARN, "RTI: Could not get interaction class: " << e._name << " " << e._reason);
+        return 0;
+    } catch (RTI::RTIinternalError& e) {
+        SG_LOG(SG_NETWORK, SG_WARN, "RTI: Could not get interaction class: " << e._name << " " << e._reason);
+        return 0;
+    }
+}
+
 RTI13ObjectInstance*
 RTI13Federate::getObjectInstance(const std::string& objectInstanceName)
 {