Example #1
0
void Timeout::traverse(osg::NodeVisitor& nv)
{
    if (nv.getVisitorType()==osg::NodeVisitor::CULL_VISITOR)
    {
        osgUtil::CullVisitor* cv = dynamic_cast<osgUtil::CullVisitor*>(&nv);
        if (_displayTimeout && cv)
        {
            osgUtil::RenderStage* previous_stage = cv->getCurrentRenderBin()->getStage();

            osg::ref_ptr<osgUtil::RenderStage> rs = new osgUtil::RenderStage;

            osg::ColorMask* colorMask = previous_stage->getColorMask();
            rs->setColorMask(colorMask);

            // set up the viewport.
            osg::Viewport* viewport = previous_stage->getViewport();
            rs->setViewport( viewport );

            rs->setClearMask(GL_DEPTH_BUFFER_BIT);

            // record the render bin, to be restored after creation
            // of the render to text
            osgUtil::RenderBin* previousRenderBin = cv->getCurrentRenderBin();

            // set the current renderbin to be the newly created stage.
            cv->setCurrentRenderBin(rs.get());

            // traverse the subgraph
            {
                Transform::traverse(nv);
            }

            // restore the previous renderbin.
            cv->setCurrentRenderBin(previousRenderBin);

            // and the render to texture stage to the current stages
            // dependancy list.
            cv->getCurrentRenderBin()->getStage()->addPostRenderStage(rs.get(),0);
        }
    }
    else if (nv.getVisitorType()==osg::NodeVisitor::EVENT_VISITOR)
    {
        int deltaFrameNumber = (nv.getFrameStamp()->getFrameNumber()-_previousFrameNumber);
        _previousFrameNumber = nv.getFrameStamp()->getFrameNumber();

        bool needToRecordEventTime = false;
        bool needToAction = false;

        if (deltaFrameNumber>1)
        {
            needToRecordEventTime = true;
        }

        bool previous_displayTimeout = _displayTimeout;
        bool needToDismiss = false;

        osgGA::EventVisitor* ev = dynamic_cast<osgGA::EventVisitor*>(&nv);
        osgViewer::Viewer* viewer = ev ? dynamic_cast<osgViewer::Viewer*>(ev->getActionAdapter()) : 0;
        if (ev)
        {
            osgGA::EventQueue::Events& events = ev->getEvents();
            for(osgGA::EventQueue::Events::iterator itr = events.begin();
                itr != events.end();
                ++itr)
            {
                osgGA::GUIEventAdapter* event = itr->get();

                bool keyEvent = event->getEventType()==osgGA::GUIEventAdapter::KEYDOWN ||  event->getEventType()==osgGA::GUIEventAdapter::KEYUP;

                if (keyEvent && event->getKey()==_keyStartsTimoutDisplay)
                {
                    OSG_NOTICE<<"_keyStartsTimoutDisplay pressed"<<std::endl;
                    _displayTimeout = true;
                }
                else if (keyEvent && event->getKey()==_keyDismissTimoutDisplay)
                {
                    OSG_NOTICE<<"_keyDismissTimoutDisplay pressed"<<std::endl;
                    needToRecordEventTime = true;
                    needToDismiss = _displayTimeout;
                    _displayTimeout = false;
                }
                else if (keyEvent && event->getKey()==_keyRunTimeoutAction)
                {
                    OSG_NOTICE<<"_keyRunTimeoutAction pressed"<<std::endl;
                    _displayTimeout = false;
                    needToRecordEventTime = true;
                    needToAction = true;
                }
                else if (event->getEventType()!=osgGA::GUIEventAdapter::FRAME)
                {
                    needToRecordEventTime = true;
                    needToDismiss = _displayTimeout;
                    _displayTimeout = false;
                }
            }
        }
        

        if (needToRecordEventTime)
        {
            _timeOfLastEvent = nv.getFrameStamp()->getReferenceTime();
        }
        
        double timeSinceLastEvent = nv.getFrameStamp() ? nv.getFrameStamp()->getReferenceTime()-_timeOfLastEvent : 0.0;

        if (timeSinceLastEvent>_idleDurationBeforeTimeoutDisplay)
        {
            _displayTimeout = true;
        }

        if (timeSinceLastEvent>_idleDurationBeforeTimeoutAction)
        {
            _displayTimeout = false;
            needToAction = true;
            needToDismiss = false;
        }

        if (!previous_displayTimeout && _displayTimeout)
        {
            if (viewer && (_displayBroadcastKeyPos._key!=0 || _displayBroadcastKeyPos._x!=FLT_MAX || _displayBroadcastKeyPos._y!=FLT_MAX))
            {
                OSG_NOTICE<<"Doing display broadcast key event"<<_displayBroadcastKeyPos._key<<std::endl;
                broadcastEvent(viewer, _displayBroadcastKeyPos);
            }

            OperationVisitor leave(OperationVisitor::ENTER);
            accept(leave);

            if (leave.sleepTime()!=0.0)
            {
                OSG_NOTICE<<"Pausing for "<<leave.sleepTime()<<std::endl;
                OpenThreads::Thread::microSleep(static_cast<unsigned int>(1000000.0*leave.sleepTime()));
                OSG_NOTICE<<"Finished Pause "<<std::endl;
            }

        }


        if (needToDismiss)
        {
            if (viewer && (_dismissBroadcastKeyPos._key!=0 || _dismissBroadcastKeyPos._x!=FLT_MAX || _dismissBroadcastKeyPos._y!=FLT_MAX))
            {
                OSG_NOTICE<<"Doing dismiss broadcast key event"<<_dismissBroadcastKeyPos._key<<std::endl;
                broadcastEvent(viewer, _dismissBroadcastKeyPos);
            }

            OperationVisitor leave(OperationVisitor::LEAVE);
            accept(leave);
        }

        Transform::traverse(nv);


        if (needToAction)
        {
            OSG_NOTICE<<"Do timeout action"<<std::endl;
            _previousFrameNumber = -1;
            _timeOfLastEvent = nv.getFrameStamp()->getReferenceTime();


            if (_actionJumpData.requiresJump())
            {
                OSG_NOTICE<<"Doing timeout jump"<<std::endl;
                _actionJumpData.jump(SlideEventHandler::instance());
            }

            if (_actionKeyPos._key!=0 || _actionKeyPos._x!=FLT_MAX || _actionKeyPos._y!=FLT_MAX)
            {
                OSG_NOTICE<<"Doing timeout key event"<<_actionKeyPos._key<<std::endl;
                if (SlideEventHandler::instance()) SlideEventHandler::instance()->dispatchEvent(_actionKeyPos);
            }

            if (viewer && (_actionBroadcastKeyPos._key!=0 || _actionBroadcastKeyPos._x!=FLT_MAX || _actionBroadcastKeyPos._y!=FLT_MAX))
            {
                OSG_NOTICE<<"Doing timeout broadcast key event"<<_actionBroadcastKeyPos._key<<std::endl;
                broadcastEvent(viewer, _actionBroadcastKeyPos);
            }
            
        }
        
    }
    else if (nv.getVisitorType()==osg::NodeVisitor::UPDATE_VISITOR)
    {
        if (_displayTimeout) Transform::traverse(nv);
    }
    else
    {
        if (strcmp(nv.className(),"FindOperatorsVisitor")==0)
        {
            OSG_NOTICE<<"Timout::traverse() "<<nv.className()<<", ignoring traversal"<<std::endl;            
        }
        else
        {
            Transform::traverse(nv);
        }
    }


    
}