From 4973824b1d89e499287d29577d32d45ddd5ce14e Mon Sep 17 00:00:00 2001 From: Robert Osfield Date: Wed, 10 Nov 2004 16:40:08 +0000 Subject: [PATCH] Added new osga plugin for reading OSG native archives --- Make/makedirdefs | 1 + VisualStudio/VisualStudio.dsw | 21 +++++ VisualStudio/osgPlugins/osga/osga.dsp | 111 +++++++++++++++++++++++ include/osgDB/Registry | 31 ++++++- src/osgDB/Registry.cpp | 99 ++++++++++++++------ src/osgPlugins/osga/GNUmakefile | 16 ++++ src/osgPlugins/osga/ReaderWriterOSGA.cpp | 71 +++++++++++++++ 7 files changed, 316 insertions(+), 34 deletions(-) create mode 100644 VisualStudio/osgPlugins/osga/osga.dsp create mode 100644 src/osgPlugins/osga/GNUmakefile create mode 100644 src/osgPlugins/osga/ReaderWriterOSGA.cpp diff --git a/Make/makedirdefs b/Make/makedirdefs index a1070d7c9..3a801e57f 100644 --- a/Make/makedirdefs +++ b/Make/makedirdefs @@ -48,6 +48,7 @@ PLUGIN_DIRS = \ osgSim\ osgFX\ osg\ + osga\ osgtgz\ pic\ pnm\ diff --git a/VisualStudio/VisualStudio.dsw b/VisualStudio/VisualStudio.dsw index d359b32e4..b85438e07 100644 --- a/VisualStudio/VisualStudio.dsw +++ b/VisualStudio/VisualStudio.dsw @@ -2358,6 +2358,27 @@ Package=<4> ############################################################################### +Project: "osgPlugin osga"=.\osgPlugins\osga\osga.dsp - Package Owner=<4> + +Package=<5> +{{{ +}}} + +Package=<4> +{{{ + Begin Project Dependency + Project_Dep_Name Core osg + End Project Dependency + Begin Project Dependency + Project_Dep_Name Core osgDB + End Project Dependency + Begin Project Dependency + Project_Dep_Name Core osgUtil + End Project Dependency +}}} + +############################################################################### + Project: "osgPlugin net"=".\osgPlugins\net\net.dsp" - Package Owner=<4> Package=<5> diff --git a/VisualStudio/osgPlugins/osga/osga.dsp b/VisualStudio/osgPlugins/osga/osga.dsp new file mode 100644 index 000000000..b4a2bd84a --- /dev/null +++ b/VisualStudio/osgPlugins/osga/osga.dsp @@ -0,0 +1,111 @@ +# Microsoft Developer Studio Project File - Name="osgPlugin osga" - Package Owner=<4> +# Microsoft Developer Studio Generated Build File, Format Version 6.00 +# ** DO NOT EDIT ** + +# TARGTYPE "Win32 (x86) Dynamic-Link Library" 0x0102 + +CFG=osgPlugin osga - Win32 Release +!MESSAGE This is not a valid makefile. To build this project using NMAKE, +!MESSAGE use the Export Makefile command and run +!MESSAGE +!MESSAGE NMAKE /f "osga.mak". +!MESSAGE +!MESSAGE You can specify a configuration when running NMAKE +!MESSAGE by defining the macro CFG on the command line. For example: +!MESSAGE +!MESSAGE NMAKE /f "osga.mak" CFG="osgPlugin osga - Win32 Release" +!MESSAGE +!MESSAGE Possible choices for configuration are: +!MESSAGE +!MESSAGE "osgPlugin osga - Win32 Release" (based on "Win32 (x86) Dynamic-Link Library") +!MESSAGE "osgPlugin osga - Win32 Debug" (based on "Win32 (x86) Dynamic-Link Library") +!MESSAGE + +# Begin Project +# PROP AllowPerConfigDependencies 0 +# PROP Scc_ProjName "" +# PROP Scc_LocalPath "" +CPP=cl.exe +MTL=midl.exe +RSC=rc.exe + +!IF "$(CFG)" == "osgPlugin osga - Win32 Release" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 0 +# PROP BASE Output_Dir "Release" +# PROP BASE Intermediate_Dir "Release" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 0 +# PROP Output_Dir "../../../lib" +# PROP Intermediate_Dir "Release" +# PROP Ignore_Export_Lib 0 +# PROP Target_Dir "" +F90=df.exe +# ADD BASE CPP /nologo /MT /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /YX /FD /c +# ADD CPP /nologo /MD /W3 /GR /GX /O2 /I "../../../include" /I "../../../../OpenThreads/include" /I "../../../../Producer/include" /I "../../../../3rdParty/include" /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /YX /FD /c +# ADD BASE MTL /nologo /D "NDEBUG" /mktyplib203 /win32 +# ADD MTL /nologo /D "NDEBUG" /mktyplib203 /win32 +# ADD BASE RSC /l 0x809 /d "NDEBUG" +# ADD RSC /l 0x809 /d "NDEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /machine:I386 +# ADD LINK32 OpenThreadsWin32.lib /nologo /dll /pdb:none /machine:I386 /nodefaultlib:"LIBC" /out:"../../../bin/osgdb_osga.dll" /libpath:"../../../lib" /libpath:"../../../../OpenThreads/lib/win32" /libpath:"../../../../Producer/lib" /libpath:"../../../../3rdParty/lib" +# SUBTRACT LINK32 /nodefaultlib + +!ELSEIF "$(CFG)" == "osgPlugin osga - Win32 Debug" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 1 +# PROP BASE Output_Dir "Debug" +# PROP BASE Intermediate_Dir "Debug" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 1 +# PROP Output_Dir "../../../lib" +# PROP Intermediate_Dir "Debug" +# PROP Ignore_Export_Lib 0 +# PROP Target_Dir "" +F90=df.exe +# ADD BASE CPP /nologo /MTd /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /YX /FD /GZ /c +# ADD CPP /nologo /MDd /W3 /Gm /vmg /vd0 /GR /GX /Zi /Od /I "../../../include" /I "../../../../OpenThreads/include" /I "../../../../Producer/include" /I "../../../../3rdParty/include" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "WIN32" /D "_DEBUG" /YX /FD /GZ /c +# ADD BASE MTL /nologo /D "_DEBUG" /mktyplib203 /win32 +# ADD MTL /nologo /D "_DEBUG" /mktyplib203 /win32 +# ADD BASE RSC /l 0x809 /d "_DEBUG" +# ADD RSC /l 0x809 /d "_DEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /debug /machine:I386 /pdbtype:sept +# ADD LINK32 OpenThreadsWin32d.lib /nologo /dll /debug /machine:I386 /nodefaultlib:"LIBC" /out:"../../../bin/osgdb_osgad.dll" /pdbtype:sept /libpath:"../../../lib" /libpath:"../../../../OpenThreads/lib/win32" /libpath:"../../../../Producer/lib" /libpath:"../../../../3rdParty/lib" +# SUBTRACT LINK32 /nodefaultlib + +!ENDIF + +# Begin Target + +# Name "osgPlugin osga - Win32 Release" +# Name "osgPlugin osga - Win32 Debug" +# Begin Group "Source Files" + +# PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat" +# Begin Source File + +SOURCE=..\..\..\src\osgPlugins\osga\ReaderWriterOSGA.cpp +# End Source File +# End Group +# Begin Group "Header Files" + +# PROP Default_Filter "h;hpp;hxx;hm;inl" +# End Group +# Begin Group "Resource Files" + +# PROP Default_Filter "ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe" +# End Group +# End Target +# End Project diff --git a/include/osgDB/Registry b/include/osgDB/Registry index 7b832477c..76836dbc3 100644 --- a/include/osgDB/Registry +++ b/include/osgDB/Registry @@ -370,11 +370,22 @@ class OSGDB_EXPORT Registry : public osg::Referenced /** Get whether the Registry::ObjectCache should be used by default.*/ CacheHintOptions getUseObjectCacheHint() const { return _useObjectCacheHint; } + + /** Add archive to archive cache so that future calls reference this archive.*/ + void addToArchiveCache(const std::string& fileName, osgDB::Archive* archive); + + /** Remove archive from cache.*/ + void removeFromArchiveCache(const std::string& fileName); + + /** Get an archive from the archive cache*/ + osgDB::Archive* getFromArchiveCache(const std::string& fileName); + + /** Remove all archives from the archive cache.*/ + void clearArchiveCache(); + + /** get the attached library with specified name.*/ DynamicLibrary* getLibrary(const std::string& fileName); - - typedef std::vector< osg::ref_ptr > ReaderWriterList; - /** Set the DatabasePager.*/ void setDatabasePager(DatabasePager* databasePager) { _databasePager = databasePager; } @@ -400,12 +411,14 @@ class OSGDB_EXPORT Registry : public osg::Referenced virtual ~Registry(); + typedef std::vector< osg::ref_ptr > ReaderWriterList; typedef std::map< std::string, osg::ref_ptr > DotOsgWrapperMap; typedef std::vector< osg::ref_ptr > DynamicLibraryList; typedef std::map< std::string, std::string> ExtensionAliasMap; typedef std::pair, double > ObjectTimeStampPair; typedef std::map ObjectCache; + typedef std::map > ArchiveCache; /** constructor is private, as its a singleton, preventing construction other than via the instance() method and @@ -437,6 +450,7 @@ class OSGDB_EXPORT Registry : public osg::Referenced const ReaderWriter::Options* _options; }; + // forward declare helper classes struct ReadObjectFunctor; struct ReadImageFunctor; struct ReadHeightFieldFunctor; @@ -444,7 +458,12 @@ class OSGDB_EXPORT Registry : public osg::Referenced struct ReadArchiveFunctor; ReaderWriter::ReadResult read(const ReadFunctor& readFunctor); - ReaderWriter::ReadResult readImplementation(const ReadFunctor& readFunctor,CacheHintOptions useObjectCache); + ReaderWriter::ReadResult readImplementation(const ReadFunctor& readFunctor,bool useObjectCache); + + + // forward declar helper class + class AvailableReaderWriterIterator; + osg::ref_ptr _readFileCallback; osg::ref_ptr _writeFileCallback; @@ -475,6 +494,10 @@ class OSGDB_EXPORT Registry : public osg::Referenced ObjectCache _objectCache; OpenThreads::Mutex _objectCacheMutex; + ArchiveCache _archiveCache; + OpenThreads::Mutex _archiveCacheMutex; + + osg::ref_ptr _databasePager; osg::ref_ptr _sharedStateManager; diff --git a/src/osgDB/Registry.cpp b/src/osgDB/Registry.cpp index f3bc5ec30..c7c9b60da 100644 --- a/src/osgDB/Registry.cpp +++ b/src/osgDB/Registry.cpp @@ -32,7 +32,7 @@ using namespace osg; using namespace osgDB; -class AvailableReaderWriterIterator +class Registry::AvailableReaderWriterIterator { public: AvailableReaderWriterIterator(Registry::ReaderWriterList& rwList): @@ -138,7 +138,7 @@ Registry::Registry() _createNodeFromImage = false; _openingLibrary = false; - _useObjectCacheHint = CACHE_NONE; + _useObjectCacheHint = CACHE_ARCHIVES; initFilePathLists(); @@ -220,6 +220,8 @@ Registry::~Registry() // even some issue with objects be allocated by a plugin that is // mainted after that plugin is deleted... Robert Osfield, Jan 2004. clearObjectCache(); + clearArchiveCache(); + // unload all the plugin before we finally destruct. closeAllLibraries(); @@ -1183,30 +1185,16 @@ ReaderWriter::ReadResult Registry::read(const ReadFunctor& readFunctor) osg::notify(osg::INFO)<<" archive : "< s_archive; - if (!s_archive) - { - s_archive = new Archive; - s_archive->open(archiveName,ReaderWriter::READ, 4096); - } + if (!result.validArchive()) return result; + + osgDB::Archive* archive = result.getArchive(); osg::ref_ptr options = new ReaderWriter::Options; options->setDatabasePath(archiveName); - if (s_archive.valid()) - { - osg::notify(osg::INFO)<<" archive loaded"<readObject(fileName,options.get()); - } - else - { - osg::notify(osg::INFO)<<" no archive loaded"<readObject(fileName,options.get()); } // if filename contains archive @@ -1308,11 +1296,11 @@ ReaderWriter::ReadResult Registry::read(const ReadFunctor& readFunctor) return results.front(); } -ReaderWriter::ReadResult Registry::readImplementation(const ReadFunctor& readFunctor, CacheHintOptions useObjectCache) +ReaderWriter::ReadResult Registry::readImplementation(const ReadFunctor& readFunctor, bool useObjectCache) { std::string file(readFunctor._filename); - if (useObjectCache & CACHE_OBJECTS) + if (useObjectCache) { // search for entry in the object cache. { @@ -1335,13 +1323,16 @@ ReaderWriter::ReadResult Registry::readImplementation(const ReadFunctor& readFun notify(INFO)<<"Adding to object cache "< lock(_objectCacheMutex); typedef std::vector ObjectsToRemove; @@ -1595,6 +1603,37 @@ void Registry::clearObjectCache() _objectCache.clear(); } +void Registry::addToArchiveCache(const std::string& fileName, osgDB::Archive* archive) +{ + OpenThreads::ScopedLock lock(_archiveCacheMutex); + _archiveCache[fileName] = archive; +} + +/** Remove archive from cache.*/ +void Registry::removeFromArchiveCache(const std::string& fileName) +{ + OpenThreads::ScopedLock lock(_archiveCacheMutex); + ArchiveCache::iterator itr = _archiveCache.find(fileName); + if (itr!=_archiveCache.end()) + { + _archiveCache.erase(itr); + } +} + +osgDB::Archive* Registry::getFromArchiveCache(const std::string& fileName) +{ + OpenThreads::ScopedLock lock(_archiveCacheMutex); + ArchiveCache::iterator itr = _archiveCache.find(fileName); + if (itr!=_archiveCache.end()) return itr->second.get(); + else return 0; +} + +void Registry::clearArchiveCache() +{ + OpenThreads::ScopedLock lock(_archiveCacheMutex); + _archiveCache.clear(); +} + DatabasePager* Registry::getOrCreateDatabasePager() { if (!_databasePager) _databasePager = new DatabasePager; diff --git a/src/osgPlugins/osga/GNUmakefile b/src/osgPlugins/osga/GNUmakefile new file mode 100644 index 000000000..e73410603 --- /dev/null +++ b/src/osgPlugins/osga/GNUmakefile @@ -0,0 +1,16 @@ +TOPDIR = ../../.. +include $(TOPDIR)/Make/makedefs + +CXXFILES =\ + ReaderWriterOSGA.cpp\ + + +INC += -I$(THISDIR) + +LIBS += $(OSG_LIBS) $(OTHER_LIBS) + +TARGET_BASENAME = osga +include $(TOPDIR)/Make/cygwin_plugin_def +PLUGIN = $(PLUGIN_PREFIX)$(TARGET_BASENAME).$(PLUGIN_EXT) + +include $(TOPDIR)/Make/makerules diff --git a/src/osgPlugins/osga/ReaderWriterOSGA.cpp b/src/osgPlugins/osga/ReaderWriterOSGA.cpp new file mode 100644 index 000000000..3b61aed67 --- /dev/null +++ b/src/osgPlugins/osga/ReaderWriterOSGA.cpp @@ -0,0 +1,71 @@ +#include + +#include +#include +#include + +class ReaderWriterOSGA : public osgDB::ReaderWriter +{ +public: + ReaderWriterOSGA() { } + + virtual const char* className() const { return "OpenSceneGraph Archive Reader/Writer"; } + virtual bool acceptsExtension(const std::string& extension) + { + return osgDB::equalCaseInsensitive(extension,"osga"); + } + + virtual ReadResult openArchive(const std::string& file,ArchiveStatus status, unsigned int indexBlockSize = 4096, const Options* = NULL) + { + std::string ext = osgDB::getLowerCaseFileExtension(file); + if (!acceptsExtension(ext)) return ReadResult::FILE_NOT_HANDLED; + + std::string fileName = osgDB::findDataFile( file ); + if (fileName.empty()) return ReadResult::FILE_NOT_FOUND; + + osg::ref_ptr archive = new osgDB::Archive; + if (!archive->open(fileName, status, indexBlockSize)) + { + return ReadResult(ReadResult::FILE_NOT_HANDLED); + } + + return archive.get(); + } + + virtual ReadResult readObject(const std::string& /*fileName*/,const Options* =NULL) { return ReadResult(ReadResult::FILE_NOT_HANDLED); } + virtual ReadResult readImage(const std::string& /*fileName*/,const Options* =NULL) { return ReadResult(ReadResult::FILE_NOT_HANDLED); } + virtual ReadResult readHeightField(const std::string& /*fileName*/,const Options* =NULL) { return ReadResult(ReadResult::FILE_NOT_HANDLED); } + + virtual ReadResult readNode(const std::string& file,const Options* options) + { + ReadResult result = openArchive(file,osgDB::Archive::READ); + + if (!result.validArchive()) return result; + + + osg::ref_ptr local_options = new ReaderWriter::Options; + local_options->setDatabasePath(file); + + ReadResult result_2 = result.getArchive()->readNode(result.getArchive()->getMasterFileName(),local_options.get()); + + + // register the archive so that it is cached for future use. + osgDB::Registry::instance()->addToArchiveCache(file, result.getArchive()); + + + return result_2; + } + + virtual WriteResult writeObject(const osg::Object& /*obj*/,const std::string& /*fileName*/,const Options* =NULL) {return WriteResult(WriteResult::FILE_NOT_HANDLED); } + virtual WriteResult writeImage(const osg::Image& /*image*/,const std::string& /*fileName*/,const Options* =NULL) {return WriteResult(WriteResult::FILE_NOT_HANDLED); } + virtual WriteResult writeHeightField(const osg::HeightField& /*heightField*/,const std::string& /*fileName*/,const Options* =NULL) {return WriteResult(WriteResult::FILE_NOT_HANDLED); } + virtual WriteResult writeNode(const osg::Node& /*node*/,const std::string& /*fileName*/,const Options* =NULL) { return WriteResult(WriteResult::FILE_NOT_HANDLED); } + +protected: + + +}; + + +// register with Registry to instantiate the above reader/writer. +osgDB::RegisterReaderWriterProxy g_osgaReaderWriterProxy;