]> git.mxchange.org Git - flightgear.git/blobdiff - src/Autopilot/autopilotgroup.cxx
Fix various route-manager issues reported by Hyde.
[flightgear.git] / src / Autopilot / autopilotgroup.cxx
index 347a39e0e7c567134f6545057954b5e3b09eb249..c9df860d220a58da2a65b0442eae59204c5e94ad 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 std::string;
 using simgear::PropertyList;
 
 class FGXMLAutopilotGroupImplementation : public FGXMLAutopilotGroup
 {
 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();
     void reinit();
     void update( double dt );
 private:
     void initFrom( SGPropertyNode_ptr rootNode, const char * childName );
     vector<string> _autopilotNames;
+    std::string _nodeName;
 
 };
 
+void FGXMLAutopilotGroupImplementation::addAutopilot( const std::string & name, SGPropertyNode_ptr apNode, SGPropertyNode_ptr config )
+{
+    BOOST_FOREACH( std::string & n, _autopilotNames ) {
+        if( n == name ) {
+            SG_LOG(SG_ALL, SG_ALERT, "NOT adding duplicate property rule name " << name );
+            return;
+        }
+    }
+    FGXMLAutopilot::Autopilot * ap = new FGXMLAutopilot::Autopilot( apNode, config );
+    ap->set_name( name );
+
+    double updateInterval = config->getDoubleValue( "update-interval-secs", 0.0 );
+    set_subsystem( name, ap, updateInterval );
+    _autopilotNames.push_back( name );
+}
+
+void FGXMLAutopilotGroupImplementation::removeAutopilot( const std::string & name )
+{
+    FGXMLAutopilot::Autopilot * ap = (FGXMLAutopilot::Autopilot*)get_subsystem( name );
+    if( ap == NULL ) return; // ?
+    remove_subsystem( name );
+    delete ap;
+}
+
+
+
 void FGXMLAutopilotGroupImplementation::update( double dt )
 {
     // update all configured autopilots
@@ -61,10 +95,7 @@ void FGXMLAutopilotGroupImplementation::reinit()
     SGSubsystemGroup::unbind();
 
     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;
+      removeAutopilot( _autopilotNames[i] );
     }
     _autopilotNames.clear();
     init();
@@ -72,12 +103,7 @@ void FGXMLAutopilotGroupImplementation::reinit()
 
 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] );
+    initFrom( fgGetNode( "/sim/systems" ), _nodeName.c_str() );
 
     SGSubsystemGroup::bind();
     SGSubsystemGroup::init();
@@ -88,21 +114,20 @@ void FGXMLAutopilotGroupImplementation::initFrom( SGPropertyNode_ptr rootNode, c
     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" );
+    BOOST_FOREACH( SGPropertyNode_ptr autopilotNode, rootNode->getChildren(childName) ) {
+        SGPropertyNode_ptr pathNode = autopilotNode->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" );
+        SGPropertyNode_ptr nameNode = autopilotNode->getNode( "name" );
         if( nameNode != NULL ) {
             apName = nameNode->getStringValue();
         } else {
           std::ostringstream buf;
-          buf <<  "unnamed_autopilot_" << i;
+          buf <<  "unnamed_autopilot_" << autopilotNode->getIndex();
           apName = buf.str();
         }
 
@@ -110,7 +135,7 @@ void FGXMLAutopilotGroupImplementation::initFrom( SGPropertyNode_ptr rootNode, c
           // check for duplicate names
           string name = apName;
           for( unsigned i = 0; get_subsystem( apName.c_str() ) != NULL; i++ ) {
-              ostringstream buf;
+              std::ostringstream buf;
               buf <<  name << "_" << i;
               apName = buf.str();
           }
@@ -118,29 +143,35 @@ void FGXMLAutopilotGroupImplementation::initFrom( SGPropertyNode_ptr rootNode, c
             SG_LOG( SG_ALL, SG_WARN, "Duplicate property-rule configuration name " << name << ", renamed to " << apName );
         }
 
-        SGPath config = globals->resolve_maybe_aircraft_path(pathNode->getStringValue());
+        addAutopilotFromFile( apName, autopilotNode, pathNode->getStringValue() );
+    }
+}
 
-        SG_LOG( SG_ALL, SG_INFO, "Reading property-rule configuration from " << config.str() );
+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_ALL, SG_ALERT, "Cannot find property-rule configuration file '" << path << "'." );
+        return;
+    }
+    SG_LOG( SG_ALL, SG_INFO, "Reading property-rule configuration from " << config.str() );
 
-        try {
-            SGPropertyNode_ptr root = new SGPropertyNode();
-            readProperties( config.str(), root );
+    try {
+        SGPropertyNode_ptr configNode = new SGPropertyNode();
+        readProperties( config.str(), configNode );
 
-            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 );
+        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() );
-            continue;
-        }
+    } 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);
 }