From: Torsten Dreyer Date: Thu, 27 Oct 2011 06:27:52 +0000 (+0200) Subject: Some autopilot fixes X-Git-Url: https://git.mxchange.org/?a=commitdiff_plain;h=1a80d70e00c074ff65fd0f7e597348b1c07326f8;p=flightgear.git Some autopilot fixes - fix minor memory leak - make autopilots addable and removeable at runtime --- diff --git a/src/Autopilot/autopilot.cxx b/src/Autopilot/autopilot.cxx index b68ea958e..be3a4f0d9 100644 --- a/src/Autopilot/autopilot.cxx +++ b/src/Autopilot/autopilot.cxx @@ -41,12 +41,25 @@ using std::string; using namespace FGXMLAutopilot; +class ComponentForge : public map *> { +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 *> componentForge; + componentForge["pid-controller"] = new CreateAndConfigureFunctor(); componentForge["pi-simple-controller"] = new CreateAndConfigureFunctor(); componentForge["predict-simple"] = new CreateAndConfigureFunctor(); diff --git a/src/Autopilot/autopilot.hxx b/src/Autopilot/autopilot.hxx index 56bb6c32e..ccda272e0 100644 --- a/src/Autopilot/autopilot.hxx +++ b/src/Autopilot/autopilot.hxx @@ -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 ); diff --git a/src/Autopilot/autopilotgroup.cxx b/src/Autopilot/autopilotgroup.cxx index 10c55514f..a856c342f 100644 --- a/src/Autopilot/autopilotgroup.cxx +++ b/src/Autopilot/autopilotgroup.cxx @@ -35,6 +35,7 @@ #include #include #include
+#include 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::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; } } diff --git a/src/Autopilot/autopilotgroup.hxx b/src/Autopilot/autopilotgroup.hxx index 1ccb0be76..6e6c1f196 100644 --- a/src/Autopilot/autopilotgroup.hxx +++ b/src/Autopilot/autopilotgroup.hxx @@ -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() {} diff --git a/src/Autopilot/functor.hxx b/src/Autopilot/functor.hxx index b68b683c3..2f1ac36df 100644 --- a/src/Autopilot/functor.hxx +++ b/src/Autopilot/functor.hxx @@ -35,8 +35,7 @@ public: }; template class CreateAndConfigureFunctor : - public FunctorBase, - SGReferenced { + public FunctorBase { public: virtual TBase * operator()( SGPropertyNode_ptr configNode ) { TBase * base = new TClass();