]> git.mxchange.org Git - flightgear.git/commitdiff
Proper shutdown() for the model manager
authorJames Turner <zakalawe@mac.com>
Sat, 19 Dec 2015 03:56:56 +0000 (19:56 -0800)
committerJames Turner <zakalawe@mac.com>
Sat, 19 Dec 2015 03:56:56 +0000 (19:56 -0800)
- also move property setup to bind/unbind

src/Main/fg_init.cxx
src/Main/globals.cxx
src/Model/modelmgr.cxx
src/Model/modelmgr.hxx

index 572ca446a42382cdfca74ba6b032b3c9d1828979..012f1437123e30eb452ac18220a9ffdf5f44d8cc 100644 (file)
@@ -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<FGModelMgr>(SGSubsystemMgr::DISPLAY);
 
     globals->add_new_subsystem<FGViewMgr>(SGSubsystemMgr::DISPLAY);
 }
index f2c57e15d2ece5345a1b7002f1a80d9a4786bf38..7e22bcfd34bfaaae3440a02ef20a704b3fbab83c 100644 (file)
@@ -216,7 +216,6 @@ FGGlobals::~FGGlobals()
     subsystem_mgr->unbind();
 
     subsystem_mgr->remove("aircraft-model");
-    subsystem_mgr->remove("model-manager");
 
     subsystem_mgr->remove(FGTileMgr::subsystemName());
 
index a92a5d5eee87b8c3284b025543d9fa0443e2e9da..dee9fbb5d25b912b3a29d0d1aab62fc20251b6fb 100644 (file)
 
 #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 <stdio.h>
 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<SGPropertyNode_ptr> model_nodes = _models->getChildren("model");
+    std::vector<SGPropertyNode_ptr> 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<Instance *>::iterator it;
+    std::vector<Instance *>::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<Instance *>::iterator it = _mgr->_instances.begin();
-  vector<Instance *>::iterator end = _mgr->_instances.end();
+    std::vector<Instance *>::iterator it = _mgr->_instances.begin();
+    std::vector<Instance *>::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;
index 0b1cf53435248d91511b2181c75682fd5962b229..13a0409a1409c6b114bbcb36642b23207c5d6872 100644 (file)
@@ -6,17 +6,12 @@
 #ifndef __MODELMGR_HXX
 #define __MODELMGR_HXX 1
 
-#ifndef __cplusplus
-# error This library requires C++
-#endif
-
 #include <vector>
+#include <memory>
 
 #include <simgear/compiler.h>  // for SG_USING_STD
 #include <simgear/structure/subsystem_mgr.hxx>
 
-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> _listener;
 
-  vector<Instance *> _instances;
+    std::vector<Instance *> _instances;
 
 };