From bfb0619f76e68880a167c986d993db182368e45b Mon Sep 17 00:00:00 2001 From: ThorstenB Date: Fri, 9 Dec 2011 17:03:14 +0100 Subject: [PATCH 1/4] Fix memory leak with FGAIModelData. Be lazy and use ref pointers - to remove memory automatically. --- src/AIModel/AIBase.cxx | 5 +++-- src/AIModel/AIBase.hxx | 2 +- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/src/AIModel/AIBase.cxx b/src/AIModel/AIBase.cxx index 230837621..e307a1d83 100644 --- a/src/AIModel/AIBase.cxx +++ b/src/AIModel/AIBase.cxx @@ -145,7 +145,7 @@ FGAIBase::~FGAIBase() { model_removed->setStringValue(props->getPath()); } - if (_refID != 0 && _refID != 1) { + if (_fx && _refID != 0 && _refID != 1) { SGSoundMgr *smgr = globals->get_soundmgr(); stringstream name; name << "aifx:"; @@ -153,7 +153,8 @@ FGAIBase::~FGAIBase() { smgr->remove(name.str()); } - delete fp; + if (fp) + delete fp; fp = 0; } diff --git a/src/AIModel/AIBase.hxx b/src/AIModel/AIBase.hxx index f09a96e00..b4815c41a 100644 --- a/src/AIModel/AIBase.hxx +++ b/src/AIModel/AIBase.hxx @@ -230,7 +230,7 @@ private: bool _initialized; osg::ref_ptr _model; //The 3D model LOD object - FGAIModelData* _aimodel; + osg::ref_ptr _aimodel; string _fxpath; SGSharedPtr _fx; From 826107f132da375d18f13bc11e69233ad633ae20 Mon Sep 17 00:00:00 2001 From: ThorstenB Date: Fri, 9 Dec 2011 17:06:19 +0100 Subject: [PATCH 2/4] #510: Fix disappearing AIShips. Untangle AI reinit and init methods. Some code in init hooks expects to be called once only. Derived classes should not redirect their reinit to init, even if this seems fine for the methods of the derived class itself. This also triggers the init methods of all base classes, which may not expect multiple calls to their init methods (or to "init" on "reinit"). --- src/AIModel/AIBallistic.cxx | 6 +++++- src/AIModel/AIBallistic.hxx | 11 +++++------ src/AIModel/AIBase.cxx | 16 ++++++++-------- src/AIModel/AIEscort.cxx | 6 +++++- src/AIModel/AIEscort.hxx | 13 ++++++------- src/AIModel/AIGroundVehicle.cxx | 6 +++++- src/AIModel/AIGroundVehicle.hxx | 12 ++++++------ src/AIModel/AIShip.cxx | 8 +++++++- src/AIModel/AIShip.hxx | 8 ++------ src/AIModel/AIWingman.cxx | 7 ++++++- src/AIModel/AIWingman.hxx | 13 ++++++------- 11 files changed, 61 insertions(+), 45 deletions(-) diff --git a/src/AIModel/AIBallistic.cxx b/src/AIModel/AIBallistic.cxx index 3fc3e8022..1df938c0b 100644 --- a/src/AIModel/AIBallistic.cxx +++ b/src/AIModel/AIBallistic.cxx @@ -126,7 +126,11 @@ void FGAIBallistic::readFromScenario(SGPropertyNode* scFileNode) { bool FGAIBallistic::init(bool search_in_AI_path) { FGAIBase::init(search_in_AI_path); + reinit(); + return true; +} +void FGAIBallistic::reinit() { _impact_reported = false; _collision_reported = false; _expiry_reported = false; @@ -179,7 +183,7 @@ bool FGAIBallistic::init(bool search_in_AI_path) { setParentNodes(_selected_ac); - return true; + FGAIBase::reinit(); } void FGAIBallistic::bind() { diff --git a/src/AIModel/AIBallistic.hxx b/src/AIModel/AIBallistic.hxx index f798347c9..70ea502cf 100644 --- a/src/AIModel/AIBallistic.hxx +++ b/src/AIModel/AIBallistic.hxx @@ -46,10 +46,10 @@ public: bool init(bool search_in_AI_path=false); virtual void bind(); virtual void unbind(); + virtual void reinit(); + virtual void update(double dt); - void update(double dt); - - FGAIBallistic *ballistic; + virtual const char* getTypeString(void) const { return "ballistic"; } void Run(double dt); @@ -114,7 +114,8 @@ public: // bool getFormate() const; bool getSlavedLoad() const; - virtual const char* getTypeString(void) const { return "ballistic"; } + FGAIBallistic *ballistic; + static const double slugs_to_kgs; //conversion factor static const double slugs_to_lbs; //conversion factor @@ -170,8 +171,6 @@ public: private: - virtual void reinit() { init(); } - bool _aero_stabilised; // if true, object will align with trajectory double _drag_area; // equivalent drag area in ft2 double _life_timer; // seconds diff --git a/src/AIModel/AIBase.cxx b/src/AIModel/AIBase.cxx index e307a1d83..c6a967f8d 100644 --- a/src/AIModel/AIBase.cxx +++ b/src/AIModel/AIBase.cxx @@ -288,8 +288,14 @@ void FGAIBase::Transform() { } -bool FGAIBase::init(bool search_in_AI_path) { - +bool FGAIBase::init(bool search_in_AI_path) +{ + if (_model.valid()) + { + SG_LOG(SG_AI, SG_WARN, "AIBase: Cannot initialize a model multiple times! " << model_path); + return false; + } + string f; if(search_in_AI_path) { @@ -318,12 +324,6 @@ bool FGAIBase::init(bool search_in_AI_path) { _aimodel = new FGAIModelData(props); osg::Node * mdl = SGModelLib::loadDeferredModel(f, props, _aimodel); - if (_model.valid()) - { - // reinit, dump the old model - removeModel(); - } - _model = new osg::LOD; _model->setName("AI-model range animation node"); diff --git a/src/AIModel/AIEscort.cxx b/src/AIModel/AIEscort.cxx index 680b5113f..c88e9af33 100644 --- a/src/AIModel/AIEscort.cxx +++ b/src/AIModel/AIEscort.cxx @@ -134,7 +134,11 @@ void FGAIEscort::unbind() { bool FGAIEscort::init(bool search_in_AI_path) { if (!FGAIShip::init(search_in_AI_path)) return false; + reinit(); + return true; +} +void FGAIEscort::reinit() { invisible = false; no_roll = false; @@ -147,7 +151,7 @@ bool FGAIEscort::init(bool search_in_AI_path) { hdg = _parent_hdg; } - return true; + FGAIShip::reinit(); } void FGAIEscort::update(double dt) { diff --git a/src/AIModel/AIEscort.hxx b/src/AIModel/AIEscort.hxx index 96e997962..a300f645e 100644 --- a/src/AIModel/AIEscort.hxx +++ b/src/AIModel/AIEscort.hxx @@ -39,17 +39,16 @@ public: virtual ~FGAIEscort(); virtual void readFromScenario(SGPropertyNode* scFileNode); - virtual void bind(); - virtual void unbind(); - virtual const char* getTypeString(void) const { return "escort"; } bool init(bool search_in_AI_path=false); - -private: - - virtual void reinit() { init(); } + virtual void bind(); + virtual void unbind(); + virtual void reinit(); virtual void update (double dt); + virtual const char* getTypeString(void) const { return "escort"; } + +private: void setStnRange(double r); void setStnBrg(double y); void setStationSpeed(); diff --git a/src/AIModel/AIGroundVehicle.cxx b/src/AIModel/AIGroundVehicle.cxx index 4708bd30f..b39a1e19b 100644 --- a/src/AIModel/AIGroundVehicle.cxx +++ b/src/AIModel/AIGroundVehicle.cxx @@ -142,7 +142,11 @@ void FGAIGroundVehicle::unbind() { bool FGAIGroundVehicle::init(bool search_in_AI_path) { if (!FGAIShip::init(search_in_AI_path)) return false; + reinit(); + return true; +} +void FGAIGroundVehicle::reinit() { invisible = false; _limit = 200; no_roll = true; @@ -162,7 +166,7 @@ bool FGAIGroundVehicle::init(bool search_in_AI_path) { setParent(); } - return true; + FGAIShip::reinit(); } void FGAIGroundVehicle::update(double dt) { diff --git a/src/AIModel/AIGroundVehicle.hxx b/src/AIModel/AIGroundVehicle.hxx index 70c06f290..08491bad6 100644 --- a/src/AIModel/AIGroundVehicle.hxx +++ b/src/AIModel/AIGroundVehicle.hxx @@ -37,17 +37,17 @@ public: virtual ~FGAIGroundVehicle(); virtual void readFromScenario(SGPropertyNode* scFileNode); - virtual void bind(); - virtual void unbind(); - virtual const char* getTypeString(void) const { return "groundvehicle"; } bool init(bool search_in_AI_path=false); + virtual void bind(); + virtual void unbind(); + virtual void reinit(); + virtual void update (double dt); + + virtual const char* getTypeString(void) const { return "groundvehicle"; } private: - virtual void reinit() { init(); } - virtual void update (double dt); - void setNoRoll(bool nr); void setContactX1offset(double x1); void setContactX2offset(double x2); diff --git a/src/AIModel/AIShip.cxx b/src/AIModel/AIShip.cxx index c6cfa7a05..df0ce649b 100644 --- a/src/AIModel/AIShip.cxx +++ b/src/AIModel/AIShip.cxx @@ -113,6 +113,12 @@ void FGAIShip::readFromScenario(SGPropertyNode* scFileNode) { } bool FGAIShip::init(bool search_in_AI_path) { + reinit(); + return FGAIBase::init(search_in_AI_path); +} + +void FGAIShip::reinit() +{ prev = 0; // the one behind you curr = 0; // the one ahead next = 0; // the next plus 1 @@ -134,7 +140,7 @@ bool FGAIShip::init(bool search_in_AI_path) { if (fp) _fp_init = initFlightPlan(); - return FGAIBase::init(search_in_AI_path); + FGAIBase::reinit(); } void FGAIShip::bind() { diff --git a/src/AIModel/AIShip.hxx b/src/AIModel/AIShip.hxx index f82a14f8d..5c3c3b7f2 100644 --- a/src/AIModel/AIShip.hxx +++ b/src/AIModel/AIShip.hxx @@ -41,8 +41,9 @@ public: virtual void bind(); virtual void unbind(); virtual void update(double dt); + virtual void reinit(); + void setFlightPlan(FGAIFlightPlan* f); -// void setName(const string&); void setRudder(float r); void setRoll(double rl); void ProcessFlightPlan( double dt); @@ -90,14 +91,9 @@ public: protected: -// string _name; // The name of this ship. - private: - - virtual void reinit() { init(); } - void setRepeat(bool r); void setRestart(bool r); void setMissed(bool m); diff --git a/src/AIModel/AIWingman.cxx b/src/AIModel/AIWingman.cxx index 370776e2c..9ba01042a 100644 --- a/src/AIModel/AIWingman.cxx +++ b/src/AIModel/AIWingman.cxx @@ -203,7 +203,11 @@ void FGAIWingman::unbind() { bool FGAIWingman::init(bool search_in_AI_path) { if (!FGAIBallistic::init(search_in_AI_path)) return false; + reinit(); + return true; +} +void FGAIWingman::reinit() { invisible = false; _tgt_x_offset = _x_offset; @@ -223,7 +227,8 @@ bool FGAIWingman::init(bool search_in_AI_path) { props->setStringValue("submodels/path", _path.c_str()); user_WoW_node = fgGetNode("gear/gear[1]/wow", true); - return true; + + FGAIBallistic::reinit(); } void FGAIWingman::update(double dt) { diff --git a/src/AIModel/AIWingman.hxx b/src/AIModel/AIWingman.hxx index 42c51094c..c291069ba 100644 --- a/src/AIModel/AIWingman.hxx +++ b/src/AIModel/AIWingman.hxx @@ -35,17 +35,16 @@ public: virtual ~FGAIWingman(); virtual void readFromScenario(SGPropertyNode* scFileNode); - virtual void bind(); - virtual void unbind(); - virtual const char* getTypeString(void) const { return "wingman"; } bool init(bool search_in_AI_path=false); - -private: - - virtual void reinit() { init(); } + virtual void bind(); + virtual void unbind(); + virtual void reinit(); virtual void update (double dt); + virtual const char* getTypeString(void) const { return "wingman"; } + +private: void formateToAC(double dt); void Break(double dt); void Join(double dt); From 444720f62d484cf9886cdbdf5735b5b1ee1d9137 Mon Sep 17 00:00:00 2001 From: ThorstenB Date: Fri, 9 Dec 2011 17:19:45 +0100 Subject: [PATCH 3/4] Avoid useless warnings during FG startup. Do not warn about missing scenery manager, unless it is really needed. Also raise warn level for multiple init calls. --- src/AIModel/AIBase.cxx | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/AIModel/AIBase.cxx b/src/AIModel/AIBase.cxx index c6a967f8d..7871f7e8e 100644 --- a/src/AIModel/AIBase.cxx +++ b/src/AIModel/AIBase.cxx @@ -164,6 +164,9 @@ FGAIBase::~FGAIBase() { void FGAIBase::removeModel() { + if (!_model.valid()) + return; + FGScenery* pSceneryManager = globals->get_scenery(); if (pSceneryManager) { @@ -292,7 +295,7 @@ bool FGAIBase::init(bool search_in_AI_path) { if (_model.valid()) { - SG_LOG(SG_AI, SG_WARN, "AIBase: Cannot initialize a model multiple times! " << model_path); + SG_LOG(SG_AI, SG_ALERT, "AIBase: Cannot initialize a model multiple times! " << model_path); return false; } From 4c17cee5fb124b1006be6f6ac03b877c0f683521 Mon Sep 17 00:00:00 2001 From: ThorstenB Date: Fri, 9 Dec 2011 17:20:28 +0100 Subject: [PATCH 4/4] Lower log level for event input/udev messages. --- src/Input/FGLinuxEventInput.cxx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Input/FGLinuxEventInput.cxx b/src/Input/FGLinuxEventInput.cxx index a5e825b10..deff1b88f 100644 --- a/src/Input/FGLinuxEventInput.cxx +++ b/src/Input/FGLinuxEventInput.cxx @@ -469,7 +469,7 @@ void FGLinuxEventInput::postinit() dev = udev_device_get_parent( dev ); const char * name = udev_device_get_sysattr_value(dev,"name"); - SG_LOG(SG_INPUT,SG_ALERT, "name=" << (name?name:"") << ", node=" << (node?node:"")); + SG_LOG(SG_INPUT,SG_DEBUG, "name=" << (name?name:"") << ", node=" << (node?node:"")); if( name && node ) AddDevice( new FGLinuxInputDevice(name, node) );