]> git.mxchange.org Git - flightgear.git/commitdiff
Some autopilot fixes
authorTorsten Dreyer <Torsten@t3r.de>
Thu, 27 Oct 2011 06:27:52 +0000 (08:27 +0200)
committerTorsten Dreyer <Torsten@t3r.de>
Thu, 27 Oct 2011 06:27:52 +0000 (08:27 +0200)
- fix minor memory leak
- make autopilots addable and removeable at runtime

src/Autopilot/autopilot.cxx
src/Autopilot/autopilot.hxx
src/Autopilot/autopilotgroup.cxx
src/Autopilot/autopilotgroup.hxx
src/Autopilot/functor.hxx

index b68ea958ee2f601585b85144bd47ca9bece9b89f..be3a4f0d90d02704422a990727591a34e7442383 100644 (file)
@@ -41,12 +41,25 @@ using std::string;
 
 using namespace FGXMLAutopilot;
 
+class ComponentForge : public map<string,FunctorBase<Component> *> {
+public:
+    virtual ~ ComponentForge();
+};
+
+ComponentForge::~ComponentForge()
+{
+    for( iterator it = begin(); it != end(); ++it )
+        delete it->second;
+}
+
+static ComponentForge componentForge;
+
 Autopilot::Autopilot( SGPropertyNode_ptr rootNode, SGPropertyNode_ptr configNode ) :
   _name("unnamed autopilot"),
   _serviceable(true),
   _rootNode(rootNode)
 {
-  map<string,FunctorBase<Component> *> componentForge;
+
   componentForge["pid-controller"]       = new CreateAndConfigureFunctor<PIDController,Component>();
   componentForge["pi-simple-controller"] = new CreateAndConfigureFunctor<PISimpleController,Component>();
   componentForge["predict-simple"]       = new CreateAndConfigureFunctor<Predictor,Component>();
index 56bb6c32e5535bb76ce24e3fcfe423a301ea151c..ccda272e0550059fd64839160c87ac6ccf30ba0f 100644 (file)
@@ -52,7 +52,7 @@ public:
     bool is_serviceable() const { return _serviceable; }
 
     std::string get_name() const { return _name; }
-    void set_name( std::string & name ) { _name = name; }
+    void set_name( const std::string & name ) { _name = name; }
 
     void add_component( Component * component );
 
index 10c55514ff4464beb5e8199fbe2d3a0ce85aa77b..a856c342fb8d0d4f2bcbbcb49913074eea97b45e 100644 (file)
@@ -35,6 +35,7 @@
 #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;
@@ -43,6 +44,8 @@ using simgear::PropertyList;
 class FGXMLAutopilotGroupImplementation : public FGXMLAutopilotGroup
 {
 public:
+    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 );
@@ -52,6 +55,30 @@ private:
 
 };
 
+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 );
+    set_subsystem( name, ap );
+    _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
@@ -63,10 +90,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();
@@ -90,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();
         }
 
@@ -120,31 +143,31 @@ 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());
-        if (config.isNull())
-        {
-            SG_LOG( SG_ALL, SG_ALERT, "Cannot find property-rule configuration file '" << pathNode->getStringValue() << "'." );
-        }
-        else
-        {
-            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;
-            }
-        }
+        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_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 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;
     }
 }
 
index 1ccb0be76f696bf47d88bff75425f099547453a6..6e6c1f1968f3a713912be0b08dcb5380c84bad37 100644 (file)
@@ -24,7 +24,6 @@
 #ifndef _XMLAUTO_HXX
 #define _XMLAUTO_HXX 1
 
-
 /**
  * @brief Model an autopilot system by implementing a SGSubsystemGroup
  * 
@@ -33,6 +32,9 @@ class FGXMLAutopilotGroup : public SGSubsystemGroup
 {
 public:
     static FGXMLAutopilotGroup * createInstance();
+    void addAutopilotFromFile( const std::string & name, SGPropertyNode_ptr apNode, const char * path );
+    virtual void addAutopilot( const std::string & name, SGPropertyNode_ptr apNode, SGPropertyNode_ptr config ) = 0;
+    virtual void removeAutopilot( const std::string & name ) = 0;
 protected:
     FGXMLAutopilotGroup() : SGSubsystemGroup() {}
 
index b68b683c31f0ae91c66763e191edc9ab117589e8..2f1ac36dfa2f18d8276248cc8f26fca09a184ba3 100644 (file)
@@ -35,8 +35,7 @@ public:
 };
 
 template <class TClass,class TBase> class CreateAndConfigureFunctor : 
-  public FunctorBase<TBase>,
-  SGReferenced {
+  public FunctorBase<TBase> {
 public:
   virtual TBase * operator()( SGPropertyNode_ptr configNode ) { 
     TBase * base = new TClass();