diff --git a/modules/gfx/pymod/export_scene.cc b/modules/gfx/pymod/export_scene.cc index 11d0f49d5d3f418c7f4531a3d4bba3b0b36c8192..b810b91225474ce769daf530ccb4e6af4e71f8a6 100644 --- a/modules/gfx/pymod/export_scene.cc +++ b/modules/gfx/pymod/export_scene.cc @@ -87,6 +87,10 @@ void scene_set_hemi_p(Scene* s, tuple p) } // anon ns +void clear_scene() { + Scene::Instance().RemoveAll(); +} + void export_Scene() { def("Scene",get_scene,return_value_policy<reference_existing_object>()); @@ -264,5 +268,15 @@ void export_Scene() .add_property("hemi_params",scene_get_hemi_p,scene_set_hemi_p) ; -} +// we need to make sure there are no pending references to Python objects +// tied to the scene singleton. The destructor of +// scene may be called after Python is shutdown which results +// in a segfault. +scope().attr("__dict__")["atexit"]=handle<>(PyImport_ImportModule("atexit")); + +def("_clear_scene", &clear_scene); +object r=scope().attr("_clear_scene"); +scope().attr("atexit").attr("register")(r); + +} diff --git a/modules/gfx/src/scene.cc b/modules/gfx/src/scene.cc index 7631d2123a74ecebd31d9a2c03b475d8adcfca21..9aeb22a01ef170a2bb0937034e1b26a4f0b999e2 100644 --- a/modules/gfx/src/scene.cc +++ b/modules/gfx/src/scene.cc @@ -151,6 +151,13 @@ Scene::Scene(): transform_.SetTrans(Vec3(0,0,-100)); } +Scene::~Scene() +{ + // cleanup all observers / gfx_nodes when scene is destructed + observers_.clear(); + this->RemoveAll(); +} + void Scene::SetFog(bool f) { fog_flag_=f; diff --git a/modules/gfx/src/scene.hh b/modules/gfx/src/scene.hh index 4205263fc2f5a054dc5c0baae3e98bb18231d21e..adacb4ca9e307ca1c96ee664d91da85f5b7e3b1f 100644 --- a/modules/gfx/src/scene.hh +++ b/modules/gfx/src/scene.hh @@ -548,6 +548,7 @@ private: Scene(); Scene(const Scene&) {} Scene& operator=(const Scene&) {return *this;} + ~Scene(); // The GL Context gets typically handled externally, e.g. using QT when // calling InitGL(), RenderGL() etc. However, there is no guarantee that the