]> git.mxchange.org Git - flightgear.git/blobdiff - src/Autopilot/autopilotgroup.cxx
Interim windows build fix
[flightgear.git] / src / Autopilot / autopilotgroup.cxx
index 347a39e0e7c567134f6545057954b5e3b09eb249..199a14b946fb7d8a8615cf5d81cb4d53d0bcefba 100644 (file)
 #include <string>
 #include <vector>
 
+#include <simgear/props/props_io.hxx>
 #include <simgear/structure/subsystem_mgr.hxx>
 #include <simgear/structure/exception.hxx>
 #include <Main/fg_props.hxx>
+#include <boost/foreach.hpp>
 
-
+using std::vector;
 using simgear::PropertyList;
+using FGXMLAutopilot::Autopilot;
 
-class FGXMLAutopilotGroupImplementation : public FGXMLAutopilotGroup
+class FGXMLAutopilotGroupImplementation:
+  public FGXMLAutopilotGroup
 {
-public:
+  public:
+    FGXMLAutopilotGroupImplementation(const std::string& nodeName):
+      FGXMLAutopilotGroup(),
+      _nodeName(nodeName)
+    {}
+
+    virtual void addAutopilot( const std::string& name,
+                               SGPropertyNode_ptr apNode,
+                               SGPropertyNode_ptr config );
+    virtual void removeAutopilot( const std::string & name );
     void init();
+    InitStatus incrementalInit();
     void reinit();
-    void update( double dt );
-private:
+
+  private:
     void initFrom( SGPropertyNode_ptr rootNode, const char * childName );
-    vector<string> _autopilotNames;
+    std::string _nodeName;
 
 };
 
-void FGXMLAutopilotGroupImplementation::update( double dt )
+//------------------------------------------------------------------------------
+void FGXMLAutopilotGroupImplementation::addAutopilot( const std::string& name,
+                                                      SGPropertyNode_ptr apNode,
+                                                      SGPropertyNode_ptr config )
+{
+  if( has_subsystem(name) )
+  {
+    SG_LOG( SG_AUTOPILOT,
+            SG_ALERT,
+            "NOT adding duplicate " << _nodeName << " name '" << name << "'");
+    return;
+  }
+
+  Autopilot* ap = new Autopilot(apNode, config);
+  ap->set_name( name );
+
+  double updateInterval = config->getDoubleValue("update-interval-secs", 0.0);
+  set_subsystem( name, ap, updateInterval );
+}
+
+//------------------------------------------------------------------------------
+void FGXMLAutopilotGroupImplementation::removeAutopilot(const std::string& name)
 {
-    // update all configured autopilots
-    SGSubsystemGroup::update( dt );
+  Autopilot* ap = static_cast<Autopilot*>(get_subsystem(name));
+  if( !ap )
+  {
+    SG_LOG( SG_AUTOPILOT,
+            SG_ALERT,
+            "CAN NOT remove unknown " << _nodeName << " '" << name << "'");
+    return;
+  }
+
+  remove_subsystem(name);
 }
 
+//------------------------------------------------------------------------------
 void FGXMLAutopilotGroupImplementation::reinit()
 {
-    SGSubsystemGroup::unbind();
+  SGSubsystemGroup::unbind();
+  clearSubsystems();
 
-    for( vector<string>::size_type i = 0; i < _autopilotNames.size(); i++ ) {
-      FGXMLAutopilot::Autopilot * ap = (FGXMLAutopilot::Autopilot*)get_subsystem( _autopilotNames[i] );
-      if( ap == NULL ) continue; // ?
-      remove_subsystem( _autopilotNames[i] );
-      delete ap;
-    }
-    _autopilotNames.clear();
-    init();
+  init();
+}
+
+//------------------------------------------------------------------------------
+SGSubsystem::InitStatus FGXMLAutopilotGroupImplementation::incrementalInit()
+{
+  init();
+  return INIT_DONE;
 }
 
+//------------------------------------------------------------------------------
 void FGXMLAutopilotGroupImplementation::init()
 {
-    static const char * nodeNames[] = {
-        "autopilot",
-        "property-rule"
-    };
-    for( unsigned i = 0; i < sizeof(nodeNames)/sizeof(nodeNames[0]); i++ )
-        initFrom( fgGetNode( "/sim/systems" ), nodeNames[i] );
-
-    SGSubsystemGroup::bind();
-    SGSubsystemGroup::init();
+  initFrom(fgGetNode("/sim/systems"), _nodeName.c_str());
+
+  SGSubsystemGroup::bind();
+  SGSubsystemGroup::init();
 }
 
-void FGXMLAutopilotGroupImplementation::initFrom( SGPropertyNode_ptr rootNode, const char * childName )
+//------------------------------------------------------------------------------
+void FGXMLAutopilotGroupImplementation::initFrom( SGPropertyNode_ptr rootNode,
+                                                  const char* childName )
 {
-    if( rootNode == NULL )
-        return;
-
-    PropertyList autopilotNodes = rootNode->getChildren(childName);
-    for( PropertyList::size_type i = 0; i < autopilotNodes.size(); i++ ) {
-        SGPropertyNode_ptr pathNode = autopilotNodes[i]->getNode( "path" );
-        if( pathNode == NULL ) {
-            SG_LOG( SG_ALL, SG_WARN, "No configuration file specified for this property-rule!");
-            continue;
-        }
-
-        string apName;
-        SGPropertyNode_ptr nameNode = autopilotNodes[i]->getNode( "name" );
-        if( nameNode != NULL ) {
-            apName = nameNode->getStringValue();
-        } else {
+  if( !rootNode )
+    return;
+
+  BOOST_FOREACH( SGPropertyNode_ptr autopilotNode,
+                 rootNode->getChildren(childName) )
+  {
+    SGPropertyNode_ptr pathNode = autopilotNode->getNode("path");
+    if( !pathNode )
+    {
+      SG_LOG
+      (
+        SG_AUTOPILOT,
+        SG_WARN,
+        "No configuration file specified for this " << childName << "!"
+      );
+      continue;
+    }
+
+    std::string apName;
+    SGPropertyNode_ptr nameNode = autopilotNode->getNode( "name" );
+    if( nameNode != NULL ) {
+        apName = nameNode->getStringValue();
+    } else {
+      std::ostringstream buf;
+      buf <<  "unnamed_autopilot_" << autopilotNode->getIndex();
+      apName = buf.str();
+    }
+
+    {
+      // check for duplicate names
+      std::string name = apName;
+      for( unsigned i = 0; get_subsystem( apName.c_str() ) != NULL; i++ ) {
           std::ostringstream buf;
-          buf <<  "unnamed_autopilot_" << i;
+          buf <<  name << "_" << i;
           apName = buf.str();
-        }
-
-        {
-          // check for duplicate names
-          string name = apName;
-          for( unsigned i = 0; get_subsystem( apName.c_str() ) != NULL; i++ ) {
-              ostringstream buf;
-              buf <<  name << "_" << i;
-              apName = buf.str();
-          }
-          if( apName != name )
-            SG_LOG( SG_ALL, SG_WARN, "Duplicate property-rule configuration name " << name << ", renamed to " << apName );
-        }
-
-        SGPath config = globals->resolve_maybe_aircraft_path(pathNode->getStringValue());
-
-        SG_LOG( SG_ALL, SG_INFO, "Reading property-rule configuration from " << config.str() );
-
-        try {
-            SGPropertyNode_ptr root = new SGPropertyNode();
-            readProperties( config.str(), root );
-
-            SG_LOG( SG_AUTOPILOT, SG_INFO, "adding  property-rule subsystem " << apName );
-            FGXMLAutopilot::Autopilot * ap = new FGXMLAutopilot::Autopilot( autopilotNodes[i], root );
-            ap->set_name( apName );
-            set_subsystem( apName, ap );
-            _autopilotNames.push_back( apName );
-
-        } catch (const sg_exception& e) {
-            SG_LOG( SG_AUTOPILOT, SG_ALERT, "Failed to load property-rule configuration: "
-                    << config.str() << ":" << e.getMessage() );
-            continue;
-        }
+      }
+      if( apName != name )
+        SG_LOG
+        (
+          SG_AUTOPILOT,
+          SG_WARN,
+          "Duplicate " << childName << " configuration name " << name
+                                    << ", renamed to " << apName
+        );
     }
+
+    addAutopilotFromFile(apName, autopilotNode, pathNode->getStringValue());
+  }
+}
+
+void FGXMLAutopilotGroup::addAutopilotFromFile( const std::string& name,
+                                                SGPropertyNode_ptr apNode,
+                                                const char* path )
+{
+  SGPath config = globals->resolve_maybe_aircraft_path(path);
+  if( config.isNull() )
+  {
+    SG_LOG
+    (
+      SG_AUTOPILOT,
+      SG_ALERT,
+      "Cannot find property-rule configuration file '" << path << "'."
+    );
+    return;
+  }
+  SG_LOG
+  (
+    SG_AUTOPILOT,
+    SG_INFO,
+    "Reading property-rule configuration from " << config.str()
+  );
+
+  try
+  {
+    SGPropertyNode_ptr configNode = new SGPropertyNode();
+    readProperties( config.str(), configNode );
+
+    SG_LOG(SG_AUTOPILOT, SG_INFO, "adding  property-rule subsystem " << name);
+    addAutopilot(name, apNode, configNode);
+  }
+  catch (const sg_exception& e)
+  {
+    SG_LOG
+    (
+      SG_AUTOPILOT,
+      SG_ALERT,
+      "Failed to load property-rule configuration: " << config.str()
+                                             << ": " << e.getMessage()
+    );
+    return;
+  }
 }
 
-FGXMLAutopilotGroup * FGXMLAutopilotGroup::createInstance()
+//------------------------------------------------------------------------------
+FGXMLAutopilotGroup*
+FGXMLAutopilotGroup::createInstance(const std::string& nodeName)
 {
-    return new FGXMLAutopilotGroupImplementation();
+  return new FGXMLAutopilotGroupImplementation(nodeName);
 }