diff --git a/examples/osgpresentation/osgpresentation.cpp b/examples/osgpresentation/osgpresentation.cpp index c68831ad7..4a4228e1d 100644 --- a/examples/osgpresentation/osgpresentation.cpp +++ b/examples/osgpresentation/osgpresentation.cpp @@ -41,10 +41,12 @@ int main(int argc, char** argv) typedef std::list< osg::ref_ptr > Scripts; Scripts scripts; + osg::ref_ptr model = new osg::Group; + std::string filename; while(arguments.read("--script",filename)) { - osg::ref_ptr script = osgDB::readFile(filename); + osg::ref_ptr script = osgDB::readScriptFile(filename); if (script.valid()) scripts.push_back(script.get()); } @@ -67,7 +69,7 @@ int main(int argc, char** argv) { while (arguments.read("--lua", str)) { - osg::ref_ptr script = osgDB::readFile(str); + osg::ref_ptr script = osgDB::readScriptFile(str); if (script.valid()) { luaScriptEngine->run(script.get()); @@ -80,7 +82,7 @@ int main(int argc, char** argv) { while (arguments.read("--js",str)) { - osg::ref_ptr script = osgDB::readFile(str); + osg::ref_ptr script = osgDB::readScriptFile(str); if (script.valid()) { v8ScriptEngine->run(script.get()); @@ -94,15 +96,18 @@ int main(int argc, char** argv) { while (arguments.read("--python",str)) { - osg::ref_ptr script = osgDB::readFile(str); + osg::ref_ptr script = osgDB::readScriptFile(str); if (script.valid()) { pythonScriptEngine->run(script.get()); } } } + + return 0; #endif +#if 1 osg::ref_ptr presentation = new osgPresentation::Presentation; osg::ref_ptr slide = new osgPresentation::Slide; @@ -438,7 +443,7 @@ int main(int argc, char** argv) std::string str; while (arguments.read("--lua", str)) { - osg::ref_ptr script = osgDB::readFile(str); + osg::ref_ptr script = osgDB::readScriptFile(str); if (script.valid()) { presentation->addUpdateCallback(new osg::ScriptNodeCallback(script.get(),"update")); @@ -448,7 +453,7 @@ int main(int argc, char** argv) if (arguments.read("--test", str)) { - osg::ref_ptr script = osgDB::readFile(str); + osg::ref_ptr script = osgDB::readScriptFile(str); if (script.valid()) { osg::Parameters inputParameters; @@ -498,5 +503,5 @@ int main(int argc, char** argv) return viewer.run(); - +#endif } diff --git a/include/osgDB/Callbacks b/include/osgDB/Callbacks index 7e0e6f27d..6b0f0b84e 100644 --- a/include/osgDB/Callbacks +++ b/include/osgDB/Callbacks @@ -65,6 +65,8 @@ class OSGDB_EXPORT ReadFileCallback : public virtual osg::Referenced virtual ReaderWriter::ReadResult readShader(const std::string& filename, const Options* options); + virtual ReaderWriter::ReadResult readScript(const std::string& filename, const Options* options); + protected: virtual ~ReadFileCallback() {} }; @@ -83,6 +85,8 @@ class OSGDB_EXPORT WriteFileCallback : public virtual osg::Referenced virtual ReaderWriter::WriteResult writeShader(const osg::Shader& obj, const std::string& fileName,const Options* options); + virtual ReaderWriter::WriteResult writeScript(const osg::Script& obj, const std::string& fileName,const Options* options); + protected: virtual ~WriteFileCallback() {} }; diff --git a/include/osgDB/ReadFile b/include/osgDB/ReadFile index f3ff3ca7e..d3f71da4d 100644 --- a/include/osgDB/ReadFile +++ b/include/osgDB/ReadFile @@ -194,6 +194,29 @@ inline osg::Shader* readShaderFile(osg::Shader::Type type, const std::string& fi return readShaderFile(type, filename,Registry::instance()->getOptions()); } + +/** Read an osg::Script from file. + * Return valid osg::Script on success, + * return NULL on failure. + * Use the Options object to control cache operations and file search paths in osgDB::Registry. + * 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::Script* readScriptFile(const std::string& filename,const Options* options); + +/** Read an osg::Script from file. + * Return valid osg::Script on success, + * return NULL on failure. + * 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.*/ +inline osg::Script* readScriptFile(const std::string& filename) +{ + return readScriptFile(filename,Registry::instance()->getOptions()); +} + + + /** Read an osg::Object from file. * Return an assigned osg::ref_ptr on success, * return an osg::ref_ptr with a NULL pointer assigned to it on failure. @@ -221,7 +244,7 @@ inline osg::ref_ptr readRefObjectFile(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::ref_ptr readRefImageFile(const std::string& filename,const Options* options); +extern OSGDB_EXPORT osg::ref_ptr readRefImageFile(const std::string& filename,const Options* options); /** Read an osg::Image from file. * Return an assigned osg::ref_ptr on success, @@ -229,7 +252,7 @@ extern OSGDB_EXPORT osg::ref_ptr readRefImageFile(const std::string * 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.*/ -inline osg::ref_ptr readRefImageFile(const std::string& filename) +inline osg::ref_ptr readRefImageFile(const std::string& filename) { return readRefImageFile(filename,Registry::instance()->getOptions()); } @@ -241,7 +264,7 @@ inline osg::ref_ptr readRefImageFile(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::ref_ptr readRefHeightFieldFile(const std::string& filename,const Options* options); +extern OSGDB_EXPORT osg::ref_ptr readRefHeightFieldFile(const std::string& filename,const Options* options); /** Read an osg::HeightField from file. * Return an assigned osg::ref_ptr on success, @@ -249,7 +272,7 @@ extern OSGDB_EXPORT osg::ref_ptr readRefHeightFieldFile(const * 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.*/ -inline osg::ref_ptr readRefHeightFieldFile(const std::string& filename) +inline osg::ref_ptr readRefHeightFieldFile(const std::string& filename) { return readRefHeightFieldFile(filename,Registry::instance()->getOptions()); } @@ -261,7 +284,7 @@ inline osg::ref_ptr readRefHeightFieldFile(const std::string& * 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::ref_ptr readRefNodeFile(const std::string& filename,const Options* options); +extern OSGDB_EXPORT osg::ref_ptr readRefNodeFile(const std::string& filename,const Options* options); /** Read an osg::Node from file. * Return an assigned osg::ref_ptr on success, @@ -269,7 +292,7 @@ extern OSGDB_EXPORT osg::ref_ptr readRefNodeFile(const std::string& * 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.*/ -inline osg::ref_ptr readRefNodeFile(const std::string& filename) +inline osg::ref_ptr readRefNodeFile(const std::string& filename) { return readRefNodeFile(filename,Registry::instance()->getOptions()); } @@ -289,7 +312,7 @@ extern OSGDB_EXPORT osg::ref_ptr readRefShaderFile(const std::strin * 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.*/ -inline osg::ref_ptr readRefShaderFile(const std::string& filename) +inline osg::ref_ptr readRefShaderFile(const std::string& filename) { return readRefShaderFile(filename, Registry::instance()->getOptions()); } @@ -320,6 +343,26 @@ inline osg::ref_ptr readRefShaderFile(osg::Shader::Type type, const } +/** Read an osg::Script from file. + * Return an assigned osg::ref_ptr on success, + * return an osg::ref_ptr with a NULL pointer assigned to it on failure. + * Use the Options object to control cache operations and file search paths in osgDB::Registry. + * 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::ref_ptr readRefScriptFile(const std::string& filename,const Options* options); + +/** Read an osg::Script from file. + * Return an assigned osg::ref_ptr on success, + * return an osg::ref_ptr with a NULL pointer assigned to it on failure. + * 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.*/ +inline osg::ref_ptr readRefScriptFile(const std::string& filename) +{ + return readRefScriptFile(filename,Registry::instance()->getOptions()); +} + } #endif diff --git a/include/osgDB/ReaderWriter b/include/osgDB/ReaderWriter index 46c98bedf..7408d7afd 100644 --- a/include/osgDB/ReaderWriter +++ b/include/osgDB/ReaderWriter @@ -17,6 +17,7 @@ #include #include #include +#include #include @@ -64,7 +65,7 @@ class OSGDB_EXPORT ReaderWriter : public osg::Object /** Return true if ReaderWriter accepts specified file extension.*/ virtual bool acceptsExtension(const std::string& /*extension*/) const; - + virtual bool acceptsProtocol(const std::string& protocol) const; /// Bit mask for setting up which feature types are available for read and/or write @@ -81,16 +82,20 @@ class OSGDB_EXPORT ReaderWriter : public osg::Object FEATURE_WRITE_HEIGHT_FIELD = 1<<7, FEATURE_WRITE_NODE = 1<<8, FEATURE_WRITE_SHADER = 1<<9, + FEATURE_READ_SCRIPT = 1<<10, + FEATURE_WRITE_SCRIPT = 1<<11, FEATURE_ALL = FEATURE_READ_OBJECT | FEATURE_READ_IMAGE | FEATURE_READ_HEIGHT_FIELD | FEATURE_READ_NODE | FEATURE_READ_SHADER | + FEATURE_READ_SCRIPT | FEATURE_WRITE_OBJECT | FEATURE_WRITE_IMAGE | FEATURE_WRITE_HEIGHT_FIELD | FEATURE_WRITE_NODE | - FEATURE_WRITE_SHADER + FEATURE_WRITE_SHADER | + FEATURE_WRITE_SCRIPT }; /** Return available features*/ virtual Features supportedFeatures() const; @@ -124,13 +129,14 @@ class OSGDB_EXPORT ReaderWriter : public osg::Object ReadResult& operator = (const ReadResult& rr) { if (this==&rr) return *this; _status=rr._status; _message=rr._message;_object=rr._object; return *this; } bool operator < (const ReadResult& rhs) const { return _status < rhs._status; } - + osg::Object* getObject(); osg::Image* getImage(); osg::HeightField* getHeightField(); osg::Node* getNode(); osgDB::Archive* getArchive(); osg::Shader* getShader(); + osg::Script* getScript(); bool validObject() { return _object.valid(); } bool validImage() { return getImage()!=0; } @@ -138,6 +144,7 @@ class OSGDB_EXPORT ReaderWriter : public osg::Object bool validNode() { return getNode()!=0; } bool validArchive() { return getArchive()!=0; } bool validShader() { return getShader()!=0; } + bool validScript() { return getScript()!=0; } osg::Object* takeObject(); osg::Image* takeImage(); @@ -145,6 +152,7 @@ class OSGDB_EXPORT ReaderWriter : public osg::Object osg::Node* takeNode(); osgDB::Archive* takeArchive(); osg::Shader* takeShader(); + osg::Script* takeScript(); std::string& message() { return _message; } const std::string& message() const { return _message; } @@ -223,24 +231,28 @@ class OSGDB_EXPORT ReaderWriter : public osg::Object virtual ReadResult readHeightField(const std::string& /*fileName*/,const Options* =NULL) const { return ReadResult(ReadResult::NOT_IMPLEMENTED); } virtual ReadResult readNode(const std::string& /*fileName*/,const Options* =NULL) const { return ReadResult(ReadResult::NOT_IMPLEMENTED); } virtual ReadResult readShader(const std::string& /*fileName*/,const Options* =NULL) const { return ReadResult(ReadResult::NOT_IMPLEMENTED); } + virtual ReadResult readScript(const std::string& /*fileName*/,const Options* =NULL) const { return ReadResult(ReadResult::NOT_IMPLEMENTED); } virtual WriteResult writeObject(const osg::Object& /*obj*/,const std::string& /*fileName*/,const Options* =NULL) const {return WriteResult(WriteResult::NOT_IMPLEMENTED); } virtual WriteResult writeImage(const osg::Image& /*image*/,const std::string& /*fileName*/,const Options* =NULL) const {return WriteResult(WriteResult::NOT_IMPLEMENTED); } virtual WriteResult writeHeightField(const osg::HeightField& /*heightField*/,const std::string& /*fileName*/,const Options* =NULL) const {return WriteResult(WriteResult::NOT_IMPLEMENTED); } virtual WriteResult writeNode(const osg::Node& /*node*/,const std::string& /*fileName*/,const Options* =NULL) const { return WriteResult(WriteResult::NOT_IMPLEMENTED); } virtual WriteResult writeShader(const osg::Shader& /*shader*/,const std::string& /*fileName*/,const Options* =NULL) const {return WriteResult(WriteResult::NOT_IMPLEMENTED); } + virtual WriteResult writeScript(const osg::Script& /*script*/,const std::string& /*fileName*/,const Options* =NULL) const {return WriteResult(WriteResult::NOT_IMPLEMENTED); } virtual ReadResult readObject(std::istream& /*fin*/,const Options* =NULL) const { return ReadResult(ReadResult::NOT_IMPLEMENTED); } virtual ReadResult readImage(std::istream& /*fin*/,const Options* =NULL) const { return ReadResult(ReadResult::NOT_IMPLEMENTED); } virtual ReadResult readHeightField(std::istream& /*fin*/,const Options* =NULL) const { return ReadResult(ReadResult::NOT_IMPLEMENTED); } virtual ReadResult readNode(std::istream& /*fin*/,const Options* =NULL) const { return ReadResult(ReadResult::NOT_IMPLEMENTED); } virtual ReadResult readShader(std::istream& /*fin*/,const Options* =NULL) const { return ReadResult(ReadResult::NOT_IMPLEMENTED); } + virtual ReadResult readScript(std::istream& /*fin*/,const Options* =NULL) const { return ReadResult(ReadResult::NOT_IMPLEMENTED); } virtual WriteResult writeObject(const osg::Object& /*obj*/,std::ostream& /*fout*/,const Options* =NULL) const { return WriteResult(WriteResult::NOT_IMPLEMENTED); } virtual WriteResult writeImage(const osg::Image& /*image*/,std::ostream& /*fout*/,const Options* =NULL) const { return WriteResult(WriteResult::NOT_IMPLEMENTED); } virtual WriteResult writeHeightField(const osg::HeightField& /*heightField*/,std::ostream& /*fout*/,const Options* =NULL) const { return WriteResult(WriteResult::NOT_IMPLEMENTED); } virtual WriteResult writeNode(const osg::Node& /*node*/,std::ostream& /*fout*/,const Options* =NULL) const { return WriteResult(WriteResult::NOT_IMPLEMENTED); } virtual WriteResult writeShader(const osg::Shader& /*shader*/,std::ostream& /*fout*/,const Options* =NULL) const { return WriteResult(WriteResult::NOT_IMPLEMENTED); } + virtual WriteResult writeScript(const osg::Script& /*script*/,std::ostream& /*fout*/,const Options* =NULL) const { return WriteResult(WriteResult::NOT_IMPLEMENTED); } /** Specify fmt string as a supported protocol. * Please note, this method should usually only be used internally by subclasses of ReaderWriter, Only in special cases diff --git a/include/osgDB/Registry b/include/osgDB/Registry index cc9aa6286..dbc95cf5f 100644 --- a/include/osgDB/Registry +++ b/include/osgDB/Registry @@ -128,10 +128,10 @@ class OSGDB_EXPORT Registry : public osg::Referenced /** get const list of all registered ReaderWriters.*/ const ReaderWriterList& getReaderWriterList() const { return _rwList; } - + /** get a list of registered ReaderWriters which can handle given protocol */ void getReaderWriterListForProtocol(const std::string& protocol, ReaderWriterList& results) const; - + ReaderWriter* getReaderWriterForProtocolAndExtension(const std::string& protocol, const std::string& extension); @@ -251,6 +251,14 @@ class OSGDB_EXPORT Registry : public osg::Referenced } ReaderWriter::ReadResult readShaderImplementation(const std::string& fileName,const Options* options); + ReaderWriter::ReadResult readScript(const std::string& fileName,const Options* options) + { + if (options && options->getReadFileCallback()) return options->getReadFileCallback()->readScript(fileName,options); + else if (_readFileCallback.valid()) return _readFileCallback->readScript(fileName,options); + else return readScriptImplementation(fileName,options); + } + ReaderWriter::ReadResult readScriptImplementation(const std::string& fileName,const Options* options); + /** Set the Registry callback to use in place of the default writeFile calls.*/ void setWriteFileCallback( WriteFileCallback* cb) { _writeFileCallback = cb; } @@ -302,6 +310,13 @@ class OSGDB_EXPORT Registry : public osg::Referenced } ReaderWriter::WriteResult writeShaderImplementation(const osg::Shader& obj, const std::string& fileName,const Options* options); + ReaderWriter::WriteResult writeScript(const osg::Script& obj, const std::string& fileName,const Options* options) + { + if (options && options->getWriteFileCallback()) return options->getWriteFileCallback()->writeScript(obj,fileName,options); + else if (_writeFileCallback.valid()) return _writeFileCallback->writeScript(obj,fileName,options); + else return writeScriptImplementation(obj,fileName,options); + } + ReaderWriter::WriteResult writeScriptImplementation(const osg::Script& obj, const std::string& fileName,const Options* options); inline void _buildKdTreeIfRequired(ReaderWriter::ReadResult& result, const Options* options) { @@ -551,6 +566,7 @@ class OSGDB_EXPORT Registry : public osg::Referenced struct ReadNodeFunctor; struct ReadArchiveFunctor; struct ReadShaderFunctor; + struct ReadScriptFunctor; // make helper classes friends to get round VS6.0 "issues" friend struct ReadFunctor; @@ -560,6 +576,7 @@ class OSGDB_EXPORT Registry : public osg::Referenced friend struct ReadNodeFunctor; friend struct ReadArchiveFunctor; friend struct ReadShaderFunctor; + friend struct ReadScriptFunctor; ReaderWriter::ReadResult read(const ReadFunctor& readFunctor); ReaderWriter::ReadResult readImplementation(const ReadFunctor& readFunctor,Options::CacheHintOptions cacheHint); diff --git a/include/osgDB/WriteFile b/include/osgDB/WriteFile index d6ad7b81d..b44b93fcb 100644 --- a/include/osgDB/WriteFile +++ b/include/osgDB/WriteFile @@ -125,6 +125,26 @@ inline bool writeShaderFile(const osg::Shader& shader, const std::string& filena return writeShaderFile( shader, filename, Registry::instance()->getOptions() ); } +/** Write an osg::Script to file. + * Return true on success, + * return false on failure. + * Use the Options object to control cache operations and file search paths in osgDB::Registry. + * The osgDB::Registry is used to load the appropriate ReaderWriter plugin + * for the filename extension, and this plugin then handles the request + * to write the specified file.*/ +extern OSGDB_EXPORT bool writeScriptFile(const osg::Script& image, const std::string& filename, const Options* options ); + +/** Write an osg::Script to file. + * Return true on success, + * return false on failure. + * The osgDB::Registry is used to load the appropriate ReaderWriter plugin + * for the filename extension, and this plugin then handles the request + * to write the specified file.*/ +inline bool writeScriptFile(const osg::Script& image, const std::string& filename) +{ + return writeScriptFile( image, filename, Registry::instance()->getOptions() ); +} + } #endif diff --git a/src/osgDB/Callbacks.cpp b/src/osgDB/Callbacks.cpp index 3e2d89b45..427c40a09 100644 --- a/src/osgDB/Callbacks.cpp +++ b/src/osgDB/Callbacks.cpp @@ -64,6 +64,11 @@ ReaderWriter::ReadResult ReadFileCallback::readShader(const std::string& filenam return osgDB::Registry::instance()->readShaderImplementation(filename,options); } +ReaderWriter::ReadResult ReadFileCallback::readScript(const std::string& filename, const Options* options) +{ + return osgDB::Registry::instance()->readScriptImplementation(filename,options); +} + /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // // WriteFileCallback default implementation @@ -92,3 +97,8 @@ ReaderWriter::WriteResult WriteFileCallback::writeShader(const osg::Shader& obj, { return osgDB::Registry::instance()->writeShaderImplementation(obj,fileName,options); } + +ReaderWriter::WriteResult WriteFileCallback::writeScript(const osg::Script& obj, const std::string& fileName,const Options* options) +{ + return osgDB::Registry::instance()->writeScriptImplementation(obj,fileName,options); +} diff --git a/src/osgDB/ReadFile.cpp b/src/osgDB/ReadFile.cpp index 58c368b71..deb16ad7f 100644 --- a/src/osgDB/ReadFile.cpp +++ b/src/osgDB/ReadFile.cpp @@ -250,6 +250,16 @@ Node* osgDB::readNodeFiles(osg::ArgumentParser& arguments,const Options* options } + +Script* osgDB::readScriptFile(const std::string& filename,const Options* options) +{ + ReaderWriter::ReadResult rr = Registry::instance()->readScript(filename,options); + if (rr.validScript()) return rr.takeScript(); + if (rr.error()) OSG_WARN << rr.message() << std::endl; + return NULL; +} + + osg::ref_ptr osgDB::readRefObjectFile(const std::string& filename,const Options* options) { ReaderWriter::ReadResult rr = Registry::instance()->readObject(filename,options); @@ -289,3 +299,11 @@ osg::ref_ptr osgDB::readRefNodeFile(const std::string& filename,const if (rr.error()) OSG_WARN << rr.message() << std::endl; return NULL; } + +osg::ref_ptr osgDB::readRefScriptFile(const std::string& filename,const Options* options) +{ + ReaderWriter::ReadResult rr = Registry::instance()->readScript(filename,options); + if (rr.validScript()) return osg::ref_ptr(rr.getScript()); + if (rr.error()) OSG_WARN << rr.message() << std::endl; + return NULL; +} diff --git a/src/osgDB/ReaderWriter.cpp b/src/osgDB/ReaderWriter.cpp index e219ab9e9..2c4d5ce57 100644 --- a/src/osgDB/ReaderWriter.cpp +++ b/src/osgDB/ReaderWriter.cpp @@ -25,6 +25,7 @@ osg::HeightField* ReaderWriter::ReadResult::getHeightField() { return dynamic_ca osg::Node* ReaderWriter::ReadResult::getNode() { return dynamic_cast(_object.get()); } osgDB::Archive* ReaderWriter::ReadResult::getArchive() { return dynamic_cast(_object.get()); } osg::Shader* ReaderWriter::ReadResult::getShader() { return dynamic_cast(_object.get()); } +osg::Script* ReaderWriter::ReadResult::getScript() { return dynamic_cast(_object.get()); } osg::Object* ReaderWriter::ReadResult::takeObject() { osg::Object* obj = _object.get(); if (obj) { obj->ref(); _object=NULL; obj->unref_nodelete(); } return obj; } osg::Image* ReaderWriter::ReadResult::takeImage() { osg::Image* image=dynamic_cast(_object.get()); if (image) { image->ref(); _object=NULL; image->unref_nodelete(); } return image; } @@ -32,6 +33,7 @@ osg::HeightField* ReaderWriter::ReadResult::takeHeightField() { osg::HeightField osg::Node* ReaderWriter::ReadResult::takeNode() { osg::Node* node=dynamic_cast(_object.get()); if (node) { node->ref(); _object=NULL; node->unref_nodelete(); } return node; } osgDB::Archive* ReaderWriter::ReadResult::takeArchive() { osgDB::Archive* archive=dynamic_cast(_object.get()); if (archive) { archive->ref(); _object=NULL; archive->unref_nodelete(); } return archive; } osg::Shader* ReaderWriter::ReadResult::takeShader() { osg::Shader* shader=dynamic_cast(_object.get()); if (shader) { shader->ref(); _object=NULL; shader->unref_nodelete(); } return shader; } +osg::Script* ReaderWriter::ReadResult::takeScript() { osg::Script* script=dynamic_cast(_object.get()); if (script) { script->ref(); _object=NULL; script->unref_nodelete(); } return script; } ReaderWriter::~ReaderWriter() { diff --git a/src/osgDB/Registry.cpp b/src/osgDB/Registry.cpp index c64f612b4..e759ff4b2 100644 --- a/src/osgDB/Registry.cpp +++ b/src/osgDB/Registry.cpp @@ -970,6 +970,18 @@ struct Registry::ReadShaderFunctor : public Registry::ReadFunctor virtual ReadFunctor* cloneType(const std::string& filename, const Options* options) const { return new ReadShaderFunctor(filename, options); } }; +struct Registry::ReadScriptFunctor : public Registry::ReadFunctor +{ + ReadScriptFunctor(const std::string& filename, const Options* options):ReadFunctor(filename,options) {} + + virtual ReaderWriter::ReadResult doRead(ReaderWriter& rw)const { return rw.readScript(_filename, _options); } + virtual bool isValid(ReaderWriter::ReadResult& readResult) const { return readResult.validScript(); } + virtual bool isValid(osg::Object* object) const { return dynamic_cast(object)!=0; } + + virtual ReadFunctor* cloneType(const std::string& filename, const Options* options) const { return new ReadScriptFunctor(filename, options); } +}; + + void Registry::addArchiveExtension(const std::string ext) { for(ArchiveExtensionList::iterator aitr=_archiveExtList.begin(); @@ -1590,6 +1602,60 @@ ReaderWriter::WriteResult Registry::writeShaderImplementation(const Shader& shad return result; } +ReaderWriter::ReadResult Registry::readScriptImplementation(const std::string& fileName,const Options* options) +{ + return readImplementation(ReadScriptFunctor(fileName, options),Options::CACHE_IMAGES); +} + +ReaderWriter::WriteResult Registry::writeScriptImplementation(const Script& image,const std::string& fileName,const Options* options) +{ + // record the errors reported by readerwriters. + typedef std::vector Results; + Results results; + + // first attempt to load the file from existing ReaderWriter's + AvailableReaderWriterIterator itr(_rwList, _pluginMutex); + for(;itr.valid();++itr) + { + ReaderWriter::WriteResult rr = itr->writeScript(image,fileName,options); + if (rr.success()) return rr; + else results.push_back(rr); + } + + // now look for a plug-in to save the file. + std::string libraryName = createLibraryNameForFile(fileName); + if (loadLibrary(libraryName)==LOADED) + { + for(;itr.valid();++itr) + { + ReaderWriter::WriteResult rr = itr->writeScript(image,fileName,options); + if (rr.success()) return rr; + else results.push_back(rr); + } + } + + if (results.empty()) + { + return ReaderWriter::WriteResult("Warning: Could not find plugin to write image to file \""+fileName+"\"."); + } + + // sort the results so the most relevant (i.e. ERROR_IN_WRITING_FILE is more relevant than FILE_NOT_FOUND) results get placed at the end of the results list. + std::sort(results.begin(), results.end()); + ReaderWriter::WriteResult result = results.back(); + + if (result.message().empty()) + { + switch(result.status()) + { + case(ReaderWriter::WriteResult::FILE_NOT_HANDLED): result.message() = "Warning: Write to \""+fileName+"\" not supported."; break; + case(ReaderWriter::WriteResult::ERROR_IN_WRITING_FILE): result.message() = "Warning: Error in writing to \""+fileName+"\"."; break; + default: break; + } + } + + return result; +} + void Registry::addEntryToObjectCache(const std::string& filename, osg::Object* object, double timestamp) { OpenThreads::ScopedLock lock(_objectCacheMutex); diff --git a/src/osgDB/WriteFile.cpp b/src/osgDB/WriteFile.cpp index 0f3d38bd5..0db2c0311 100644 --- a/src/osgDB/WriteFile.cpp +++ b/src/osgDB/WriteFile.cpp @@ -61,3 +61,10 @@ bool osgDB::writeShaderFile(const Shader& shader,const std::string& filename, co return wr.success(); } +bool osgDB::writeScriptFile(const Script& image,const std::string& filename, const Options* options ) +{ + ReaderWriter::WriteResult wr = Registry::instance()->writeScript( image, filename, options ); + if (wr.error()) OSG_WARN << "Error writing file " << filename << ": " << wr.message() << std::endl; + return wr.success(); +} + diff --git a/src/osgPlugins/V8/ReaderWriterV8.cpp b/src/osgPlugins/V8/ReaderWriterV8.cpp index 0c3fca8a0..578442fdd 100644 --- a/src/osgPlugins/V8/ReaderWriterV8.cpp +++ b/src/osgPlugins/V8/ReaderWriterV8.cpp @@ -29,7 +29,20 @@ class ReaderWriterV8 : public osgDB::ReaderWriter virtual const char* className() const { return "V8 JavaScript ScriptEngine plugin"; } - virtual ReadResult readObject(std::istream& fin,const osgDB::ReaderWriter::Options* options =NULL) const + virtual ReadResult readObject(std::istream& fin, const osgDB::ReaderWriter::Options* options =NULL) const + { + return readScript(fin, options); + } + + virtual ReadResult readObject(const std::string& file, const osgDB::ReaderWriter::Options* options =NULL) const + { + if (file=="ScriptEngine.V8") return new v8::V8ScriptEngine(); + if (file=="ScriptEngine.js") return new v8::V8ScriptEngine(); + + return readScript(file); + } + + virtual ReadResult readScript(std::istream& fin,const osgDB::ReaderWriter::Options* options =NULL) const { osg::ref_ptr script = new osg::Script; script->setLanguage("js"); @@ -48,11 +61,8 @@ class ReaderWriterV8 : public osgDB::ReaderWriter return script.release(); } - virtual ReadResult readObject(const std::string& file, const osgDB::ReaderWriter::Options* options =NULL) const + virtual ReadResult readScript(const std::string& file, const osgDB::ReaderWriter::Options* options =NULL) const { - if (file=="ScriptEngine.V8") return new v8::V8ScriptEngine(); - if (file=="ScriptEngine.js") return new v8::V8ScriptEngine(); - std::string ext = osgDB::getLowerCaseFileExtension(file); if (!acceptsExtension(ext)) return ReadResult::FILE_NOT_HANDLED; @@ -62,9 +72,8 @@ class ReaderWriterV8 : public osgDB::ReaderWriter osgDB::ifstream istream(fileName.c_str(), std::ios::in); if(!istream) return ReadResult::FILE_NOT_HANDLED; - return readObject(istream, options); + return readScript(istream, options); } - }; // now register with Registry to instantiate the above diff --git a/src/osgPlugins/lua/ReaderWriterLua.cpp b/src/osgPlugins/lua/ReaderWriterLua.cpp index 2296b31c5..e5a148ddb 100644 --- a/src/osgPlugins/lua/ReaderWriterLua.cpp +++ b/src/osgPlugins/lua/ReaderWriterLua.cpp @@ -28,45 +28,11 @@ class ReaderWriterLua : public osgDB::ReaderWriter virtual const char* className() const { return "Lua ScriptEngine plugin"; } - virtual ReadResult readObject(std::istream& fin,const osgDB::ReaderWriter::Options* options =NULL) const - { - osg::ref_ptr script = new osg::Script; - script->setLanguage("lua"); - - std::string str; - while(fin) - { - int c = fin.get(); - if (c>=0 && c<=255) - { - str.push_back(c); - } - } - script->setScript(str); - - return script.release(); - } - - virtual ReadResult readObject(const std::string& file, const osgDB::ReaderWriter::Options* options =NULL) const - { - if (file=="ScriptEngine.lua") return new lua::LuaScriptEngine(); - - std::string ext = osgDB::getLowerCaseFileExtension(file); - if (!acceptsExtension(ext)) return ReadResult::FILE_NOT_HANDLED; - - std::string fileName = osgDB::findDataFile( file, options ); - if (fileName.empty()) return ReadResult::FILE_NOT_FOUND; - - osgDB::ifstream istream(fileName.c_str(), std::ios::in); - if(!istream) return ReadResult::FILE_NOT_HANDLED; - - return readObject(istream, options); - } virtual ReadResult readObjectFromScript(std::istream& fin, const osgDB::ReaderWriter::Options* options =NULL) const { - ReadResult result = readObject(fin, options); + ReadResult result = readScript(fin, options); if (!result.validObject()) return result; osg::ref_ptr script = dynamic_cast(result.getObject()); @@ -112,6 +78,27 @@ class ReaderWriterLua : public osgDB::ReaderWriter else return 0; } + virtual ReadResult readObject(std::istream& fin, const osgDB::ReaderWriter::Options* options =NULL) const + { + return readObjectFromScript(fin, options); + } + + virtual ReadResult readObject(const std::string& file, const osgDB::ReaderWriter::Options* options =NULL) const + { + if (file=="ScriptEngine.lua") return new lua::LuaScriptEngine(); + + std::string ext = osgDB::getLowerCaseFileExtension(file); + if (!acceptsExtension(ext)) return ReadResult::FILE_NOT_HANDLED; + + std::string fileName = osgDB::findDataFile( file, options ); + if (fileName.empty()) return ReadResult::FILE_NOT_FOUND; + + osgDB::ifstream istream(fileName.c_str(), std::ios::in); + if(!istream) return ReadResult::FILE_NOT_HANDLED; + + return readObject(istream, options); + } + virtual ReadResult readImage(std::istream& fin, const osgDB::ReaderWriter::Options* options =NULL) const { return readObjectFromScript(fin, options); @@ -136,8 +123,8 @@ class ReaderWriterLua : public osgDB::ReaderWriter return readObjectFromScript(fin, options); } - virtual ReadResult readNode(const std::string& file, const osgDB::ReaderWriter::Options* options =NULL) const - { + virtual ReadResult readNode(const std::string& file, const osgDB::ReaderWriter::Options* options =NULL) const + { std::string ext = osgDB::getLowerCaseFileExtension(file); if (!acceptsExtension(ext)) return ReadResult::FILE_NOT_HANDLED; @@ -148,7 +135,41 @@ class ReaderWriterLua : public osgDB::ReaderWriter if(!istream) return ReadResult::FILE_NOT_HANDLED; return readNode(istream, options); - } + } + + virtual ReadResult readScript(std::istream& fin,const osgDB::ReaderWriter::Options* options =NULL) const + { + osg::ref_ptr script = new osg::Script; + script->setLanguage("lua"); + + std::string str; + while(fin) + { + int c = fin.get(); + if (c>=0 && c<=255) + { + str.push_back(c); + } + } + script->setScript(str); + + return script.release(); + } + + virtual ReadResult readScript(const std::string& file, const osgDB::ReaderWriter::Options* options =NULL) const + { + std::string ext = osgDB::getLowerCaseFileExtension(file); + if (!acceptsExtension(ext)) return ReadResult::FILE_NOT_HANDLED; + + std::string fileName = osgDB::findDataFile( file, options ); + if (fileName.empty()) return ReadResult::FILE_NOT_FOUND; + + osgDB::ifstream istream(fileName.c_str(), std::ios::in); + if(!istream) return ReadResult::FILE_NOT_HANDLED; + + return readScript(istream, options); + } + }; // now register with Registry to instantiate the above diff --git a/src/osgPlugins/python/ReaderWriterPython.cpp b/src/osgPlugins/python/ReaderWriterPython.cpp index 78ece43c3..a7a6fbba1 100644 --- a/src/osgPlugins/python/ReaderWriterPython.cpp +++ b/src/osgPlugins/python/ReaderWriterPython.cpp @@ -28,7 +28,19 @@ class ReaderWriterPython : public osgDB::ReaderWriter virtual const char* className() const { return "Python ScriptEngine plugin"; } - virtual ReadResult readObject(std::istream& fin,const osgDB::ReaderWriter::Options* options =NULL) const + virtual ReadResult readObject(std::istream& fin, const osgDB::ReaderWriter::Options* options =NULL) const + { + return readScript(fin); + } + + virtual ReadResult readObject(const std::string& file, const osgDB::ReaderWriter::Options* options =NULL) const + { + if (file=="ScriptEngine.python") return new python::PythonScriptEngine(); + + return readScript(file, options); + } + + virtual ReadResult readScript(std::istream& fin, const osgDB::ReaderWriter::Options* options =NULL) const { osg::ref_ptr script = new osg::Script; script->setLanguage("python"); @@ -47,10 +59,10 @@ class ReaderWriterPython : public osgDB::ReaderWriter return script.release(); } - virtual ReadResult readObject(const std::string& file, const osgDB::ReaderWriter::Options* options =NULL) const + + virtual ReadResult readScript(const std::string& file, const osgDB::ReaderWriter::Options* options =NULL) const { if (file=="ScriptEngine.python") return new python::PythonScriptEngine(); - std::string ext = osgDB::getLowerCaseFileExtension(file); if (!acceptsExtension(ext)) return ReadResult::FILE_NOT_HANDLED; @@ -60,7 +72,7 @@ class ReaderWriterPython : public osgDB::ReaderWriter osgDB::ifstream istream(fileName.c_str(), std::ios::in); if(!istream) return ReadResult::FILE_NOT_HANDLED; - return readObject(istream, options); + return readScript(istream, options); } };