diff --git a/examples/osgcallback/osgcallback.cpp b/examples/osgcallback/osgcallback.cpp index f9ada5b18..5fc703087 100644 --- a/examples/osgcallback/osgcallback.cpp +++ b/examples/osgcallback/osgcallback.cpp @@ -104,6 +104,20 @@ class InsertCallbacksVisitor : public osg::NodeVisitor } }; +class MyReadFileCallback : public osgDB::Registry::ReadFileCallback +{ +public: + virtual osgDB::ReaderWriter::ReadResult readNode(const std::string& fileName, osgDB::Registry::CacheHintOptions useObjectCache) + { + std::cout<<"before readNode"<readNodeImplementation(fileName,useObjectCache); + std::cout<<"after readNode"<setCommandLineUsage(arguments.getApplicationName()+" [options] filename ..."); arguments.getApplicationUsage()->addCommandLineOption("-h or --help","Display this information"); + // set the osgDB::Registy the read file callback to catch all requests for reading files. + osgDB::Registry::instance()->setReadFileCallback(new MyReadFileCallback()); + // initialize the viewer. osgProducer::Viewer viewer(arguments); diff --git a/include/osgDB/ReadFile b/include/osgDB/ReadFile index a44f711a6..da782da0d 100644 --- a/include/osgDB/ReadFile +++ b/include/osgDB/ReadFile @@ -33,7 +33,7 @@ namespace osgDB { * The osgDB::Registry is used to load the appropriate ReaderWriter plugin * for the filename extension, and this plugin then handles the request * to read the specified file.*/ -extern OSGDB_EXPORT osg::Object* readObjectFile(const std::string& filename,bool useObjectCache); +extern OSGDB_EXPORT osg::Object* readObjectFile(const std::string& filename,Registry::CacheHintOptions useObjectCache); /** Read an osg::Object from file. * Return valid osg::Object on success, @@ -54,7 +54,7 @@ inline osg::Object* readObjectFile(const std::string& filename) * The osgDB::Registry is used to load the appropriate ReaderWriter plugin * for the filename extension, and this plugin then handles the request * to read the specified file.*/ -extern OSGDB_EXPORT osg::Image* readImageFile(const std::string& filename,bool useObjectCache); +extern OSGDB_EXPORT osg::Image* readImageFile(const std::string& filename,Registry::CacheHintOptions useObjectCache); /** Read an osg::Image from file. * Return valid osg::Image on success, @@ -74,7 +74,7 @@ inline osg::Image* readImageFile(const std::string& filename) * The osgDB::Registry is used to load the appropriate ReaderWriter plugin * for the filename extension, and this plugin then handles the request * to read the specified file.*/ -extern OSGDB_EXPORT osg::HeightField* readHeightFieldFile(const std::string& filename,bool useObjectCache); +extern OSGDB_EXPORT osg::HeightField* readHeightFieldFile(const std::string& filename,Registry::CacheHintOptions useObjectCache); /** Read an osg::HeightField from file. * Return valid osg::HeightField on success, @@ -94,7 +94,7 @@ inline osg::HeightField* readHeightFieldFile(const std::string& filename) * The osgDB::Registry is used to load the appropriate ReaderWriter plugin * for the filename extension, and this plugin then handles the request * to read the specified file.*/ -extern OSGDB_EXPORT osg::Node* readNodeFile(const std::string& filename,bool useObjectCache); +extern OSGDB_EXPORT osg::Node* readNodeFile(const std::string& filename,Registry::CacheHintOptions useObjectCache); /** Read an osg::Node from file. * Return valid osg::Node on success, @@ -111,7 +111,7 @@ inline osg::Node* readNodeFile(const std::string& filename) /** Read an osg::Node subgraph from files, creating a osg::Group to contain the nodes if more * than one subgraph has been loaded. * Use the useObjectCache flag to override the osgDB::Regisytr::getUseObjectCacheHint().*/ -extern OSGDB_EXPORT osg::Node* readNodeFiles(std::vector& commandLine,bool useObjectCache); +extern OSGDB_EXPORT osg::Node* readNodeFiles(std::vector& commandLine,Registry::CacheHintOptions useObjectCache); /** Read an osg::Node subgraph from files, creating a osg::Group to contain the nodes if more * than one subgraph has been loaded.*/ @@ -124,7 +124,7 @@ inline osg::Node* readNodeFiles(std::vector& commandLine) /** Read an osg::Node subgraph from files, creating a osg::Group to contain the nodes if more * than one subgraph has been loaded. * Use the useObjectCache flag to override the osgDB::Regisytr::getUseObjectCacheHint().*/ -extern OSGDB_EXPORT osg::Node* readNodeFiles(osg::ArgumentParser& parser,bool useObjectCache); +extern OSGDB_EXPORT osg::Node* readNodeFiles(osg::ArgumentParser& parser,Registry::CacheHintOptions useObjectCache); /** Read an osg::Node subgraph from files, creating a osg::Group to contain the nodes if more * than one subgraph has been loaded.*/ diff --git a/include/osgDB/Registry b/include/osgDB/Registry index dc3cfdbee..f222179bb 100644 --- a/include/osgDB/Registry +++ b/include/osgDB/Registry @@ -32,21 +32,21 @@ namespace osgDB { /** basic structure for custom runtime inheritance checking */ struct basic_type_wrapper { - virtual bool matches(const osg::Object *proto) const = 0; + virtual bool matches(const osg::Object *proto) const = 0; }; /** a class template that checks inheritance between a given Object's class and a class defined at compile time through - the template parameter T. - This is used in conjunction with readObjectOfType() to - specify an abstract class as reference type. + the template parameter T. + This is used in conjunction with readObjectOfType() to + specify an abstract class as reference type. **/ template struct type_wrapper: basic_type_wrapper { - bool matches(const osg::Object *proto) const - { - return dynamic_cast(proto) != 0; - } + bool matches(const osg::Object *proto) const + { + return dynamic_cast(proto) != 0; + } }; /** list of directories to search through which searching for files. */ @@ -68,6 +68,21 @@ class OSGDB_EXPORT Registry : public osg::Referenced { public: + enum CacheHintOptions + { + CACHE_NONE = 0, + CACHE_NODES = 1, + CACHE_IMAGES = 2, + CACHE_HEIGHTFIELDS = 4, + CACHE_OBJECTS = 8, + CACHE_ALL = CACHE_NODES | + CACHE_IMAGES | + CACHE_HEIGHTFIELDS | + CACHE_OBJECTS + }; + + + static Registry* instance(bool erase = false); /** read the command line arguments.*/ @@ -117,21 +132,144 @@ class OSGDB_EXPORT Registry : public osg::Referenced bool writeObject(const osg::Object& obj,Output& fw); - ReaderWriter::ReadResult readObject(const std::string& fileName,bool useObjectCache); - ReaderWriter::WriteResult writeObject(const osg::Object& obj, const std::string& fileName); + class ReadFileCallback : public osg::Referenced + { + public: + + virtual ReaderWriter::ReadResult readObject(const std::string& filename, CacheHintOptions options) + { + return osgDB::Registry::instance()->readObjectImplementation(filename,options); + } - ReaderWriter::ReadResult readImage(const std::string& fileName,bool useObjectCache); - ReaderWriter::WriteResult writeImage(const osg::Image& obj, const std::string& fileName); + virtual ReaderWriter::ReadResult readImage(const std::string& filename, CacheHintOptions options) + { + return osgDB::Registry::instance()->readImageImplementation(filename,options); + } + + virtual ReaderWriter::ReadResult readHeightField(const std::string& filename, CacheHintOptions options) + { + return osgDB::Registry::instance()->readImageImplementation(filename,options); + } + + virtual ReaderWriter::ReadResult readNode(const std::string& filename, CacheHintOptions options) + { + return osgDB::Registry::instance()->readImageImplementation(filename,options); + } + + protected: + virtual ~ReadFileCallback() {} + }; - ReaderWriter::ReadResult readHeightField(const std::string& fileName,bool useObjectCache); - ReaderWriter::WriteResult writeHeightField(const osg::HeightField& obj, const std::string& fileName); + /** Set the Registry callback to use in place of the default readFile calls.*/ + void setReadFileCallback( ReadFileCallback* cb) { _readFileCallback = cb; } - ReaderWriter::ReadResult readNode(const std::string& fileName,bool useObjectCache); - ReaderWriter::WriteResult writeNode(const osg::Node& node, const std::string& fileName); + /** Get the readFile callback.*/ + ReadFileCallback* getReadFileCallback() { return _readFileCallback.get(); } + + /** Get the const readFile callback.*/ + const ReadFileCallback* getReadFileCallback() const { return _readFileCallback.get(); } + + + ReaderWriter::ReadResult readObject(const std::string& fileName,CacheHintOptions useObjectCache) + { + if (_readFileCallback.valid()) return _readFileCallback->readObject(fileName,useObjectCache); + else return readObjectImplementation(fileName,useObjectCache); + } + ReaderWriter::ReadResult readObjectImplementation(const std::string& fileName,CacheHintOptions useObjectCache); + + ReaderWriter::ReadResult readImage(const std::string& fileName,CacheHintOptions useObjectCache) + { + if (_readFileCallback.valid()) return _readFileCallback->readImage(fileName,useObjectCache); + else return readImageImplementation(fileName,useObjectCache); + } + ReaderWriter::ReadResult readImageImplementation(const std::string& fileName,CacheHintOptions useObjectCache); + + ReaderWriter::ReadResult readHeightField(const std::string& fileName,CacheHintOptions useObjectCache) + { + if (_readFileCallback.valid()) return _readFileCallback->readHeightField(fileName,useObjectCache); + else return readHeightFieldImplementation(fileName,useObjectCache); + } + ReaderWriter::ReadResult readHeightFieldImplementation(const std::string& fileName,CacheHintOptions useObjectCache); + + ReaderWriter::ReadResult readNode(const std::string& fileName,CacheHintOptions useObjectCache) + { + if (_readFileCallback.valid()) return _readFileCallback->readNode(fileName,useObjectCache); + else return readNodeImplementation(fileName,useObjectCache); + } + ReaderWriter::ReadResult readNodeImplementation(const std::string& fileName,CacheHintOptions useObjectCache); + + + class WriteFileCallback : public osg::Referenced + { + public: + + virtual ReaderWriter::WriteResult writeObject(const osg::Object& obj, const std::string& fileName) + { + return osgDB::Registry::instance()->writeObjectImplementation(obj,fileName); + } + + virtual ReaderWriter::WriteResult writeImage(const osg::Image& obj, const std::string& fileName) + { + return osgDB::Registry::instance()->writeImageImplementation(obj,fileName); + } + + virtual ReaderWriter::WriteResult writeHeightField(const osg::HeightField& obj, const std::string& fileName) + { + return osgDB::Registry::instance()->writeHeightFieldImplementation(obj,fileName); + } + + virtual ReaderWriter::WriteResult writeNode(const osg::Node& obj, const std::string& fileName) + { + return osgDB::Registry::instance()->writeNodeImplementation(obj,fileName); + } + + protected: + virtual ~WriteFileCallback() {} + }; + + /** Set the Registry callback to use in place of the default writeFile calls.*/ + void setWriteFileCallback( WriteFileCallback* cb) { _writeFileCallback = cb; } + + /** Get the writeFile callback.*/ + WriteFileCallback* getWriteFileCallback() { return _writeFileCallback.get(); } + + /** Get the const writeFile callback.*/ + const WriteFileCallback* getWriteFileCallback() const { return _writeFileCallback.get(); } + + + ReaderWriter::WriteResult writeObject(const osg::Object& obj, const std::string& fileName) + { + if (_writeFileCallback.valid()) return _writeFileCallback->writeObject(obj,fileName); + else return writeObjectImplementation(obj,fileName); + } + ReaderWriter::WriteResult writeObjectImplementation(const osg::Object& obj, const std::string& fileName); + + ReaderWriter::WriteResult writeImage(const osg::Image& obj, const std::string& fileName) + { + if (_writeFileCallback.valid()) return _writeFileCallback->writeImage(obj,fileName); + else return writeImageImplementation(obj,fileName); + } + ReaderWriter::WriteResult writeImageImplementation(const osg::Image& obj, const std::string& fileName); + + ReaderWriter::WriteResult writeHeightField(const osg::HeightField& obj, const std::string& fileName) + { + if (_writeFileCallback.valid()) return _writeFileCallback->writeHeightField(obj,fileName); + else return writeHeightFieldImplementation(obj,fileName); + } + ReaderWriter::WriteResult writeHeightFieldImplementation(const osg::HeightField& obj, const std::string& fileName); + + ReaderWriter::WriteResult writeNode(const osg::Node& node, const std::string& fileName) + { + if (_writeFileCallback.valid()) return _writeFileCallback->writeNode(node,fileName); + else return writeNodeImplementation(node,fileName); + } + ReaderWriter::WriteResult writeNodeImplementation(const osg::Node& node, const std::string& fileName); + void setCreateNodeFromImage(bool flag) { _createNodeFromImage = flag; } bool getCreateNodeFromImage() const { return _createNodeFromImage; } + void setOptions(ReaderWriter::Options* opt) { _options = opt; } ReaderWriter::Options* getOptions() { return _options.get(); } const ReaderWriter::Options* getOptions() const { return _options.get(); } @@ -201,10 +339,10 @@ class OSGDB_EXPORT Registry : public osg::Referenced void addEntryToObjectCache(const std::string& filename, osg::Object* object, double timestamp = 0.0); /** Set whether the Registry::ObjectCache should be used by default.*/ - void setUseObjectCacheHint(bool useObjectCache) { _useObjectCacheHint = useObjectCache; } + void setUseObjectCacheHint(CacheHintOptions useObjectCache) { _useObjectCacheHint = useObjectCache; } /** Get whether the Registry::ObjectCache should be used by default.*/ - bool getUseObjectCacheHint() const { return _useObjectCacheHint; } + CacheHintOptions getUseObjectCacheHint() const { return _useObjectCacheHint; } /** get the attached library with specified name.*/ DynamicLibrary* getLibrary(const std::string& fileName); @@ -261,6 +399,9 @@ class OSGDB_EXPORT Registry : public osg::Referenced ReaderWriter::ReadResult readHeightField(const std::string& fileName); ReaderWriter::ReadResult readNode(const std::string& fileName); + osg::ref_ptr _readFileCallback; + osg::ref_ptr _writeFileCallback; + DotOsgWrapperMap _objectWrapperMap; DotOsgWrapperMap _imageWrapperMap; DotOsgWrapperMap _drawableWrapperMap; @@ -273,9 +414,9 @@ class OSGDB_EXPORT Registry : public osg::Referenced DynamicLibraryList _dlList; bool _openingLibrary; - - // map to alias to extensions to plugins. - ExtensionAliasMap _extAliasMap; + + // map to alias to extensions to plugins. + ExtensionAliasMap _extAliasMap; // options to pass to reader writers. osg::ref_ptr _options; @@ -283,7 +424,7 @@ class OSGDB_EXPORT Registry : public osg::Referenced FilePathList _dataFilePath; FilePathList _libraryFilePath; - bool _useObjectCacheHint; + CacheHintOptions _useObjectCacheHint; ObjectCache _objectCache; osg::ref_ptr _databasePager; diff --git a/src/osgDB/ReadFile.cpp b/src/osgDB/ReadFile.cpp index 4c2d9a5c9..4079b4637 100644 --- a/src/osgDB/ReadFile.cpp +++ b/src/osgDB/ReadFile.cpp @@ -24,7 +24,7 @@ using namespace osg; using namespace osgDB; -Object* osgDB::readObjectFile(const std::string& filename,bool useObjectCache) +Object* osgDB::readObjectFile(const std::string& filename,Registry::CacheHintOptions useObjectCache) { ReaderWriter::ReadResult rr = Registry::instance()->readObject(filename,useObjectCache); if (rr.validObject()) return rr.takeObject(); @@ -33,7 +33,7 @@ Object* osgDB::readObjectFile(const std::string& filename,bool useObjectCache) } -Image* osgDB::readImageFile(const std::string& filename,bool useObjectCache) +Image* osgDB::readImageFile(const std::string& filename,Registry::CacheHintOptions useObjectCache) { ReaderWriter::ReadResult rr = Registry::instance()->readImage(filename,useObjectCache); if (rr.validImage()) return rr.takeImage(); @@ -42,7 +42,7 @@ Image* osgDB::readImageFile(const std::string& filename,bool useObjectCache) } -HeightField* osgDB::readHeightFieldFile(const std::string& filename,bool useObjectCache) +HeightField* osgDB::readHeightFieldFile(const std::string& filename,Registry::CacheHintOptions useObjectCache) { ReaderWriter::ReadResult rr = Registry::instance()->readHeightField(filename,useObjectCache); if (rr.validHeightField()) return rr.takeHeightField(); @@ -51,7 +51,7 @@ HeightField* osgDB::readHeightFieldFile(const std::string& filename,bool useObje } -Node* osgDB::readNodeFile(const std::string& filename,bool useObjectCache) +Node* osgDB::readNodeFile(const std::string& filename,Registry::CacheHintOptions useObjectCache) { ReaderWriter::ReadResult rr = Registry::instance()->readNode(filename,useObjectCache); if (rr.validNode()) return rr.takeNode(); @@ -59,7 +59,7 @@ Node* osgDB::readNodeFile(const std::string& filename,bool useObjectCache) return NULL; } -Node* osgDB::readNodeFiles(std::vector& commandLine,bool useObjectCache) +Node* osgDB::readNodeFiles(std::vector& commandLine,Registry::CacheHintOptions useObjectCache) { typedef std::vector NodeList; NodeList nodeList; @@ -108,7 +108,7 @@ Node* osgDB::readNodeFiles(std::vector& commandLine,bool useObjectC } -Node* osgDB::readNodeFiles(osg::ArgumentParser& arguments,bool useObjectCache) +Node* osgDB::readNodeFiles(osg::ArgumentParser& arguments,Registry::CacheHintOptions useObjectCache) { typedef std::vector NodeList; diff --git a/src/osgDB/Registry.cpp b/src/osgDB/Registry.cpp index 75aca6f37..2f18debe1 100644 --- a/src/osgDB/Registry.cpp +++ b/src/osgDB/Registry.cpp @@ -137,7 +137,7 @@ Registry::Registry() _createNodeFromImage = false; _openingLibrary = false; - _useObjectCacheHint = false; + _useObjectCacheHint = CACHE_NONE; initFilePathLists(); @@ -1244,9 +1244,11 @@ ReaderWriter::ReadResult Registry::readObject(const std::string& fileName) return results.front(); } -ReaderWriter::ReadResult Registry::readObject(const std::string& file,bool useObjectCache) +ReaderWriter::ReadResult Registry::readObjectImplementation(const std::string& constFile,CacheHintOptions useObjectCache) { - if (useObjectCache) + std::string file(constFile); + + if (useObjectCache & CACHE_OBJECTS) { // search for entry in the object cache. ObjectCache::iterator oitr=_objectCache.find(file); @@ -1288,7 +1290,7 @@ ReaderWriter::ReadResult Registry::readObject(const std::string& file,bool useOb } } -ReaderWriter::WriteResult Registry::writeObject(const Object& obj,const std::string& fileName) +ReaderWriter::WriteResult Registry::writeObjectImplementation(const Object& obj,const std::string& fileName) { // record the errors reported by readerwriters. typedef std::vector Results; @@ -1390,10 +1392,9 @@ ReaderWriter::ReadResult Registry::readImage(const std::string& fileName) } -ReaderWriter::ReadResult Registry::readImage(const std::string& file,bool useObjectCache) +ReaderWriter::ReadResult Registry::readImageImplementation(const std::string& file,CacheHintOptions useObjectCache) { - - if (useObjectCache) + if (useObjectCache & CACHE_IMAGES) { // search for entry in the object cache. ObjectCache::iterator oitr=_objectCache.find(file); @@ -1439,7 +1440,7 @@ ReaderWriter::ReadResult Registry::readImage(const std::string& file,bool useObj -ReaderWriter::WriteResult Registry::writeImage(const Image& image,const std::string& fileName) +ReaderWriter::WriteResult Registry::writeImageImplementation(const Image& image,const std::string& fileName) { // record the errors reported by readerwriters. typedef std::vector Results; @@ -1541,9 +1542,9 @@ ReaderWriter::ReadResult Registry::readHeightField(const std::string& fileName) } -ReaderWriter::ReadResult Registry::readHeightField(const std::string& file,bool useObjectCache) +ReaderWriter::ReadResult Registry::readHeightFieldImplementation(const std::string& file,CacheHintOptions useObjectCache) { - if (useObjectCache) + if (useObjectCache & CACHE_HEIGHTFIELDS) { // search for entry in the object cache. ObjectCache::iterator oitr=_objectCache.find(file); @@ -1589,7 +1590,7 @@ ReaderWriter::ReadResult Registry::readHeightField(const std::string& file,bool -ReaderWriter::WriteResult Registry::writeHeightField(const HeightField& HeightField,const std::string& fileName) +ReaderWriter::WriteResult Registry::writeHeightFieldImplementation(const HeightField& HeightField,const std::string& fileName) { // record the errors reported by readerwriters. typedef std::vector Results; @@ -1686,7 +1687,7 @@ ReaderWriter::ReadResult Registry::readNode(const std::string& fileName) // need to sort out. - bool useObjectCache=true; + CacheHintOptions useObjectCache = CACHE_ALL; if (_createNodeFromImage) { @@ -1703,9 +1704,9 @@ ReaderWriter::ReadResult Registry::readNode(const std::string& fileName) return results.front(); } -ReaderWriter::ReadResult Registry::readNode(const std::string& file,bool useObjectCache) +ReaderWriter::ReadResult Registry::readNodeImplementation(const std::string& file,CacheHintOptions useObjectCache) { - if (useObjectCache) + if (useObjectCache & CACHE_NODES) { // search for entry in the object cache. ObjectCache::iterator oitr=_objectCache.find(file); @@ -1747,7 +1748,7 @@ ReaderWriter::ReadResult Registry::readNode(const std::string& file,bool useObje } } -ReaderWriter::WriteResult Registry::writeNode(const Node& node,const std::string& fileName) +ReaderWriter::WriteResult Registry::writeNodeImplementation(const Node& node,const std::string& fileName) { // record the errors reported by readerwriters. typedef std::vector Results;