From 986fc05ac1bc54e7a3702cb8bf165f77766aba5c Mon Sep 17 00:00:00 2001 From: Robert Osfield Date: Fri, 29 May 2009 18:24:47 +0000 Subject: [PATCH] Added revisions plugin in support of paged database revisions. --- include/osgDB/DatabaseRevisions | 46 ++++- src/osgDB/DatabaseRevisions.cpp | 54 ++++- src/osgPlugins/CMakeLists.txt | 1 + src/osgPlugins/revisions/CMakeLists.txt | 4 + .../revisions/ReaderWriterRevisions.cpp | 189 ++++++++++++++++++ 5 files changed, 287 insertions(+), 7 deletions(-) create mode 100644 src/osgPlugins/revisions/CMakeLists.txt create mode 100644 src/osgPlugins/revisions/ReaderWriterRevisions.cpp diff --git a/include/osgDB/DatabaseRevisions b/include/osgDB/DatabaseRevisions index a480f7e6a..2e51265c2 100644 --- a/include/osgDB/DatabaseRevisions +++ b/include/osgDB/DatabaseRevisions @@ -22,6 +22,28 @@ namespace osgDB { +class OSGDB_EXPORT FileList : public osg::Object +{ + public: + + FileList(); + FileList(const FileList& fileList, const osg::CopyOp=osg::CopyOp::SHALLOW_COPY); + + META_Object(osgDB, FileList) + + typedef std::set FileNames; + FileNames& getFileNames() { return _files; } + const FileNames& getFileNames() const { return _files; } + + bool contains(const std::string& filename) const { return _files.count(filename)!=0; } + + protected: + + virtual ~FileList(); + + FileNames _files; +}; + class OSGDB_EXPORT DatabaseRevision : public osg::Object { @@ -34,9 +56,17 @@ class OSGDB_EXPORT DatabaseRevision : public osg::Object typedef std::set FileNames; - FileNames& getFilesAdded() { return _filesAdded; } - FileNames& getFilesRemoved() { return _filesRemoved; } - FileNames& getFilesModified() { return _filesModified; } + void setFilesAdded(FileList* fileList) { _filesAdded = fileList; } + FileList* getFilesAdded() { return _filesAdded.get(); } + const FileList* getFilesAdded() const { return _filesAdded.get(); } + + void setFilesRemoved(FileList* fileList) { _filesRemoved = fileList; } + FileList* getFilesRemoved() { return _filesRemoved.get(); } + const FileList* getFilesRemoved() const { return _filesRemoved.get(); } + + void setFilesModified(FileList* fileList) { _filesModified = fileList; } + FileList* getFilesModified() { return _filesModified.get(); } + const FileList* getFilesModified() const { return _filesModified.get(); } bool isFileBlackListed(const std::string& filename) const; @@ -44,9 +74,9 @@ class OSGDB_EXPORT DatabaseRevision : public osg::Object virtual ~DatabaseRevision(); - FileNames _filesAdded; - FileNames _filesRemoved; - FileNames _filesModified; + osg::ref_ptr _filesAdded; + osg::ref_ptr _filesRemoved; + osg::ref_ptr _filesModified; }; class OSGDB_EXPORT DatabaseRevisions : public osg::Object @@ -60,7 +90,11 @@ class OSGDB_EXPORT DatabaseRevisions : public osg::Object typedef std::vector< osg::ref_ptr > DatabaseRevisionList; + void addRevision(DatabaseRevision* revision); + void removeRevision(DatabaseRevision* revision); + DatabaseRevisionList& getDatabaseRevisionList() { return _revisionList; } + const DatabaseRevisionList& getDatabaseRevisionList() const { return _revisionList; } bool isFileBlackListed(const std::string& filename) const; diff --git a/src/osgDB/DatabaseRevisions.cpp b/src/osgDB/DatabaseRevisions.cpp index b57013271..c0194f589 100644 --- a/src/osgDB/DatabaseRevisions.cpp +++ b/src/osgDB/DatabaseRevisions.cpp @@ -19,6 +19,24 @@ using namespace osgDB; +//////////////////////////////////////////////////////////////////////////////////////////// +// +// FilelList +// +FileList::FileList() +{ +} + +FileList::FileList(const FileList& fileList, const osg::CopyOp): + _files(fileList._files) +{ +} + +FileList::~FileList() +{ +} + + //////////////////////////////////////////////////////////////////////////////////////////// // // DatabaseRevision @@ -40,7 +58,8 @@ DatabaseRevision::~DatabaseRevision() bool DatabaseRevision::isFileBlackListed(const std::string& filename) const { - return _filesRemoved.count(filename)!=0 || _filesModified.count(filename)!=0; + return (_filesRemoved.valid() && _filesRemoved->contains(filename)) || + (_filesAdded.valid() && _filesAdded->contains(filename)); } @@ -61,6 +80,39 @@ DatabaseRevisions::~DatabaseRevisions() { } +void DatabaseRevisions::addRevision(DatabaseRevision* revision) +{ + if (!revision) return; + + for(DatabaseRevisionList::iterator itr = _revisionList.begin(); + itr != _revisionList.end(); + ++itr) + { + if (*itr == revision) return; + if ((*itr)->getName()==revision->getName()) + { + (*itr) = revision; + return; + } + } + + _revisionList.push_back(revision); +} + +void DatabaseRevisions::removeRevision(DatabaseRevision* revision) +{ + for(DatabaseRevisionList::iterator itr = _revisionList.begin(); + itr != _revisionList.end(); + ++itr) + { + if (*itr == revision) + { + _revisionList.erase(itr); + return; + } + } +} + bool DatabaseRevisions::isFileBlackListed(const std::string& filename) const { for(DatabaseRevisionList::const_iterator itr = _revisionList.begin(); diff --git a/src/osgPlugins/CMakeLists.txt b/src/osgPlugins/CMakeLists.txt index 979bc96f1..e7f158faf 100644 --- a/src/osgPlugins/CMakeLists.txt +++ b/src/osgPlugins/CMakeLists.txt @@ -51,6 +51,7 @@ ADD_SUBDIRECTORY(rot) ADD_SUBDIRECTORY(scale) ADD_SUBDIRECTORY(trans) ADD_SUBDIRECTORY(normals) +ADD_SUBDIRECTORY(revisions) ############################################################ # diff --git a/src/osgPlugins/revisions/CMakeLists.txt b/src/osgPlugins/revisions/CMakeLists.txt new file mode 100644 index 000000000..9d1f93957 --- /dev/null +++ b/src/osgPlugins/revisions/CMakeLists.txt @@ -0,0 +1,4 @@ +SET(TARGET_SRC ReaderWriterRevisions.cpp ) + +#### end var setup ### +SETUP_PLUGIN(revisions) diff --git a/src/osgPlugins/revisions/ReaderWriterRevisions.cpp b/src/osgPlugins/revisions/ReaderWriterRevisions.cpp new file mode 100644 index 000000000..2f67dd3c3 --- /dev/null +++ b/src/osgPlugins/revisions/ReaderWriterRevisions.cpp @@ -0,0 +1,189 @@ +#include +#include +#include +#include +#include +#include + +class ReaderWriterFreeType : public osgDB::ReaderWriter +{ + public: + ReaderWriterFreeType() + { + supportsExtension("revisions","list of revision files"); + supportsExtension("added","revision file containing list of added files"); + supportsExtension("removed","revision file containing list of removed files"); + supportsExtension("modified","revision file containing list of modified files"); + } + + virtual const char* className() const { return "FreeType Font Reader/Writer"; } + + virtual ReadResult readObject(const std::string& file, const osgDB::ReaderWriter::Options* options) 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; + + std::ifstream fin(fileName.c_str()); + + if (ext=="revisions") return readRevisions(fin, file, options); + else return readFileList(fin, file, options); + } + + virtual ReadResult readObject(std::istream& fin, const osgDB::ReaderWriter::Options* options) const + { + std::string fileName = options->getPluginStringData("filename"); + if (fileName.empty()) + { + osg::notify(osg::NOTICE)<<"Error: ReaderWriterRevision unable to determine stream type, cannot not read file."< fileList = new osgDB::FileList; + fileList->setName(name); + + while(fin) + { + std::string filename; + fin >> filename; + if (!filename.empty()) fileList->getFileNames().insert(filename); + } + + return fileList.get(); + } + + ReadResult readRevisions(std::istream& fin, const std::string& name, const osgDB::ReaderWriter::Options* options) const + { + osg::ref_ptr revisions = new osgDB::DatabaseRevisions; + revisions->setName(name); + + typedef std::map > RevisionMap; + RevisionMap revisionMap; + + std::string revisions_path; + if (options && !(options->getDatabasePathList().empty())) revisions_path = options->getDatabasePathList().front(); + + while(fin) + { + std::string filename; + fin >> filename; + if (!filename.empty()) + { + std::string ext = osgDB::getLowerCaseFileExtension(filename); + std::string revisionName = osgDB::getNameLessExtension(filename); + if (revisionName.empty()) + { + osg::ref_ptr& dbRevision = revisionMap[revisionName]; + if (!dbRevision) + { + dbRevision = new osgDB::DatabaseRevision; + dbRevision->setName(revisionName); + } + + std::string complete_path = osgDB::concatPaths(revisions_path, filename); + osg::ref_ptr object = osgDB::readObjectFile(complete_path, options); + osgDB::FileList* fileList = dynamic_cast(object.get()); + + if (fileList) + { + if (ext=="added") + { + dbRevision->setFilesAdded(fileList); + } + else if (ext=="removed") + { + dbRevision->setFilesRemoved(fileList); + } + else if (ext=="modified") + { + dbRevision->setFilesModified(fileList); + } + } + } + } + } + + for(RevisionMap::iterator itr = revisionMap.begin(); + itr != revisionMap.end(); + ++itr) + { + revisions->addRevision(itr->second); + } + + return revisions.get(); + } + + virtual WriteResult writeObject(const osg::Object& object, std::ostream& fout,const osgDB::ReaderWriter::Options*) const + { + const osgDB::FileList* fileList = dynamic_cast(&object); + if (fileList) + { + const osgDB::FileList::FileNames& fileNames = fileList->getFileNames(); + for(osgDB::FileList::FileNames::const_iterator itr = fileNames.begin(); + itr != fileNames.end(); + ++itr) + { + fout<<*itr<(&object); + if (revisions) + { + typedef osgDB::DatabaseRevisions::DatabaseRevisionList RevisionList; + const RevisionList& revisionList = revisions->getDatabaseRevisionList(); + for(RevisionList::const_iterator itr = revisionList.begin(); + itr != revisionList.end(); + ++itr) + { + const osgDB::DatabaseRevision* revision = itr->get(); + if (revision->getFilesAdded()) + { + if (!(revision->getFilesAdded()->getName().empty())) fout<getFilesAdded()->getName()<getFilesRemoved()) + { + if (!(revision->getFilesRemoved()->getName().empty())) fout<getFilesRemoved()->getName()<getFilesModified()) + { + if (!(revision->getFilesModified()->getName().empty())) fout<getFilesModified()->getName()<