From b132aed2175ae6d0e42fd67aa01f3379ea21bc1c Mon Sep 17 00:00:00 2001 From: Robert Osfield Date: Mon, 16 Jul 2007 21:39:30 +0000 Subject: [PATCH] Work in progress on support for dynamically reading a master file in a background thread --- examples/osgterrain/osgterrain.cpp | 204 +++++++++++++++++------------ 1 file changed, 123 insertions(+), 81 deletions(-) diff --git a/examples/osgterrain/osgterrain.cpp b/examples/osgterrain/osgterrain.cpp index 6277e1cbd..a03f7d5e0 100644 --- a/examples/osgterrain/osgterrain.cpp +++ b/examples/osgterrain/osgterrain.cpp @@ -53,11 +53,18 @@ class MasterOperation : public osg::Operation { public: + typedef std::set Files; + typedef std::map > FilenameNodeMap; + typedef std::vector< osg::ref_ptr > Nodes; + + MasterOperation(const std::string& filename): Operation("Master reading operation",true), - _filename(filename) {} - - virtual void operator () (osg::Object* object) + _filename(filename) + { + } + + bool readMasterFile(Files& files) const { std::ifstream fin(_filename.c_str()); if (fin) @@ -65,8 +72,8 @@ public: osgDB::Input fr; fr.attach(&fin); - Files files; - + bool readFilename; + while(!fr.eof()) { bool itrAdvanced = false; @@ -75,75 +82,105 @@ public: files.insert(fr[1].getStr()); fr += 2; itrAdvanced = true; + readFilename = true; } - + if (!itrAdvanced) { ++fr; } } - - Files newFiles; - Files removedFiles; - - { - OpenThreads::ScopedLock lock(_mutex); - - for(Files::iterator fitr = files.begin(); - fitr != files.end(); - ++fitr) - { - if (_existingFilenameNodeMap.count(*fitr)==0) newFiles.insert(*fitr); - } - - for(FilenameNodeMap::iterator litr = _existingFilenameNodeMap.begin(); - litr != _existingFilenameNodeMap.end(); - ++litr) - { - if (files.count(litr->first)==0) - { - removedFiles.insert(litr->first); - } - } - } - - // first load the files. - FilenameNodeMap nodesToAdd; - for(Files::iterator nitr = newFiles.begin(); - nitr != newFiles.end(); - ++nitr) - { - osg::notify(osg::NOTICE)<<"loading files "<<*nitr< loadedModel = osgDB::readNodeFile(*nitr); - if (loadedModel.get()) nodesToAdd[*nitr] = loadedModel; - } - - for(Files::iterator ritr = removedFiles.begin(); - ritr != removedFiles.end(); - ++ritr) - { - osg::notify(osg::NOTICE)<<"Removed files "<<*ritr< lock(_mutex); - _nodesToRemove.swap(removedFiles); - _nodesToAdd.swap(nodesToAdd); - } - - // now block so we don't try to load anything till the new data has been merged - // otherwise _existingFilenameNodeMap will get out of sync. - _updatesMergedBlock.block(); - + return readFilename; } + return false; + } + + bool open(osg::Group* group) + { + Files files; + readMasterFile(files); + for(Files::iterator itr = files.begin(); + itr != files.end(); + ++itr) + { + osg::Node* model = osgDB::readNodeFile(*itr); + if (model) + { + osg::notify(osg::NOTICE)<<"open: Loaded file "<<*itr<addChild(model); + _existingFilenameNodeMap[*itr] = model; + } + } + + return true; + } + + + virtual void operator () (osg::Object* object) + { + Files files; + readMasterFile(files); + + Files newFiles; + Files removedFiles; + + { + OpenThreads::ScopedLock lock(_mutex); + + for(Files::iterator fitr = files.begin(); + fitr != files.end(); + ++fitr) + { + if (_existingFilenameNodeMap.count(*fitr)==0) newFiles.insert(*fitr); + } + + for(FilenameNodeMap::iterator litr = _existingFilenameNodeMap.begin(); + litr != _existingFilenameNodeMap.end(); + ++litr) + { + if (files.count(litr->first)==0) + { + removedFiles.insert(litr->first); + } + } + } + + // first load the files. + FilenameNodeMap nodesToAdd; + for(Files::iterator nitr = newFiles.begin(); + nitr != newFiles.end(); + ++nitr) + { + osg::notify(osg::NOTICE)<<"loading files "<<*nitr< loadedModel = osgDB::readNodeFile(*nitr); + if (loadedModel.get()) nodesToAdd[*nitr] = loadedModel; + } + + for(Files::iterator ritr = removedFiles.begin(); + ritr != removedFiles.end(); + ++ritr) + { + osg::notify(osg::NOTICE)<<"Removed files "<<*ritr< lock(_mutex); + _nodesToRemove.swap(removedFiles); + _nodesToAdd.swap(nodesToAdd); + } + + // now block so we don't try to load anything till the new data has been merged + // otherwise _existingFilenameNodeMap will get out of sync. + _updatesMergedBlock.block(); + } void update(osg::Group* scene) { - osg::notify(osg::NOTICE)<<"update"< lock(_mutex); @@ -156,6 +193,8 @@ public: FilenameNodeMap::iterator fnmItr = _existingFilenameNodeMap.find(*itr); if (fnmItr != _existingFilenameNodeMap.end()) { + osg::notify(osg::NOTICE)<<" removing "<<*itr<removeChild(fnmItr->second.get()); _existingFilenameNodeMap.erase(fnmItr); } @@ -187,10 +226,6 @@ public: } - typedef std::set Files; - typedef std::map > FilenameNodeMap; - typedef std::vector< osg::ref_ptr > Nodes; - std::string _filename; OpenThreads::Mutex _mutex; @@ -367,34 +402,41 @@ int main(int argc, char** argv) double y = 0.0; double w = 1.0; double h = 1.0; - - osg::ref_ptr loadedModel = osgDB::readNodeFiles(arguments); - if (!loadedModel.valid()) return 0; - - osg::ref_ptr scene = dynamic_cast(loadedModel.get()); - if (!scene.valid()) + + osg::ref_ptr masterOperation; + std::string masterFilename; + while(arguments.read("-m",masterFilename)) { - scene = new osg::Group; - scene->addChild(loadedModel.get()); + masterOperation = new MasterOperation(masterFilename); } + osg::ref_ptr scene = new osg::Group; + + osg::ref_ptr loadedModel = osgDB::readNodeFiles(arguments); + if (!masterOperation && !loadedModel) return 0; + + if (masterOperation.valid()) masterOperation->open(scene.get()); + if (loadedModel.valid()) scene->addChild(loadedModel.get()); viewer.setSceneData(scene.get()); + viewer.realize(); - osg::ref_ptr operationThread = new osg::OperationThread; - osg::ref_ptr masterOperation = new MasterOperation("master.terrain"); - operationThread->startThread(); - operationThread->add(masterOperation.get()); - + osg::ref_ptr operationThread; + if (masterOperation.valid()) + { + operationThread = new osg::OperationThread; + operationThread->startThread(); + operationThread->add(masterOperation.get()); + } + while (!viewer.done()) { viewer.advance(); - viewer.eventTraversal(); viewer.updateTraversal(); - masterOperation->update(scene.get()); + if () masterOperation->update(scene.get()); viewer.frame(); }