Show
Ignore:
Timestamp:
08/28/07 16:02:16 (7 years ago)
Author:
robert
Message:

Added multi-threaded test path

Files:
1 modified

Legend:

Unmodified
Added
Removed
  • OpenSceneGraph/trunk/examples/osgtext/osgtext.cpp

    r6941 r7309  
    2424 
    2525#include <osgViewer/Viewer> 
     26#include <osgViewer/ViewerEventHandlers> 
    2627 
    2728#include <osg/Geode> 
     
    2930#include <osg/ShapeDrawable> 
    3031#include <osg/Sequence> 
     32#include <osg/PolygonMode> 
     33#include <osg/io_utils> 
    3134 
    3235#include <osgText/Font> 
     
    475478} 
    476479 
    477 int main(int , char **) 
     480class UpdateTextOperation : public osg::Operation 
    478481{ 
     482public: 
     483 
     484    UpdateTextOperation(osg::Group* group):         
     485        Operation("UpdateTextOperation", true), 
     486        _group(group), 
     487        _maxNumChildren(20), 
     488        _maxNumTextPerGeode(100) 
     489    { 
     490    } 
     491 
     492    virtual void operator () (osg::Object* callingObject) 
     493    { 
     494        // decided which method to call according to whole has called me. 
     495        osgViewer::Viewer* viewer = dynamic_cast<osgViewer::Viewer*>(callingObject); 
     496 
     497        if (viewer) update(); 
     498        else load(); 
     499    } 
     500     
     501    void update() 
     502    { 
     503        // osg::notify(osg::NOTICE)<<"*** Doing update"<<std::endl; 
     504         
     505        OpenThreads::ScopedLock<OpenThreads::Mutex> lock(_mutex); 
     506         
     507        if (_mergeSubgraph.valid()) 
     508        { 
     509            _group->addChild(_mergeSubgraph.get()); 
     510 
     511            _mergeSubgraph = 0; 
     512 
     513            if (_group->getNumChildren()>_maxNumChildren) 
     514            { 
     515                osg::Geode* geode = dynamic_cast<osg::Geode*>(_group->getChild(0)); 
     516                if (geode) 
     517                { 
     518                    _availableSubgraph.push_back(geode); 
     519                    geode->removeDrawables(0,geode->getNumDrawables()); 
     520                } 
     521                _group->removeChild(0,1); 
     522            } 
     523             
     524            _waitOnMergeBlock.release(); 
     525        }         
     526    } 
     527     
     528    void load() 
     529    { 
     530     
     531        // osg::notify(osg::NOTICE)<<"Doing load"<<std::endl; 
     532 
     533        osg::ref_ptr<osg::Geode> geode; 
     534        { 
     535            OpenThreads::ScopedLock<OpenThreads::Mutex> lock(_mutex); 
     536            if (!_availableSubgraph.empty()) 
     537            { 
     538                geode = _availableSubgraph.front(); 
     539                _availableSubgraph.pop_front(); 
     540            } 
     541        } 
     542         
     543        if (!geode) geode = new osg::Geode; 
     544 
     545        for(unsigned int i=0; i<_maxNumTextPerGeode; ++i) 
     546        { 
     547            osg::Vec3 position(float(rand()) / float(RAND_MAX), float(rand()) / float(RAND_MAX), float(i)/float(_maxNumTextPerGeode)); 
     548 
     549            std::string str; 
     550            unsigned int _numCharacters = 5; 
     551            for(unsigned int ni=0; ni<_numCharacters;++ni) 
     552            { 
     553                str.push_back(char(32.0 + (float(rand())/float(RAND_MAX))*128.0f)); 
     554            } 
     555                         
     556            osgText::Text* text = new osgText::Text; 
     557            text->setDataVariance(osg::Object::DYNAMIC); 
     558            text->setPosition(position); 
     559            text->setFont("times.ttf"); 
     560            text->setText(str); 
     561            text->setCharacterSize(0.025f); 
     562            text->setAxisAlignment(osgText::Text::SCREEN); 
     563             
     564            geode->addDrawable(text); 
     565        } 
     566 
     567 
     568        {         
     569            OpenThreads::ScopedLock<OpenThreads::Mutex> lock(_mutex); 
     570            _mergeSubgraph = geode; 
     571        } 
     572         
     573        // osg::notify(osg::NOTICE)<<"Waiting on merge"<<std::endl; 
     574 
     575        _waitOnMergeBlock.block(); 
     576 
     577    } 
     578     
     579    virtual void release() 
     580    { 
     581        _waitOnMergeBlock.release(); 
     582    } 
     583 
     584    typedef std::list< osg::ref_ptr<osg::Geode> > AvailableList; 
     585 
     586    unsigned int                _maxNumChildren; 
     587    unsigned int                _maxNumTextPerGeode; 
     588     
     589    OpenThreads::Mutex          _mutex; 
     590    osg::ref_ptr<osg::Group>    _group; 
     591    osg::ref_ptr<osg::Geode>    _mergeSubgraph; 
     592    AvailableList               _availableSubgraph; 
     593    OpenThreads::Block          _waitOnMergeBlock; 
     594     
     595    unsigned int                _counter; 
     596 
     597}; 
     598 
     599 
     600int main(int argc, char** argv) 
     601{ 
     602    osg::ArgumentParser arguments(&argc, argv); 
     603 
    479604    // construct the viewer. 
    480     osgViewer::Viewer viewer; 
    481  
    482     // prepare scene. 
    483     { 
     605    osgViewer::Viewer viewer(arguments); 
     606 
     607    osg::ref_ptr<osg::OperationThread> operationThread; 
     608    osg::ref_ptr<UpdateTextOperation> updateOperation; 
     609 
     610    if (arguments.read("--mt")) 
     611    { 
     612        // construct a multi-threaded text updating test. 
     613         
     614        // create a group to add everything into. 
     615        osg::Group* mainGroup = new osg::Group; 
     616 
     617        osg::Group* textGroup = new osg::Group; 
     618        mainGroup->addChild(textGroup); 
     619 
     620        // create the background thread 
     621        operationThread = new osg::OperationThread; 
     622         
     623        // create the operation that will run in the background and 
     624        // sync once per frame with the main viewer loop. 
     625        updateOperation = new UpdateTextOperation(textGroup); 
     626         
     627        // add the operation to the operation thread and start it. 
     628        operationThread->add(updateOperation.get()); 
     629        operationThread->startThread(); 
     630         
     631        // add the operation to the viewer to sync once per frame. 
     632        viewer.addUpdateOperation(updateOperation.get()); 
     633 
     634 
     635        // add a unit cube for the text to appear within. 
     636        osg::Geode* geode = new osg::Geode; 
     637        geode->getOrCreateStateSet()->setAttribute(new osg::PolygonMode(osg::PolygonMode::FRONT_AND_BACK,osg::PolygonMode::LINE)); 
     638        geode->addDrawable(new osg::ShapeDrawable(new osg::Box(osg::Vec3(0.5f,0.5f,0.5f),1.0))); 
     639 
     640        mainGroup->addChild(geode); 
     641         
     642        viewer.setSceneData(mainGroup);         
     643    } 
     644    else 
     645    { 
     646        // prepare scene. 
    484647        osg::Vec3 center(0.0f,0.0f,0.0f); 
    485648        float radius = 1.0f; 
     
    507670    } 
    508671 
     672#if 0 
    509673    osgDB::writeNodeFile(*viewer.getSceneData(),"text.osg"); 
    510  
    511     return viewer.run(); 
     674#endif 
     675 
     676    viewer.addEventHandler(new osgViewer::StatsHandler()); 
     677 
     678    viewer.run(); 
     679     
     680    if (operationThread.valid()) 
     681    { 
     682        operationThread->cancel(); 
     683    } 
    512684} 
    513685