Added support for openArchive into osgDB

This commit is contained in:
Robert Osfield
2004-11-07 21:17:31 +00:00
parent f44ecb1f65
commit f84f8d87e0
6 changed files with 249 additions and 29 deletions

View File

@@ -21,6 +21,17 @@ using namespace osgDB;
float Archive::s_currentSupportedVersion = 0.0;
osgDB::Archive* osgDB::openArchive(const std::string& filename, Archive::ArchiveStatus status, unsigned int indexBlockSizeHint)
{
return openArchive(filename, status, indexBlockSizeHint, Registry::instance()->getUseObjectCacheHint());
}
osgDB::Archive* osgDB::openArchive(const std::string& filename, Archive::ArchiveStatus status, unsigned int indexBlockSizeHint,Registry::CacheHintOptions useObjectCache)
{
ReaderWriter::ReadResult result = osgDB::Registry::instance()->openArchive(filename, status, indexBlockSizeHint, useObjectCache);
return result.takeArchive();
}
Archive::IndexBlock::IndexBlock(unsigned int blockSize):
_requiresWrite(false),
_filePosition(0),
@@ -185,7 +196,7 @@ Archive::~Archive()
}
#include <sys/stat.h>
bool Archive::open(const std::string& filename, Status status, unsigned int indexBlockSize)
bool Archive::open(const std::string& filename, ArchiveStatus status, unsigned int indexBlockSize)
{
if (status==READ)
{
@@ -295,6 +306,7 @@ bool Archive::open(const std::string& filename, Status status, unsigned int inde
else
{
osg::notify(osg::NOTICE)<<"Archive::open("<<filename<<") is a strange place!!."<<std::endl;
return false;
}
}

View File

@@ -12,9 +12,22 @@
*/
#include <osgDB/ReaderWriter>
#include <osgDB/Archive>
using namespace osgDB;
osg::Object* ReaderWriter::ReadResult::getObject() { return _object.get(); }
osg::Image* ReaderWriter::ReadResult::getImage() { return dynamic_cast<osg::Image*>(_object.get()); }
osg::HeightField* ReaderWriter::ReadResult::getHeightField() { return dynamic_cast<osg::HeightField*>(_object.get()); }
osg::Node* ReaderWriter::ReadResult::getNode() { return dynamic_cast<osg::Node*>(_object.get()); }
osgDB::Archive* ReaderWriter::ReadResult::getArchive() { return dynamic_cast<osgDB::Archive*>(_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<osg::Image*>(_object.get()); if (image) { image->ref(); _object=NULL; image->unref_nodelete(); } return image; }
osg::HeightField* ReaderWriter::ReadResult::takeHeightField() { osg::HeightField* hf=dynamic_cast<osg::HeightField*>(_object.get()); if (hf) { hf->ref(); _object=NULL; hf->unref_nodelete(); } return hf; }
osg::Node* ReaderWriter::ReadResult::takeNode() { osg::Node* node=dynamic_cast<osg::Node*>(_object.get()); if (node) { node->ref(); _object=NULL; node->unref_nodelete(); } return node; }
osgDB::Archive* ReaderWriter::ReadResult::takeArchive() { osgDB::Archive* archive=dynamic_cast<osgDB::Archive*>(_object.get()); if (archive) { archive->ref(); _object=NULL; archive->unref_nodelete(); } return archive; }
ReaderWriter::~ReaderWriter()
{
}

View File

@@ -22,6 +22,7 @@
#include <osgDB/Registry>
#include <osgDB/FileUtils>
#include <osgDB/FileNameUtils>
#include <osgDB/Archive>
#include <stdio.h>
@@ -1113,6 +1114,162 @@ bool Registry::writeObject(const osg::Object& obj,Output& fw)
return false;
}
//
// read object from specified file.
//
ReaderWriter::ReadResult Registry::openArchive(const std::string& fileName, ReaderWriter::ArchiveStatus status, unsigned int indexBlockSizeHint)
{
if (containsServerAddress(fileName))
{
std::string serverName = getServerAddress(fileName);
std::string serverFile = getServerFileName(fileName);
osg::notify(osg::INFO)<<"Contains sever address : "<<serverName<<std::endl;
osg::notify(osg::INFO)<<" file name on server : "<<serverFile<<std::endl;
if (serverName.empty())
{
return ReaderWriter::ReadResult("Warning: Server address invalid.");
}
if (serverFile.empty())
{
return ReaderWriter::ReadResult("Warning: Server file name invalid.");
}
ReaderWriter* rw = getReaderWriterForExtension("net");
if (rw)
{
return rw->openArchive(serverName+":"+serverFile, status, indexBlockSizeHint, _options.get());
}
else
{
return ReaderWriter::ReadResult("Warning: Could not find the .net plugin to read from server.");
}
}
// record the errors reported by readerwriters.
typedef std::vector<ReaderWriter::ReadResult> Results;
Results results;
// first attempt to load the file from existing ReaderWriter's
AvailableReaderWriterIterator itr(_rwList);
for(;itr.valid();++itr)
{
ReaderWriter::ReadResult rr = itr->openArchive(fileName,status, indexBlockSizeHint, _options.get());
if (rr.validArchive()) return rr;
else results.push_back(rr);
}
if (!results.empty())
{
unsigned int num_FILE_NOT_HANDLED = 0;
unsigned int num_FILE_NOT_FOUND = 0;
unsigned int num_ERROR_IN_READING_FILE = 0;
for(Results::iterator ritr=results.begin();
ritr!=results.end();
++ritr)
{
if (ritr->status()==ReaderWriter::ReadResult::FILE_NOT_HANDLED) ++num_FILE_NOT_HANDLED;
else if (ritr->status()==ReaderWriter::ReadResult::FILE_NOT_FOUND) ++num_FILE_NOT_FOUND;
else if (ritr->status()==ReaderWriter::ReadResult::ERROR_IN_READING_FILE) ++num_ERROR_IN_READING_FILE;
}
if (num_FILE_NOT_HANDLED!=results.size())
{
// we've come across a file not found or error in reading file.
if (num_ERROR_IN_READING_FILE)
{
osg::notify(osg::NOTICE)<<"Warning: error reading file \""<<fileName<<"\""<<std::endl;
return NULL;
}
else if (num_FILE_NOT_FOUND)
{
osg::notify(osg::NOTICE)<<"Warning: could not find file \""<<fileName<<"\""<<std::endl;
return NULL;
}
}
}
// now look for a plug-in to load the file.
std::string libraryName = createLibraryNameForFile(fileName);
if (loadLibrary(libraryName))
{
for(;itr.valid();++itr)
{
ReaderWriter::ReadResult rr = itr->openArchive(fileName,status, indexBlockSizeHint, _options.get());
if (rr.validArchive()) return rr;
else results.push_back(rr);
}
}
if (results.empty())
{
return ReaderWriter::ReadResult("Warning: Could not find plugin to read objects from file \""+fileName+"\".");
}
return results.front();
}
ReaderWriter::ReadResult Registry::openArchiveImplementation(const std::string& fileName, ReaderWriter::ArchiveStatus status, unsigned int indexBlockSizeHint, CacheHintOptions useObjectCache)
{
std::string file(fileName);
if (useObjectCache & CACHE_OBJECTS)
{
// search for entry in the object cache.
{
OpenThreads::ScopedLock<OpenThreads::Mutex> lock(_objectCacheMutex);
ObjectCache::iterator oitr=_objectCache.find(file);
if (oitr!=_objectCache.end())
{
notify(INFO)<<"returning cached instanced of "<<file<<std::endl;
osgDB::Archive* archive = dynamic_cast<osgDB::Archive*>(oitr->second.first.get());
if (archive) return ReaderWriter::ReadResult(archive, ReaderWriter::ReadResult::FILE_LOADED_FROM_CACHE);
else return ReaderWriter::ReadResult("Error file does not contain an osg::Object");
}
}
PushAndPopDataPath tmpfile(getFilePath(file));
ReaderWriter::ReadResult rr = openArchive(file, status, indexBlockSizeHint);
if (rr.validObject())
{
// update cache with new entry.
notify(INFO)<<"Adding to cache object "<<file<<std::endl;
addEntryToObjectCache(file,rr.getObject());
}
return rr;
}
else
{
ObjectCache tmpObjectCache;
{
OpenThreads::ScopedLock<OpenThreads::Mutex> lock(_objectCacheMutex);
tmpObjectCache.swap(_objectCache);
}
PushAndPopDataPath tmpfile(getFilePath(file));
ReaderWriter::ReadResult rr = openArchive(file, status, indexBlockSizeHint);
{
OpenThreads::ScopedLock<OpenThreads::Mutex> lock(_objectCacheMutex);
tmpObjectCache.swap(_objectCache);
}
return rr;
}
}
//
// read object from specified file.
//