From 289e768ca527ac9e859ed06501847acf45291243 Mon Sep 17 00:00:00 2001 From: James Turner Date: Sun, 5 Sep 2010 20:22:12 +0100 Subject: [PATCH] Add ResourceManager, and use to find sound and model paths. --- projects/VC100/SimGear.vcxproj | 2 + projects/VC90/SimGear.vcproj | 8 +++ simgear/misc/Makefile.am | 6 +- simgear/misc/ResourceManager.cxx | 104 +++++++++++++++++++++++++++++++ simgear/misc/ResourceManager.hxx | 93 +++++++++++++++++++++++++++ simgear/misc/sg_path.cxx | 5 ++ simgear/misc/sg_path.hxx | 5 ++ simgear/scene/model/modellib.cxx | 28 ++------- simgear/scene/model/modellib.hxx | 5 -- simgear/sound/sample_openal.cxx | 8 +-- 10 files changed, 229 insertions(+), 35 deletions(-) create mode 100644 simgear/misc/ResourceManager.cxx create mode 100644 simgear/misc/ResourceManager.hxx diff --git a/projects/VC100/SimGear.vcxproj b/projects/VC100/SimGear.vcxproj index 52594439..1281e58a 100644 --- a/projects/VC100/SimGear.vcxproj +++ b/projects/VC100/SimGear.vcxproj @@ -220,6 +220,8 @@ + + diff --git a/projects/VC90/SimGear.vcproj b/projects/VC90/SimGear.vcproj index 8de61f5b..8a245af3 100644 --- a/projects/VC90/SimGear.vcproj +++ b/projects/VC90/SimGear.vcproj @@ -671,6 +671,14 @@ RelativePath="..\..\simgear\misc\zfstream.hxx" > + + + + + +#include + +namespace simgear +{ + +static ResourceManager* static_manager = NULL; + +ResourceManager::ResourceManager() +{ + +} + +ResourceManager* ResourceManager::instance() +{ + if (!static_manager) { + static_manager = new ResourceManager(); + } + + return static_manager; +} + +/** + * trivial provider using a fixed base path + */ +class BasePathProvider : public ResourceProvider +{ +public: + BasePathProvider(const SGPath& aBase, int aPriority) : + ResourceProvider(aPriority), + _base(aBase) + { + + } + + virtual SGPath resolve(const std::string& aResource, SGPath&) const + { + SGPath p(_base, aResource); + return p.exists() ? p : SGPath(); + } +private: + SGPath _base; +}; + +void ResourceManager::addBasePath(const SGPath& aPath, Priority aPriority) +{ + addProvider(new BasePathProvider(aPath, aPriority)); +} + +void ResourceManager::addProvider(ResourceProvider* aProvider) +{ + ProviderVec::iterator it = _providers.begin(); + for (; it != _providers.end(); ++it) { + if (aProvider->priority() > (*it)->priority()) { + _providers.insert(it, aProvider); + return; + } + } + + // fell out of the iteration, goes to the end of the vec + _providers.push_back(aProvider); +} + +SGPath ResourceManager::findPath(const std::string& aResource, SGPath aContext) +{ + if (!aContext.isNull()) { + SGPath r(aContext, aResource); + if (r.exists()) { + return r; + } + } + + ProviderVec::iterator it = _providers.begin(); + for (; it != _providers.end(); ++it) { + SGPath path = (*it)->resolve(aResource, aContext); + if (!path.isNull()) { + return path; + } + } + + return SGPath(); +} + +} // of namespace simgear diff --git a/simgear/misc/ResourceManager.hxx b/simgear/misc/ResourceManager.hxx new file mode 100644 index 00000000..bfaa5310 --- /dev/null +++ b/simgear/misc/ResourceManager.hxx @@ -0,0 +1,93 @@ +// ResourceManager.hxx -- manage finding resources by names/paths +// Copyright (C) 2010 James Turner +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Library General Public +// License as published by the Free Software Foundation; either +// version 2 of the License, or (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Library General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program; if not, write to the Free Software +// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. +// +// $Id$ + + +#ifndef SG_RESOURCE_MANAGER_HXX +#define SG_RESOURCE_MANAGER_HXX + +#include + +#include + +namespace simgear +{ + +class ResourceProvider; + +/** + * singleton management of resources + */ +class ResourceManager +{ +public: + typedef enum { + PRIORITY_DEFAULT = 0, + PRIORITY_FALLBACK = -100, + PRIORITY_NORMAL = 100, + PRIORITY_HIGH = 1000 + } Priority; + + static ResourceManager* instance(); + + /** + * add a simple fixed resource location, to resolve against + */ + void addBasePath(const SGPath& aPath, Priority aPriority = PRIORITY_DEFAULT); + + /** + * + */ + void addProvider(ResourceProvider* aProvider); + + /** + * given a resource name (or path), find the appropriate real resource + * path. + * @param aContext an optional current location to resolve relative names + * against (e.g a current directory) + */ + SGPath findPath(const std::string& aResource, SGPath aContext = SGPath()); + +private: + ResourceManager(); + + typedef std::vector ProviderVec; + ProviderVec _providers; +}; + +class ResourceProvider +{ +public: + virtual SGPath resolve(const std::string& aResource, SGPath& aContext) const = 0; + + virtual int priority() const + { + return _priority; + } + +protected: + ResourceProvider(int aPriority) : + _priority(aPriority) + {} + + int _priority; +}; + +} // of simgear namespace + +#endif // of header guard diff --git a/simgear/misc/sg_path.cxx b/simgear/misc/sg_path.cxx index 0de0d925..73475b0c 100644 --- a/simgear/misc/sg_path.cxx +++ b/simgear/misc/sg_path.cxx @@ -358,3 +358,8 @@ bool SGPath::isAbsolute() const return (path[0] == sgDirPathSep); } + +bool SGPath::isNull() const +{ + return path.empty() || (path == ""); +} diff --git a/simgear/misc/sg_path.hxx b/simgear/misc/sg_path.hxx index 6f8968b7..69dd5944 100644 --- a/simgear/misc/sg_path.hxx +++ b/simgear/misc/sg_path.hxx @@ -166,6 +166,11 @@ public: * I.e starts with a directory seperator, or a single character + colon */ bool isAbsolute() const; + + /** + * check for default constructed path + */ + bool isNull() const; private: void fix(); diff --git a/simgear/scene/model/modellib.cxx b/simgear/scene/model/modellib.cxx index cdcb724f..ae90f1a4 100644 --- a/simgear/scene/model/modellib.cxx +++ b/simgear/scene/model/modellib.cxx @@ -30,6 +30,7 @@ #include #include #include +#include #include "SGPagedLOD.hxx" #include "SGReaderWriterXML.hxx" @@ -47,7 +48,6 @@ ModelRegistryCallbackProxy g_xmlCallbackProxy("xml"); SGPropertyNode_ptr SGModelLib::static_propRoot; SGModelLib::panel_func SGModelLib::static_panelFunc = NULL; -SGModelLib::resolve_func SGModelLib::static_resolver = NULL; //////////////////////////////////////////////////////////////////////// // Implementation of SGModelLib. @@ -67,33 +67,15 @@ void SGModelLib::setPanelFunc(panel_func pf) static_panelFunc = pf; } -void SGModelLib::setResolveFunc(resolve_func rf) -{ - static_resolver = rf; -} - std::string SGModelLib::findDataFile(const std::string& file, const osgDB::ReaderWriter::Options* opts, SGPath currentPath) { - // if we have a valid current path, first attempt to resolve relative - // to that path - if (currentPath.exists()) { - SGPath p = currentPath; - p.append(file); - if (p.exists()) { - return p.str(); - } - } - - // next try the resolve function if one has been defined - if (static_resolver) { - SGPath p = static_resolver(file); - if (p.exists()) { - return p.str(); - } + SGPath p = ResourceManager::instance()->findPath(file, currentPath); + if (p.exists()) { + return p.str(); } - + // finally hand on to standard OSG behaviour return osgDB::findDataFile(file, opts); } diff --git a/simgear/scene/model/modellib.hxx b/simgear/scene/model/modellib.hxx index d28f692b..63358855 100644 --- a/simgear/scene/model/modellib.hxx +++ b/simgear/scene/model/modellib.hxx @@ -44,16 +44,12 @@ class SGModelLib public: typedef osg::Node *(*panel_func)(SGPropertyNode *); - typedef SGPath (*resolve_func)(const std::string& path); - static void init(const std::string &root_dir); static void setPropRoot(SGPropertyNode* root); static void setPanelFunc(panel_func pf); - static void setResolveFunc(resolve_func rf); - // Load a 3D model (any format) // data->modelLoaded() will be called after the model is loaded static osg::Node* loadModel(const std::string &path, @@ -80,7 +76,6 @@ protected: private: static SGPropertyNode_ptr static_propRoot; static panel_func static_panelFunc; - static resolve_func static_resolver; }; diff --git a/simgear/sound/sample_openal.cxx b/simgear/sound/sample_openal.cxx index 7b355002..022cb40d 100644 --- a/simgear/sound/sample_openal.cxx +++ b/simgear/sound/sample_openal.cxx @@ -33,6 +33,7 @@ #include #include #include +#include #include "soundmgr_openal.hxx" #include "sample_openal.hxx" @@ -110,11 +111,8 @@ SGSoundSample::SGSoundSample( const char *path, const char *file ) : _static_changed(true), _is_file(true) { - SGPath samplepath( path ); - if ( strlen(file) ) { - samplepath.append( file ); - } - _refname = samplepath.str(); + SGPath p = simgear::ResourceManager::instance()->findPath(file); + _refname = p.str(); } // constructor -- 2.39.5