From 5fd1ece440061ad35c7eb5f8b5ea47712ca85b0a Mon Sep 17 00:00:00 2001 From: Robert Osfield Date: Fri, 24 Jun 2011 12:40:18 +0000 Subject: [PATCH] Implemented missing Archive::readShader/writeShader, and added searching of the archive list in Registr::read() so that files that are stored in the archives can be found. --- include/osgDB/Archive | 2 + include/osgDB/Registry | 7 +++- src/osgDB/Registry.cpp | 56 +++++++++++++++++++++++++++- src/osgPlugins/osga/OSGA_Archive.cpp | 25 ++++++++++++- src/osgPlugins/osga/OSGA_Archive.h | 8 ++++ src/osgPlugins/zip/ZipArchive.cpp | 39 +++++++++++++++++++ src/osgPlugins/zip/ZipArchive.h | 2 + 7 files changed, 134 insertions(+), 5 deletions(-) diff --git a/include/osgDB/Archive b/include/osgDB/Archive index 4f43168dc..b2a1da43e 100644 --- a/include/osgDB/Archive +++ b/include/osgDB/Archive @@ -66,11 +66,13 @@ class OSGDB_EXPORT Archive : public ReaderWriter virtual ReadResult readImage(const std::string& /*fileName*/,const Options* =NULL) const = 0; virtual ReadResult readHeightField(const std::string& /*fileName*/,const Options* =NULL) const = 0; virtual ReadResult readNode(const std::string& /*fileName*/,const Options* =NULL) const = 0; + virtual ReadResult readShader(const std::string& /*fileName*/,const Options* =NULL) const = 0; virtual WriteResult writeObject(const osg::Object& /*obj*/,const std::string& /*fileName*/,const Options* =NULL) const = 0; virtual WriteResult writeImage(const osg::Image& /*image*/,const std::string& /*fileName*/,const Options* =NULL) const = 0; virtual WriteResult writeHeightField(const osg::HeightField& /*heightField*/,const std::string& /*fileName*/,const Options* =NULL) const = 0; virtual WriteResult writeNode(const osg::Node& /*node*/,const std::string& /*fileName*/,const Options* =NULL) const = 0; + virtual WriteResult writeShader(const osg::Shader& /*shader*/,const std::string& /*fileName*/,const Options* =NULL) const = 0; }; diff --git a/include/osgDB/Registry b/include/osgDB/Registry index 4ccdcb3a2..641f1e08f 100644 --- a/include/osgDB/Registry +++ b/include/osgDB/Registry @@ -572,6 +572,8 @@ class OSGDB_EXPORT Registry : public osg::Referenced // forward declare helper class class AvailableReaderWriterIterator; friend class AvailableReaderWriterIterator; + class AvailableArchiveIterator; + friend class AvailableArchiveIterator; osg::ref_ptr _findFileCallback; @@ -584,6 +586,9 @@ class OSGDB_EXPORT Registry : public osg::Referenced ImageProcessorList _ipList; DynamicLibraryList _dlList; + OpenThreads::ReentrantMutex _archiveCacheMutex; + ArchiveCache _archiveCache; + bool _openingLibrary; // map to alias to extensions to plugins. @@ -605,8 +610,6 @@ class OSGDB_EXPORT Registry : public osg::Referenced ObjectCache _objectCache; OpenThreads::Mutex _objectCacheMutex; - ArchiveCache _archiveCache; - OpenThreads::Mutex _archiveCacheMutex; ArchiveExtensionList _archiveExtList; diff --git a/src/osgDB/Registry.cpp b/src/osgDB/Registry.cpp index 9f2a6c1cd..e3fd20600 100644 --- a/src/osgDB/Registry.cpp +++ b/src/osgDB/Registry.cpp @@ -111,6 +111,50 @@ protected: }; +class Registry::AvailableArchiveIterator +{ +public: + AvailableArchiveIterator(Registry::ArchiveCache& archives, OpenThreads::ReentrantMutex& mutex): + _archives(archives), + _mutex(mutex) {} + + + Archive& operator * () { return *get(); } + Archive* operator -> () { return get(); } + + bool valid() { return get()!=0; } + + void operator ++() + { + _archivesUsed.insert(get()); + } + + +protected: + + AvailableArchiveIterator& operator = (const AvailableArchiveIterator&) { return *this; } + + Registry::ArchiveCache& _archives; + OpenThreads::ReentrantMutex& _mutex; + + std::set _archivesUsed; + + Archive* get() + { + OpenThreads::ScopedLock lock(_mutex); + Registry::ArchiveCache::iterator itr=_archives.begin(); + for(;itr!=_archives.end();++itr) + { + if (_archivesUsed.find(itr->second.get())==_archivesUsed.end()) + { + return itr->second.get(); + } + } + return 0; + } + +}; + #if 0 // temporary test of autoregistering, not compiled by default. enum Methods @@ -1047,7 +1091,7 @@ ReaderWriter::ReadResult Registry::read(const ReadFunctor& readFunctor) return archive->readObject(fileName,options.get()); } } - + // record the errors reported by readerwriters. typedef std::vector Results; Results results; @@ -1061,6 +1105,16 @@ ReaderWriter::ReadResult Registry::read(const ReadFunctor& readFunctor) else results.push_back(rr); } + // check loaded archives. + AvailableArchiveIterator aaitr(_archiveCache, _archiveCacheMutex); + for(;aaitr.valid();++aaitr) + { + ReaderWriter::ReadResult rr = readFunctor.doRead(*aaitr); + if (readFunctor.isValid(rr)) return rr; + else results.push_back(rr); + } + + if (!results.empty()) { unsigned int num_FILE_NOT_HANDLED = 0; diff --git a/src/osgPlugins/osga/OSGA_Archive.cpp b/src/osgPlugins/osga/OSGA_Archive.cpp index cf9770dad..0548c79c4 100644 --- a/src/osgPlugins/osga/OSGA_Archive.cpp +++ b/src/osgPlugins/osga/OSGA_Archive.cpp @@ -661,7 +661,13 @@ struct OSGA_Archive::ReadHeightFieldFunctor : public OSGA_Archive::ReadFunctor struct OSGA_Archive::ReadNodeFunctor : public OSGA_Archive::ReadFunctor { ReadNodeFunctor(const std::string& filename, const ReaderWriter::Options* options):ReadFunctor(filename,options) {} - virtual ReaderWriter::ReadResult doRead(ReaderWriter& rw, std::istream& input) const { return rw.readNode(input, _options); } + virtual ReaderWriter::ReadResult doRead(ReaderWriter& rw, std::istream& input) const { return rw.readNode(input, _options); } +}; + +struct OSGA_Archive::ReadShaderFunctor : public OSGA_Archive::ReadFunctor +{ + ReadShaderFunctor(const std::string& filename, const ReaderWriter::Options* options):ReadFunctor(filename,options) {} + virtual ReaderWriter::ReadResult doRead(ReaderWriter& rw, std::istream& input) const { return rw.readShader(input, _options); } }; ReaderWriter::ReadResult OSGA_Archive::read(const ReadFunctor& readFunctor) @@ -724,6 +730,11 @@ ReaderWriter::ReadResult OSGA_Archive::readNode(const std::string& fileName,cons return const_cast(this)->read(ReadNodeFunctor(fileName, options)); } +ReaderWriter::ReadResult OSGA_Archive::readShader(const std::string& fileName,const Options* options) const +{ + return const_cast(this)->read(ReadShaderFunctor(fileName, options)); +} + struct OSGA_Archive::WriteObjectFunctor : public OSGA_Archive::WriteFunctor { @@ -762,7 +773,17 @@ struct OSGA_Archive::WriteNodeFunctor : public OSGA_Archive::WriteFunctor _object(object) {} const osg::Node& _object; - virtual ReaderWriter::WriteResult doWrite(ReaderWriter& rw, std::ostream& output) const { return rw.writeNode(_object, output, _options); } + virtual ReaderWriter::WriteResult doWrite(ReaderWriter& rw, std::ostream& output) const { return rw.writeNode(_object, output, _options); } +}; + +struct OSGA_Archive::WriteShaderFunctor : public OSGA_Archive::WriteFunctor +{ + WriteShaderFunctor(const osg::Shader& object, const std::string& filename, const ReaderWriter::Options* options): + WriteFunctor(filename,options), + _object(object) {} + const osg::Shader& _object; + + virtual ReaderWriter::WriteResult doWrite(ReaderWriter& rw, std::ostream& output) const { return rw.writeShader(_object, output, _options); } }; ReaderWriter::WriteResult OSGA_Archive::write(const WriteFunctor& writeFunctor) diff --git a/src/osgPlugins/osga/OSGA_Archive.h b/src/osgPlugins/osga/OSGA_Archive.h index 6dd13dab3..1712242b4 100644 --- a/src/osgPlugins/osga/OSGA_Archive.h +++ b/src/osgPlugins/osga/OSGA_Archive.h @@ -72,6 +72,9 @@ class OSGA_Archive : public osgDB::Archive /** Read an osg::Node of specified file name from the Archive.*/ virtual ReadResult readNode(const std::string& fileName,const Options* options=NULL) const; + /** Read an osg::Shader of specified file name from the Archive.*/ + virtual ReadResult readShader(const std::string& fileName,const Options* options=NULL) const; + /** Write an osg::Object with specified file name to the Archive.*/ virtual WriteResult writeObject(const osg::Object& obj,const std::string& fileName,const Options* options=NULL) const; @@ -83,6 +86,9 @@ class OSGA_Archive : public osgDB::Archive /** Write an osg::Node with specified file name to the Archive.*/ virtual WriteResult writeNode(const osg::Node& node,const std::string& fileName,const Options* options=NULL) const; + + /** Write an osg::Shader with specified file name to the Archive.*/ + virtual WriteResult writeShader(const osg::Shader& shader,const std::string& fileName,const Options* options=NULL) const; #if defined(_MSC_VER) typedef __int64 pos_type; @@ -186,12 +192,14 @@ class OSGA_Archive : public osgDB::Archive struct ReadImageFunctor; struct ReadHeightFieldFunctor; struct ReadNodeFunctor; + struct ReadShaderFunctor; struct WriteObjectFunctor; struct WriteImageFunctor; struct WriteHeightFieldFunctor; struct WriteNodeFunctor; + struct WriteShaderFunctor; osgDB::ReaderWriter::ReadResult read(const ReadFunctor& readFunctor); diff --git a/src/osgPlugins/zip/ZipArchive.cpp b/src/osgPlugins/zip/ZipArchive.cpp index 4de8d6899..50e4cffd5 100644 --- a/src/osgPlugins/zip/ZipArchive.cpp +++ b/src/osgPlugins/zip/ZipArchive.cpp @@ -298,6 +298,40 @@ osgDB::ReaderWriter::ReadResult ZipArchive::readNode(const std::string& file,con return rresult; } + +osgDB::ReaderWriter::ReadResult ZipArchive::readShader(const std::string& file,const osgDB::ReaderWriter::Options* options) const +{ + osgDB::ReaderWriter::ReadResult rresult = osgDB::ReaderWriter::ReadResult::FILE_NOT_HANDLED; + + std::string ext = osgDB::getLowerCaseFileExtension(file); + if (!mZipLoaded || !acceptsExtension(ext)) return osgDB::ReaderWriter::ReadResult::FILE_NOT_HANDLED; + + const ZIPENTRY* ze = GetZipEntry(file); + if(ze != NULL) + { + std::stringstream buffer; + + osgDB::ReaderWriter* rw = ReadFromZipEntry(ze, options, buffer); + if (rw != NULL) + { + // Setup appropriate options + osg::ref_ptr local_opt = options ? + options->cloneOptions() : + new osgDB::ReaderWriter::Options; + + local_opt->setPluginStringData("STREAM_FILENAME", osgDB::getSimpleFileName(ze->name)); + + osgDB::ReaderWriter::ReadResult readResult = rw->readShader(buffer,local_opt.get()); + if (readResult.success()) + { + return readResult; + } + } + } + + return rresult; +} + osgDB::ReaderWriter::WriteResult ZipArchive::writeObject(const osg::Object& /*obj*/,const std::string& /*fileName*/,const osgDB::ReaderWriter::Options*) const { return osgDB::ReaderWriter::WriteResult(osgDB::ReaderWriter::WriteResult::FILE_NOT_HANDLED); @@ -318,6 +352,11 @@ osgDB::ReaderWriter::WriteResult ZipArchive::writeNode(const osg::Node& /*node*/ return osgDB::ReaderWriter::WriteResult(osgDB::ReaderWriter::WriteResult::FILE_NOT_HANDLED); } +osgDB::ReaderWriter::WriteResult ZipArchive::writeShader(const osg::Shader& /*shader*/,const std::string& /*fileName*/,const osgDB::ReaderWriter::Options*) const +{ + return osgDB::ReaderWriter::WriteResult(osgDB::ReaderWriter::WriteResult::FILE_NOT_HANDLED); +} + osgDB::ReaderWriter* ZipArchive::ReadFromZipEntry(const ZIPENTRY* ze, const osgDB::ReaderWriter::Options* options, std::stringstream& buffer) const { diff --git a/src/osgPlugins/zip/ZipArchive.h b/src/osgPlugins/zip/ZipArchive.h index 7a45ec63b..6d96d5e55 100644 --- a/src/osgPlugins/zip/ZipArchive.h +++ b/src/osgPlugins/zip/ZipArchive.h @@ -53,11 +53,13 @@ class ZipArchive : public osgDB::Archive virtual osgDB::ReaderWriter::ReadResult readImage(const std::string& /*fileName*/,const osgDB::ReaderWriter::Options* =NULL) const; virtual osgDB::ReaderWriter::ReadResult readHeightField(const std::string& /*fileName*/,const osgDB::ReaderWriter::Options* =NULL) const; virtual osgDB::ReaderWriter::ReadResult readNode(const std::string& /*fileName*/, const osgDB::ReaderWriter::Options* =NULL) const; + virtual osgDB::ReaderWriter::ReadResult readShader(const std::string& /*fileName*/, const osgDB::ReaderWriter::Options* =NULL) const; virtual osgDB::ReaderWriter::WriteResult writeObject(const osg::Object& /*obj*/, const std::string& /*fileName*/,const osgDB::ReaderWriter::Options* =NULL) const; virtual osgDB::ReaderWriter::WriteResult writeImage(const osg::Image& /*image*/, const std::string& /*fileName*/,const osgDB::ReaderWriter::Options* =NULL) const; virtual osgDB::ReaderWriter::WriteResult writeHeightField(const osg::HeightField& /*heightField*/, const std::string& /*fileName*/,const osgDB::ReaderWriter::Options* =NULL) const; virtual osgDB::ReaderWriter::WriteResult writeNode(const osg::Node& /*node*/, const std::string& /*fileName*/,const osgDB::ReaderWriter::Options* =NULL) const; + virtual osgDB::ReaderWriter::WriteResult writeShader(const osg::Shader& /*shader*/, const std::string& /*fileName*/,const osgDB::ReaderWriter::Options* =NULL) const; protected: