]> git.mxchange.org Git - flightgear.git/commitdiff
hla: Use hla derived classes part 1.
authorMathias Froehlich <Mathias.Froehlich@web.de>
Sat, 10 Nov 2012 16:19:33 +0000 (17:19 +0100)
committerMathias Froehlich <Mathias.Froehlich@web.de>
Sun, 11 Nov 2012 15:30:36 +0000 (16:30 +0100)
src/Network/HLA/hla.cxx
src/Network/HLA/hla.hxx

index b3923a75cb6a6e76d7262e6b02399a2b6e27c186..8d91e88e98dc9d3bc26cbe4e3dfd46906e791c31 100644 (file)
@@ -24,8 +24,8 @@
 
 #include <simgear/compiler.h>
 
-#include <string>
-
+#include <algorithm>
+#include <list>
 #include <map>
 #include <string>
 #include <stack>
@@ -865,12 +865,76 @@ private:
     sg::HLADataElement::IndexPathPair _mpPropertiesIndexPathPair;
 };
 
+class FGHLA::MultiplayerObjectInstance : public sg::HLAObjectInstance {
+public:
+    MultiplayerObjectInstance(sg::HLAObjectClass* objectClass) :
+        sg::HLAObjectInstance(objectClass)
+    { }
+    virtual ~MultiplayerObjectInstance()
+    { }
+};
+
+class FGHLA::MultiplayerObjectClass : public sg::HLAObjectClass {
+public:
+    MultiplayerObjectClass(const std::string& name, sg::HLAFederate* federate) :
+        HLAObjectClass(name, federate)
+    { }
+    virtual ~MultiplayerObjectClass()
+    { }
+
+    virtual MultiplayerObjectInstance* createObjectInstance(const std::string& name)
+    { return new MultiplayerObjectInstance(this); }
+};
+
 class FGHLA::Federate : public sg::HLAFederate {
 public:
     virtual ~Federate()
     { }
     virtual bool readObjectModel()
     { return readRTI1516ObjectModelTemplate(getFederationObjectModel()); }
+
+    virtual sg::HLAObjectClass* createObjectClass(const std::string& name)
+    {
+        if (std::find(_multiplayerObjectClassNames.begin(), _multiplayerObjectClassNames.end(), name)
+            != _multiplayerObjectClassNames.end()) {
+            if (_localAircraftClass.valid()) {
+                return new MultiplayerObjectClass(name, this);
+            } else {
+                _localAircraftClass = new MultiplayerObjectClass(name, this);
+                return _localAircraftClass.get();
+            }
+        } else {
+            return 0;
+        }
+    }
+
+    void updateLocalAircraftInstance()
+    {
+        // First push our own data so that others can recieve ...
+        if (!_localAircraftClass.valid())
+            return;
+        if (!_localAircraftInstance.valid()) {
+            _localAircraftInstance = new MultiplayerObjectInstance(_localAircraftClass.get());
+            _localAircraftInstance->registerInstance();
+        }
+        _localAircraftInstance->updateAttributeValues(sg::RTIData("MPAircraft"));
+    }
+
+    virtual bool shutdown()
+    {
+        if (_localAircraftInstance.valid()) {
+            // Remove the local object from the rti
+            _localAircraftInstance->deleteInstance(simgear::RTIData("gone"));
+            _localAircraftInstance = 0;
+        }
+        return HLAFederate::shutdown();
+    }
+
+    std::list<std::string> _multiplayerObjectClassNames;
+    /// This class is used to register the local instance and to subscribe for others
+    SGSharedPtr<MultiplayerObjectClass> _localAircraftClass;
+    /// The local aircraft instance
+    SGSharedPtr<MultiplayerObjectInstance> _localAircraftInstance;
 };
 
 FGHLA::FGHLA(const std::vector<std::string>& tokens) :
@@ -989,6 +1053,21 @@ FGHLA::open()
     _hlaFederate->setFederationObjectModel(objectModel);
     _hlaFederate->setFederateType(_federate);
 
+    // Store the multiplayer class name in the federate
+    XMLConfigReader::ObjectClassConfigList::const_iterator i;
+    for (i = configReader.getObjectClassConfigList().begin();
+         i != configReader.getObjectClassConfigList().end(); ++i) {
+
+        if (i->_type != "Multiplayer") {
+            SG_LOG(SG_IO, SG_ALERT, "Ignoring unknown object class type \"" << i->_type << "\"!");
+            continue;
+        }
+
+        // Register the object class that we need for this simple hla implementation
+        _hlaFederate->_multiplayerObjectClassNames.push_back(i->_name);
+    }
+
+
     // Now that it is paramtrized, connect/join
     if (!_hlaFederate->init()) {
         SG_LOG(SG_IO, SG_ALERT, "Could not init the hla/rti connect.");
@@ -998,22 +1077,20 @@ FGHLA::open()
     // bool publish = get_direction() & SG_IO_OUT;
     // bool subscribe = get_direction() & SG_IO_IN;
 
-    // This should be configured form a file
-    XMLConfigReader::ObjectClassConfigList::const_iterator i;
+    // Interpret the configuration file
     for (i = configReader.getObjectClassConfigList().begin();
          i != configReader.getObjectClassConfigList().end(); ++i) {
 
-        if (i->_type != "Multiplayer") {
-            SG_LOG(SG_IO, SG_ALERT, "Ignoring unknown object class type \"" << i->_type << "\"!");
+        /// already warned about this above
+        if (i->_type != "Multiplayer")
             continue;
-        }
 
         /// The object class for HLA aircraft
-        SGSharedPtr<simgear::HLAObjectClass> objectClass;
+        SGSharedPtr<MultiplayerObjectClass> objectClass;
 
         // Register the object class that we need for this simple hla implementation
         std::string aircraftClassName = i->_name;
-        objectClass = _hlaFederate->getObjectClass(aircraftClassName);
+        objectClass = dynamic_cast<MultiplayerObjectClass*>(_hlaFederate->getObjectClass(aircraftClassName));
         if (!objectClass.valid()) {
             SG_LOG(SG_IO, SG_ALERT, "Could not find " << aircraftClassName << " object class!");
             continue;
@@ -1255,9 +1332,6 @@ FGHLA::open()
         }
 
         objectClass->setInstanceCallback(mpClassCallback);
-
-        if (i->_type == "Multiplayer")
-            _localAircraftClass = objectClass;
     }
 
     set_enabled(true);
@@ -1270,21 +1344,15 @@ FGHLA::process()
     if (!is_enabled())
         return false;
 
+    if (!_hlaFederate.valid())
+        return false;
+
     // First push our own data so that others can recieve ...
-    if (get_direction() & SG_IO_OUT) {
-        if (fgGetBool("/sim/fdm-initialized", false) && _localAircraftClass.valid()) {
-            if (!_localAircraftInstance.valid()) {
-                _localAircraftInstance = new sg::HLAObjectInstance(_localAircraftClass.get());
-                _localAircraftInstance->registerInstance();
-            }
-            _localAircraftInstance->updateAttributeValues(sg::RTIData("tag"));
-        }
-    }
+    if (get_direction() & SG_IO_OUT)
+        _hlaFederate->updateLocalAircraftInstance();
 
     // Then get news from others and process possible update requests
-    if (get_direction() & (SG_IO_IN|SG_IO_OUT)) {
-        _hlaFederate->processMessages();
-    }
+    _hlaFederate->update();
 
     return true;
 }
@@ -1295,14 +1363,12 @@ FGHLA::close()
     if (!is_enabled())
         return false;
 
-    if (get_direction() & SG_IO_OUT) {
-        // Remove the local object from the rti
-        _localAircraftInstance->deleteInstance(simgear::RTIData("gone"));
-        _localAircraftInstance = 0;
-    }
+    if (!_hlaFederate.valid())
+        return false;
 
     // Leave the federation and try to destroy the federation execution.
     _hlaFederate->shutdown();
+    _hlaFederate = 0;
 
     set_enabled(false);
 
index d843160c28b63648b2c1f1534924048e936243b9..bf3212f01621ec4254378ea1946d5f8f548094e6 100644 (file)
 
 #include <simgear/compiler.h>
 #include <simgear/structure/SGSharedPtr.hxx>
-#include <simgear/props/props.hxx>
 
 #include <string>
 #include <vector>
 #include <Network/protocol.hxx>
 
-namespace simgear {
-class HLAFederate;
-class HLAObjectClass;
-class HLAObjectInstance;
-}
-
 class FGHLA : public FGProtocol {
 public:
     FGHLA(const std::vector<std::string>& tokens);
@@ -45,6 +38,8 @@ public:
 private:
     /// All the utility classes we need currently
     class XMLConfigReader;
+    class MultiplayerObjectInstance;
+    class MultiplayerObjectClass;
     class Federate;
 
     /// The configuration parameters extracted from the tokens in the constructor
@@ -54,10 +49,6 @@ private:
 
     /// The toplevel rti class
     SGSharedPtr<Federate> _hlaFederate;
-    /// This class that is used to send register the local instance
-    SGSharedPtr<simgear::HLAObjectClass> _localAircraftClass;
-    /// The local aircraft instance
-    SGSharedPtr<simgear::HLAObjectInstance> _localAircraftInstance;
 };
 
 #endif // _FG_HLA_HXX