From 89065ea5c2b54c3ded7b6dedeaac38e6f0518e52 Mon Sep 17 00:00:00 2001 From: James Turner Date: Fri, 18 Dec 2015 19:56:56 -0800 Subject: [PATCH] Proper shutdown() for the model manager - also move property setup to bind/unbind --- src/Main/fg_init.cxx | 2 +- src/Main/globals.cxx | 1 - src/Model/modelmgr.cxx | 55 ++++++++++++++++++++++++------------------ src/Model/modelmgr.hxx | 15 +++++------- 4 files changed, 39 insertions(+), 34 deletions(-) diff --git a/src/Main/fg_init.cxx b/src/Main/fg_init.cxx index 572ca446a..012f14371 100644 --- a/src/Main/fg_init.cxx +++ b/src/Main/fg_init.cxx @@ -895,7 +895,7 @@ void fgCreateSubsystems(bool duringReset) { } globals->add_subsystem("aircraft-model", new FGAircraftModel, SGSubsystemMgr::DISPLAY); - globals->add_subsystem("model-manager", new FGModelMgr, SGSubsystemMgr::DISPLAY); + globals->add_new_subsystem(SGSubsystemMgr::DISPLAY); globals->add_new_subsystem(SGSubsystemMgr::DISPLAY); } diff --git a/src/Main/globals.cxx b/src/Main/globals.cxx index f2c57e15d..7e22bcfd3 100644 --- a/src/Main/globals.cxx +++ b/src/Main/globals.cxx @@ -216,7 +216,6 @@ FGGlobals::~FGGlobals() subsystem_mgr->unbind(); subsystem_mgr->remove("aircraft-model"); - subsystem_mgr->remove("model-manager"); subsystem_mgr->remove(FGTileMgr::subsystemName()); diff --git a/src/Model/modelmgr.cxx b/src/Model/modelmgr.cxx index a92a5d5ee..dee9fbb5d 100644 --- a/src/Model/modelmgr.cxx +++ b/src/Model/modelmgr.cxx @@ -28,46 +28,45 @@ #include "modelmgr.hxx" -using std::vector; - using namespace simgear; // OSGFIXME // extern SGShadowVolume *shadows; FGModelMgr::FGModelMgr () - : _models(fgGetNode("/models", true)), - _listener(new Listener(this)) { - _models->addChangeListener(_listener); } -#include FGModelMgr::~FGModelMgr () { - _models->removeChangeListener(_listener); - delete _listener; - - osg::Group *scene_graph = globals->get_scenery()->get_scene_graph(); - if (!scene_graph) - SG_LOG(SG_AIRCRAFT, SG_ALERT, "Warning: The scenegraph wass deleted before the models could be removed"); - - for (unsigned int i = 0; i < _instances.size(); i++) { - if (scene_graph) - scene_graph->removeChild(_instances[i]->model->getSceneGraph()); - delete _instances[i]; - } } void FGModelMgr::init () { - vector model_nodes = _models->getChildren("model"); + std::vector model_nodes = _models->getChildren("model"); for (unsigned int i = 0; i < model_nodes.size(); i++) add_model(model_nodes[i]); } +void FGModelMgr::shutdown() +{ + osg::Group *scene_graph = NULL; + if (globals->get_scenery()) { + scene_graph = globals->get_scenery()->get_scene_graph(); + } + + // always delete instances, even if the scene-graph is gone + for (unsigned int i = 0; i < _instances.size(); i++) { + if (scene_graph) { + scene_graph->removeChild(_instances[i]->model->getSceneGraph()); + } + + delete _instances[i]; + } +} + void FGModelMgr::add_model (SGPropertyNode * node) { @@ -141,11 +140,18 @@ FGModelMgr::add_model (SGPropertyNode * node) void FGModelMgr::bind () { + _models = fgGetNode("/models", true); + + _listener.reset(new Listener(this)); + _models->addChangeListener(_listener.get()); } void FGModelMgr::unbind () { + _models->removeChangeListener(_listener.get()); + _listener.reset(); + _models.clear(); } namespace @@ -219,7 +225,7 @@ FGModelMgr::add_instance (Instance * instance) void FGModelMgr::remove_instance (Instance * instance) { - vector::iterator it; + std::vector::iterator it; for (it = _instances.begin(); it != _instances.end(); it++) { if (*it == instance) { _instances.erase(it); @@ -274,8 +280,8 @@ FGModelMgr::Listener::childRemoved(SGPropertyNode * parent, SGPropertyNode * chi return; // search instance by node and remove it from scenegraph - vector::iterator it = _mgr->_instances.begin(); - vector::iterator end = _mgr->_instances.end(); + std::vector::iterator it = _mgr->_instances.begin(); + std::vector::iterator end = _mgr->_instances.end(); for (; it != end; ++it) { Instance *instance = *it; @@ -287,7 +293,10 @@ FGModelMgr::Listener::childRemoved(SGPropertyNode * parent, SGPropertyNode * chi // OSGFIXME // if (shadows && instance->shadow) // shadows->deleteOccluder(branch); - globals->get_scenery()->get_scene_graph()->removeChild(branch); + + if (globals->get_scenery() && globals->get_scenery()->get_scene_graph()) { + globals->get_scenery()->get_scene_graph()->removeChild(branch); + } delete instance; break; diff --git a/src/Model/modelmgr.hxx b/src/Model/modelmgr.hxx index 0b1cf5343..13a0409a1 100644 --- a/src/Model/modelmgr.hxx +++ b/src/Model/modelmgr.hxx @@ -6,17 +6,12 @@ #ifndef __MODELMGR_HXX #define __MODELMGR_HXX 1 -#ifndef __cplusplus -# error This library requires C++ -#endif - #include +#include #include // for SG_USING_STD #include -using std::vector; - // Don't pull in headers, since we don't need them here. class SGPropertyNode; class SGModelPlacement; @@ -61,6 +56,8 @@ public: virtual ~FGModelMgr (); virtual void init (); + virtual void shutdown (); + virtual void bind (); virtual void unbind (); virtual void update (double dt); @@ -87,7 +84,7 @@ public: */ virtual void remove_instance (Instance * instance); - + static const char* subsystemName() { return "model-manager"; } private: /** * Listener class that adds models at runtime. @@ -104,9 +101,9 @@ private: }; SGPropertyNode_ptr _models; - Listener * _listener; + std::auto_ptr _listener; - vector _instances; + std::vector _instances; };