From 289e768ca527ac9e859ed06501847acf45291243 Mon Sep 17 00:00:00 2001 From: James Turner Date: Sun, 5 Sep 2010 20:22:12 +0100 Subject: [PATCH 1/4] 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(); - } + SGPath p = ResourceManager::instance()->findPath(file, currentPath); + 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(); - } - } - + // 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 From d75ce1e12ee4fba106bc6595a2fb1b3b50ccbbc1 Mon Sep 17 00:00:00 2001 From: James Turner Date: Mon, 6 Sep 2010 09:26:46 +0100 Subject: [PATCH 2/4] Pass current-dir down through XMLSound (should allow relative paths in sound XML files) --- simgear/sound/sample_openal.cxx | 4 ++-- simgear/sound/sample_openal.hxx | 3 +-- simgear/sound/xmlsound.cxx | 4 ++-- simgear/sound/xmlsound.hxx | 2 +- 4 files changed, 6 insertions(+), 7 deletions(-) diff --git a/simgear/sound/sample_openal.cxx b/simgear/sound/sample_openal.cxx index 022cb40d..3c9cb864 100644 --- a/simgear/sound/sample_openal.cxx +++ b/simgear/sound/sample_openal.cxx @@ -79,7 +79,7 @@ SGSoundSample::SGSoundSample() : } // constructor -SGSoundSample::SGSoundSample( const char *path, const char *file ) : +SGSoundSample::SGSoundSample(const char *file, const SGPath& currentDir) : _absolute_pos(SGVec3d::zeros()), _relative_pos(SGVec3d::zeros()), _direction(SGVec3d::zeros()), @@ -111,7 +111,7 @@ SGSoundSample::SGSoundSample( const char *path, const char *file ) : _static_changed(true), _is_file(true) { - SGPath p = simgear::ResourceManager::instance()->findPath(file); + SGPath p = simgear::ResourceManager::instance()->findPath(file, currentDir); _refname = p.str(); } diff --git a/simgear/sound/sample_openal.hxx b/simgear/sound/sample_openal.hxx index 491ba572..b2afba4f 100644 --- a/simgear/sound/sample_openal.hxx +++ b/simgear/sound/sample_openal.hxx @@ -60,11 +60,10 @@ public: /** * Constructor - * @param path Path name to sound * @param file File name of sound Buffer data is freed by the sample group */ - SGSoundSample( const char *path, const char *file ); + SGSoundSample(const char *file, const SGPath& currentDir); /** * Constructor. diff --git a/simgear/sound/xmlsound.cxx b/simgear/sound/xmlsound.cxx index 616d9514..2ca9cdfa 100644 --- a/simgear/sound/xmlsound.cxx +++ b/simgear/sound/xmlsound.cxx @@ -84,7 +84,7 @@ SGXmlSound::~SGXmlSound() void SGXmlSound::init(SGPropertyNode *root, SGPropertyNode *node, SGSampleGroup *sgrp, SGSampleGroup *avionics, - const string &path) + const SGPath& currentDir) { // @@ -272,7 +272,7 @@ SGXmlSound::init(SGPropertyNode *root, SGPropertyNode *node, } else { _sgrp = sgrp; } - _sample = new SGSoundSample( path.c_str(), node->getStringValue("path", "")); + _sample = new SGSoundSample(node->getStringValue("path", ""), currentDir); if (!_sample->file_path().exists()) { throw sg_io_exception("XML sound: couldn't find file: " + _sample->file_path().str()); } diff --git a/simgear/sound/xmlsound.hxx b/simgear/sound/xmlsound.hxx index 141f5eef..f3635b08 100644 --- a/simgear/sound/xmlsound.hxx +++ b/simgear/sound/xmlsound.hxx @@ -104,7 +104,7 @@ public: * @param path The path where the audio files remain. */ virtual void init (SGPropertyNode *, SGPropertyNode *, SGSampleGroup *, - SGSampleGroup *, const string &); + SGSampleGroup *, const SGPath& currentDir); /** * Check whether an event has happened and if action has to be taken. From 49270e99e5835adc1f3a202b8f1f52893efb548e Mon Sep 17 00:00:00 2001 From: James Turner Date: Mon, 6 Sep 2010 12:30:13 +0100 Subject: [PATCH 3/4] Fix up tests for revised SGSoundSample ctor. --- simgear/sound/openal_test2.cxx | 12 ++++++------ simgear/sound/openal_test3.cxx | 2 +- 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/simgear/sound/openal_test2.cxx b/simgear/sound/openal_test2.cxx index eb0da57e..d935b8d7 100644 --- a/simgear/sound/openal_test2.cxx +++ b/simgear/sound/openal_test2.cxx @@ -26,7 +26,7 @@ int main( int argc, char *argv[] ) { smgr->set_position( SGVec3d::fromGeod(pos), pos ); smgr->activate(); - SGSoundSample *sample1 = new SGSoundSample( SRC_DIR, "jet.wav" ); + SGSoundSample *sample1 = new SGSoundSample("jet.wav", SRC_DIR); sample1->set_volume(1.0); sample1->set_pitch(1.0); sample1->play_looped(); @@ -35,7 +35,7 @@ int main( int argc, char *argv[] ) { printf("playing sample1\n"); sleep(1); - SGSoundSample *sample2 = new SGSoundSample( SRC_DIR, "jet.wav" ); + SGSoundSample *sample2 = new SGSoundSample("jet.wav", SRC_DIR); sample2->set_volume(0.5); sample2->set_pitch(0.4); sample2->play_looped(); @@ -44,7 +44,7 @@ int main( int argc, char *argv[] ) { printf("playing sample2\n"); sleep(1); - SGSoundSample *sample3 = new SGSoundSample( SRC_DIR, "jet.wav" ); + SGSoundSample *sample3 = new SGSoundSample("jet.wav", SRC_DIR); sample3->set_volume(0.5); sample3->set_pitch(0.8); sample3->play_looped(); @@ -53,7 +53,7 @@ int main( int argc, char *argv[] ) { printf("playing sample3\n"); sleep(1); - SGSoundSample *sample4 = new SGSoundSample( SRC_DIR, "jet.wav" ); + SGSoundSample *sample4 = new SGSoundSample("jet.wav", SRC_DIR); sample4->set_volume(0.5); sample4->set_pitch(1.2); sample4->play_looped(); @@ -62,7 +62,7 @@ int main( int argc, char *argv[] ) { printf("playing sample4\n"); sleep(1); - SGSoundSample *sample5 = new SGSoundSample( SRC_DIR, "jet.wav" ); + SGSoundSample *sample5 = new SGSoundSample("jet.wav", SRC_DIR); sample5->set_volume(0.5); sample5->set_pitch(1.6); sample5->play_looped(); @@ -71,7 +71,7 @@ int main( int argc, char *argv[] ) { printf("playing sample5\n"); sleep(1); - SGSoundSample *sample6 = new SGSoundSample( SRC_DIR, "jet.wav" ); + SGSoundSample *sample6 = new SGSoundSample("jet.wav", SRC_DIR); sample6->set_volume(0.5); sample6->set_pitch(2.0); sample6->play_looped(); diff --git a/simgear/sound/openal_test3.cxx b/simgear/sound/openal_test3.cxx index 96a57a04..70260289 100644 --- a/simgear/sound/openal_test3.cxx +++ b/simgear/sound/openal_test3.cxx @@ -26,7 +26,7 @@ int main( int argc, char *argv[] ) { smgr->activate(); printf("default position and orientation\n"); - SGSoundSample *sample1 = new SGSoundSample( SRC_DIR, "jet.wav" ); + SGSoundSample *sample1 = new SGSoundSample("jet.wav", SRC_DIR); sample1->set_volume(1.0); sample1->set_pitch(1.0); sample1->play_looped(); From a7697f6095eca0a2b8e1129d8430aebb62138509 Mon Sep 17 00:00:00 2001 From: James Turner Date: Mon, 6 Sep 2010 14:27:58 +0100 Subject: [PATCH 4/4] Second attempt to fixed OpenAL tests. --- simgear/sound/openal_test2.cxx | 14 ++++++++------ simgear/sound/openal_test3.cxx | 4 +++- 2 files changed, 11 insertions(+), 7 deletions(-) diff --git a/simgear/sound/openal_test2.cxx b/simgear/sound/openal_test2.cxx index d935b8d7..13a62d63 100644 --- a/simgear/sound/openal_test2.cxx +++ b/simgear/sound/openal_test2.cxx @@ -26,7 +26,9 @@ int main( int argc, char *argv[] ) { smgr->set_position( SGVec3d::fromGeod(pos), pos ); smgr->activate(); - SGSoundSample *sample1 = new SGSoundSample("jet.wav", SRC_DIR); + SGPath srcDir(SRC_DIR); + + SGSoundSample *sample1 = new SGSoundSample("jet.wav", srcDir); sample1->set_volume(1.0); sample1->set_pitch(1.0); sample1->play_looped(); @@ -35,7 +37,7 @@ int main( int argc, char *argv[] ) { printf("playing sample1\n"); sleep(1); - SGSoundSample *sample2 = new SGSoundSample("jet.wav", SRC_DIR); + SGSoundSample *sample2 = new SGSoundSample("jet.wav", srcDir); sample2->set_volume(0.5); sample2->set_pitch(0.4); sample2->play_looped(); @@ -44,7 +46,7 @@ int main( int argc, char *argv[] ) { printf("playing sample2\n"); sleep(1); - SGSoundSample *sample3 = new SGSoundSample("jet.wav", SRC_DIR); + SGSoundSample *sample3 = new SGSoundSample("jet.wav", srcDir); sample3->set_volume(0.5); sample3->set_pitch(0.8); sample3->play_looped(); @@ -53,7 +55,7 @@ int main( int argc, char *argv[] ) { printf("playing sample3\n"); sleep(1); - SGSoundSample *sample4 = new SGSoundSample("jet.wav", SRC_DIR); + SGSoundSample *sample4 = new SGSoundSample("jet.wav", srcDir); sample4->set_volume(0.5); sample4->set_pitch(1.2); sample4->play_looped(); @@ -62,7 +64,7 @@ int main( int argc, char *argv[] ) { printf("playing sample4\n"); sleep(1); - SGSoundSample *sample5 = new SGSoundSample("jet.wav", SRC_DIR); + SGSoundSample *sample5 = new SGSoundSample("jet.wav", srcDir); sample5->set_volume(0.5); sample5->set_pitch(1.6); sample5->play_looped(); @@ -71,7 +73,7 @@ int main( int argc, char *argv[] ) { printf("playing sample5\n"); sleep(1); - SGSoundSample *sample6 = new SGSoundSample("jet.wav", SRC_DIR); + SGSoundSample *sample6 = new SGSoundSample("jet.wav", srcDir); sample6->set_volume(0.5); sample6->set_pitch(2.0); sample6->play_looped(); diff --git a/simgear/sound/openal_test3.cxx b/simgear/sound/openal_test3.cxx index 70260289..fafb4045 100644 --- a/simgear/sound/openal_test3.cxx +++ b/simgear/sound/openal_test3.cxx @@ -25,8 +25,10 @@ int main( int argc, char *argv[] ) { smgr->set_volume(0.9); smgr->activate(); + SGPath srcDir(SRC_DIR); + printf("default position and orientation\n"); - SGSoundSample *sample1 = new SGSoundSample("jet.wav", SRC_DIR); + SGSoundSample *sample1 = new SGSoundSample("jet.wav", srcDir); sample1->set_volume(1.0); sample1->set_pitch(1.0); sample1->play_looped();