From ea1efaac0cc5b7d228a90a99757594fe25e10cab Mon Sep 17 00:00:00 2001 From: scrawl Date: Sat, 6 Feb 2016 00:15:12 +0100 Subject: [PATCH] Use the osgDB::ObjectCache in SceneManager, cleanup --- components/resource/bulletshapemanager.hpp | 3 +++ components/resource/keyframemanager.hpp | 2 +- components/resource/niffilemanager.hpp | 2 +- components/resource/scenemanager.cpp | 27 +++++++++------------- components/resource/scenemanager.hpp | 23 ++++++++++-------- 5 files changed, 30 insertions(+), 27 deletions(-) diff --git a/components/resource/bulletshapemanager.hpp b/components/resource/bulletshapemanager.hpp index d9293896b..c8db8849e 100644 --- a/components/resource/bulletshapemanager.hpp +++ b/components/resource/bulletshapemanager.hpp @@ -26,6 +26,9 @@ namespace Resource class BulletShape; class BulletShapeInstance; + /// Handles loading, caching and "instancing" of bullet shapes. + /// A shape 'instance' is a clone of another shape, with the goal of setting a different scale on this instance. + /// @note May be used from any thread. class BulletShapeManager { public: diff --git a/components/resource/keyframemanager.hpp b/components/resource/keyframemanager.hpp index 5032d0e38..5a5cb3628 100644 --- a/components/resource/keyframemanager.hpp +++ b/components/resource/keyframemanager.hpp @@ -23,6 +23,7 @@ namespace Resource { /// @brief Managing of keyframe resources + /// @note May be used from any thread. class KeyframeManager { public: @@ -32,7 +33,6 @@ namespace Resource void clearCache(); /// Retrieve a read-only keyframe resource by name (case-insensitive). - /// @note This method is safe to call from any thread. /// @note Throws an exception if the resource is not found. osg::ref_ptr get(const std::string& name); diff --git a/components/resource/niffilemanager.hpp b/components/resource/niffilemanager.hpp index 90ad9fc29..4551cf227 100644 --- a/components/resource/niffilemanager.hpp +++ b/components/resource/niffilemanager.hpp @@ -19,7 +19,7 @@ namespace Resource { /// @brief Handles caching of NIFFiles. - /// @note The NifFileManager is completely thread safe. + /// @note May be used from any thread. class NifFileManager { public: diff --git a/components/resource/scenemanager.cpp b/components/resource/scenemanager.cpp index dd4847877..95e03b389 100644 --- a/components/resource/scenemanager.cpp +++ b/components/resource/scenemanager.cpp @@ -26,10 +26,12 @@ #include "imagemanager.hpp" #include "niffilemanager.hpp" +#include "objectcache.hpp" namespace { + /// @todo Do this in updateCallback so that animations are accounted for. class InitWorldSpaceParticlesVisitor : public osg::NodeVisitor { public: @@ -236,6 +238,7 @@ namespace Resource , mMaxAnisotropy(1) , mUnRefImageDataAfterApply(false) , mParticleSystemMask(~0u) + , mCache(new osgDB::ObjectCache) { } @@ -315,8 +318,10 @@ namespace Resource std::string normalized = name; mVFS->normalizeFilename(normalized); - Index::iterator it = mIndex.find(normalized); - if (it == mIndex.end()) + osg::ref_ptr obj = mCache->getRefFromObjectCache(normalized); + if (obj) + return osg::ref_ptr(static_cast(obj.get())); + else { osg::ref_ptr loaded; try @@ -357,11 +362,9 @@ namespace Resource if (mIncrementalCompileOperation) mIncrementalCompileOperation->add(loaded); - mIndex[normalized] = loaded; + mCache->addEntryToObjectCache(normalized, loaded); return loaded; } - else - return it->second; } osg::ref_ptr SceneManager::createInstance(const std::string &name) @@ -386,10 +389,7 @@ namespace Resource void SceneManager::releaseGLObjects(osg::State *state) { - for (Index::iterator it = mIndex.begin(); it != mIndex.end(); ++it) - { - it->second->releaseGLObjects(state); - } + mCache->releaseGLObjects(state); } void SceneManager::setIncrementalCompileOperation(osgUtil::IncrementalCompileOperation *ico) @@ -458,6 +458,8 @@ namespace Resource mMagFilter = mag; mMaxAnisotropy = std::max(1, maxAnisotropy); + mCache->clear(); + SetFilterSettingsControllerVisitor setFilterSettingsControllerVisitor (mMinFilter, mMagFilter, mMaxAnisotropy); SetFilterSettingsVisitor setFilterSettingsVisitor (mMinFilter, mMagFilter, mMaxAnisotropy); if (viewer && viewer->getSceneData()) @@ -466,13 +468,6 @@ namespace Resource viewer->getSceneData()->accept(setFilterSettingsVisitor); } - for (Index::iterator it = mIndex.begin(); it != mIndex.end(); ++it) - { - osg::Node* node = it->second; - node->accept(setFilterSettingsControllerVisitor); - node->accept(setFilterSettingsVisitor); - } - if(viewer) viewer->startThreading(); } diff --git a/components/resource/scenemanager.hpp b/components/resource/scenemanager.hpp index 3dd37111d..32bd80660 100644 --- a/components/resource/scenemanager.hpp +++ b/components/resource/scenemanager.hpp @@ -24,6 +24,11 @@ namespace osgUtil class IncrementalCompileOperation; } +namespace osgDB +{ + class ObjectCache; +} + namespace osgViewer { class Viewer; @@ -32,7 +37,8 @@ namespace osgViewer namespace Resource { - /// @brief Handles loading and caching of scenes, e.g. NIF files + /// @brief Handles loading and caching of scenes, e.g. .nif files or .osg files + /// @note Some methods of the scene manager can be used from any thread, see the methods documentation for more details. class SceneManager { public: @@ -42,20 +48,24 @@ namespace Resource /// Get a read-only copy of this scene "template" /// @note If the given filename does not exist or fails to load, an error marker mesh will be used instead. /// If even the error marker mesh can not be found, an exception is thrown. + /// @note Thread safe. osg::ref_ptr getTemplate(const std::string& name); /// Create an instance of the given scene template /// @see getTemplate + /// @note Thread safe. osg::ref_ptr createInstance(const std::string& name); /// Create an instance of the given scene template and immediately attach it to a parent node /// @see getTemplate + /// @note Not thread safe, unless parentNode is not part of the main scene graph yet. osg::ref_ptr createInstance(const std::string& name, osg::Group* parentNode); /// Attach the given scene instance to the given parent node /// @note You should have the parentNode in its intended position before calling this method, /// so that world space particles of the \a instance get transformed correctly. /// @note Assumes the given instance was not attached to any parents before. + /// @note Not thread safe, unless parentNode is not part of the main scene graph yet. void attachTo(osg::Node* instance, osg::Group* parentNode) const; /// Manually release created OpenGL objects for the given graphics context. This may be required @@ -75,11 +85,12 @@ namespace Resource /// @param mask The node mask to apply to loaded particle system nodes. void setParticleSystemMask(unsigned int mask); + /// @param viewer used to apply the new filter settings to the existing scene graph. If there is no scene yet, you can pass a NULL viewer. void setFilterSettings(const std::string &magfilter, const std::string &minfilter, const std::string &mipmap, int maxAnisotropy, osgViewer::Viewer *viewer); - /// Apply filter settings to the given texture. Note, when loading an object through this scene manager (i.e. calling getTemplate / createInstance) + /// Apply filter settings to the given texture. Note, when loading an object through this scene manager (i.e. calling getTemplate or createInstance) /// the filter settings are applied automatically. This method is provided for textures that were created outside of the SceneManager. void applyFilterSettings (osg::Texture* tex); @@ -101,16 +112,10 @@ namespace Resource unsigned int mParticleSystemMask; - // observer_ptr? - typedef std::map > Index; - Index mIndex; + osg::ref_ptr mCache; SceneManager(const SceneManager&); void operator = (const SceneManager&); - - /// @warning It is unsafe to call this function when a draw thread is using the textures. Call stopThreading() first! - void setFilterSettings(osg::Texture::FilterMode minFilter, osg::Texture::FilterMode maxFilter, int maxAnisotropy); - }; }