From f784884fd190eb95cb19ca539b6baec7821ec5b2 Mon Sep 17 00:00:00 2001 From: Robert Osfield Date: Mon, 25 Jun 2012 16:31:36 +0000 Subject: [PATCH] Refactored the way that the static Scene cache is managed by moving all the functionality into a SceneSingleton --- src/osgViewer/Scene.cpp | 88 ++++++++++++++++++++++++++--------------- 1 file changed, 57 insertions(+), 31 deletions(-) diff --git a/src/osgViewer/Scene.cpp b/src/osgViewer/Scene.cpp index 039180908..2d04f6c6a 100644 --- a/src/osgViewer/Scene.cpp +++ b/src/osgViewer/Scene.cpp @@ -16,18 +16,64 @@ using namespace osgViewer; -typedef std::vector< osg::observer_ptr > SceneCache; +#define OSG_INIT_SINGLETON_PROXY(ProxyName, Func) static struct ProxyName{ ProxyName() { Func; } } s_##ProxyName; -static SceneCache s_sceneCache; -static SceneCache& getSceneCache() +namespace osgViewer { - return s_sceneCache; + + +struct SceneSingleton +{ + SceneSingleton() {} + + inline void add(Scene* scene) + { + OpenThreads::ScopedLock lock(_mutex); + _cache.push_back(scene); + } + + inline void remove(Scene* scene) + { + OpenThreads::ScopedLock lock(_mutex); + for(SceneCache::iterator itr = _cache.begin(); + itr != _cache.end(); + ++itr) + { + if (scene==itr->get()) + { + _cache.erase(itr); + break; + } + } + } + + inline Scene* getScene(osg::Node* node) + { + OpenThreads::ScopedLock lock(_mutex); + for(SceneCache::iterator itr = _cache.begin(); + itr != _cache.end(); + ++itr) + { + Scene* scene = itr->get(); + if (scene && scene->getSceneData()==node) return scene; + } + return 0; + } + + typedef std::vector< osg::observer_ptr > SceneCache; + SceneCache _cache; + OpenThreads::Mutex _mutex; +}; + +static SceneSingleton& getSceneSingleton() +{ + static SceneSingleton s_sceneSingleton; + return s_sceneSingleton; } -static OpenThreads::Mutex s_sceneCacheMutex; -static OpenThreads::Mutex& getSceneCacheMutex() -{ - return s_sceneCacheMutex; +// Use a proxy to force the initialization of the the SceneSingleton during static initialization +OSG_INIT_SINGLETON_PROXY(SceneSingletonProxy, getSceneSingleton()) + } Scene::Scene(): @@ -35,25 +81,12 @@ Scene::Scene(): { setDatabasePager(osgDB::DatabasePager::create()); setImagePager(new osgDB::ImagePager); - - OpenThreads::ScopedLock lock(getSceneCacheMutex()); - getSceneCache().push_back(this); + getSceneSingleton().add(this); } Scene::~Scene() { - OpenThreads::ScopedLock lock(getSceneCacheMutex()); - for(SceneCache::iterator itr = getSceneCache().begin(); - itr != getSceneCache().end(); - ++itr) - { - Scene* scene = itr->get(); - if (scene==this) - { - getSceneCache().erase(itr); - break; - } - } + getSceneSingleton().remove(this); } void Scene::setSceneData(osg::Node* node) @@ -107,14 +140,7 @@ void Scene::updateSceneGraph(osg::NodeVisitor& updateVisitor) Scene* Scene::getScene(osg::Node* node) { - OpenThreads::ScopedLock lock(getSceneCacheMutex()); - for(SceneCache::iterator itr = getSceneCache().begin(); - itr != getSceneCache().end(); - ++itr) - { - Scene* scene = itr->get(); - if (scene && scene->getSceneData()==node) return scene; - } + return getSceneSingleton().getScene(node); return 0; }