From eabe2faf7e393a6f150ca4b76d83b05482def5e7 Mon Sep 17 00:00:00 2001 From: Robert Osfield Date: Tue, 28 Aug 2007 14:02:16 +0000 Subject: [PATCH] Added multi-threaded test path --- examples/osgtext/osgtext.cpp | 182 ++++++++++++++++++++++++++++++++++- 1 file changed, 177 insertions(+), 5 deletions(-) diff --git a/examples/osgtext/osgtext.cpp b/examples/osgtext/osgtext.cpp index 63ad5be11..99ab1f333 100644 --- a/examples/osgtext/osgtext.cpp +++ b/examples/osgtext/osgtext.cpp @@ -23,11 +23,14 @@ #include #include +#include #include #include #include #include +#include +#include #include #include @@ -474,13 +477,173 @@ osg::Group* create3DText(const osg::Vec3& center,float radius) return rootNode; } -int main(int , char **) +class UpdateTextOperation : public osg::Operation { - // construct the viewer. - osgViewer::Viewer viewer; +public: - // prepare scene. + UpdateTextOperation(osg::Group* group): + Operation("UpdateTextOperation", true), + _group(group), + _maxNumChildren(20), + _maxNumTextPerGeode(100) { + } + + virtual void operator () (osg::Object* callingObject) + { + // decided which method to call according to whole has called me. + osgViewer::Viewer* viewer = dynamic_cast(callingObject); + + if (viewer) update(); + else load(); + } + + void update() + { + // osg::notify(osg::NOTICE)<<"*** Doing update"< lock(_mutex); + + if (_mergeSubgraph.valid()) + { + _group->addChild(_mergeSubgraph.get()); + + _mergeSubgraph = 0; + + if (_group->getNumChildren()>_maxNumChildren) + { + osg::Geode* geode = dynamic_cast(_group->getChild(0)); + if (geode) + { + _availableSubgraph.push_back(geode); + geode->removeDrawables(0,geode->getNumDrawables()); + } + _group->removeChild(0,1); + } + + _waitOnMergeBlock.release(); + } + } + + void load() + { + + // osg::notify(osg::NOTICE)<<"Doing load"< geode; + { + OpenThreads::ScopedLock lock(_mutex); + if (!_availableSubgraph.empty()) + { + geode = _availableSubgraph.front(); + _availableSubgraph.pop_front(); + } + } + + if (!geode) geode = new osg::Geode; + + for(unsigned int i=0; i<_maxNumTextPerGeode; ++i) + { + osg::Vec3 position(float(rand()) / float(RAND_MAX), float(rand()) / float(RAND_MAX), float(i)/float(_maxNumTextPerGeode)); + + std::string str; + unsigned int _numCharacters = 5; + for(unsigned int ni=0; ni<_numCharacters;++ni) + { + str.push_back(char(32.0 + (float(rand())/float(RAND_MAX))*128.0f)); + } + + osgText::Text* text = new osgText::Text; + text->setDataVariance(osg::Object::DYNAMIC); + text->setPosition(position); + text->setFont("times.ttf"); + text->setText(str); + text->setCharacterSize(0.025f); + text->setAxisAlignment(osgText::Text::SCREEN); + + geode->addDrawable(text); + } + + + { + OpenThreads::ScopedLock lock(_mutex); + _mergeSubgraph = geode; + } + + // osg::notify(osg::NOTICE)<<"Waiting on merge"< > AvailableList; + + unsigned int _maxNumChildren; + unsigned int _maxNumTextPerGeode; + + OpenThreads::Mutex _mutex; + osg::ref_ptr _group; + osg::ref_ptr _mergeSubgraph; + AvailableList _availableSubgraph; + OpenThreads::Block _waitOnMergeBlock; + + unsigned int _counter; + +}; + + +int main(int argc, char** argv) +{ + osg::ArgumentParser arguments(&argc, argv); + + // construct the viewer. + osgViewer::Viewer viewer(arguments); + + osg::ref_ptr operationThread; + osg::ref_ptr updateOperation; + + if (arguments.read("--mt")) + { + // construct a multi-threaded text updating test. + + // create a group to add everything into. + osg::Group* mainGroup = new osg::Group; + + osg::Group* textGroup = new osg::Group; + mainGroup->addChild(textGroup); + + // create the background thread + operationThread = new osg::OperationThread; + + // create the operation that will run in the background and + // sync once per frame with the main viewer loop. + updateOperation = new UpdateTextOperation(textGroup); + + // add the operation to the operation thread and start it. + operationThread->add(updateOperation.get()); + operationThread->startThread(); + + // add the operation to the viewer to sync once per frame. + viewer.addUpdateOperation(updateOperation.get()); + + + // add a unit cube for the text to appear within. + osg::Geode* geode = new osg::Geode; + geode->getOrCreateStateSet()->setAttribute(new osg::PolygonMode(osg::PolygonMode::FRONT_AND_BACK,osg::PolygonMode::LINE)); + geode->addDrawable(new osg::ShapeDrawable(new osg::Box(osg::Vec3(0.5f,0.5f,0.5f),1.0))); + + mainGroup->addChild(geode); + + viewer.setSceneData(mainGroup); + } + else + { + // prepare scene. osg::Vec3 center(0.0f,0.0f,0.0f); float radius = 1.0f; @@ -506,8 +669,17 @@ int main(int , char **) viewer.setSceneData(group); } +#if 0 osgDB::writeNodeFile(*viewer.getSceneData(),"text.osg"); +#endif - return viewer.run(); + viewer.addEventHandler(new osgViewer::StatsHandler()); + + viewer.run(); + + if (operationThread.valid()) + { + operationThread->cancel(); + } }