diff --git a/include/osgGA/Device b/include/osgGA/Device index fa9f59392..d7cfc4df7 100644 --- a/include/osgGA/Device +++ b/include/osgGA/Device @@ -37,7 +37,7 @@ class OSGGA_EXPORT Device : public osg::Object int getCapabilities() const { return _capabilities; } - virtual void checkEvents() {}; + virtual bool checkEvents() { return _eventQueue.valid() ? !(getEventQueue()->empty()) : false; } virtual void sendEvent(const GUIEventAdapter& ea); virtual void sendEvents(const EventQueue::Events& events); diff --git a/include/osgGA/EventQueue b/include/osgGA/EventQueue index 613c7689e..4edeaeb13 100644 --- a/include/osgGA/EventQueue +++ b/include/osgGA/EventQueue @@ -35,6 +35,12 @@ class OSGGA_EXPORT EventQueue : public osg::Referenced typedef std::list< osg::ref_ptr > Events; + bool empty() const + { + OpenThreads::ScopedLock lock(_eventQueueMutex); + return _eventQueue.empty(); + } + /** Set events.*/ void setEvents(Events& events); diff --git a/include/osgViewer/CompositeViewer b/include/osgViewer/CompositeViewer index bd7380866..c46946f75 100644 --- a/include/osgViewer/CompositeViewer +++ b/include/osgViewer/CompositeViewer @@ -87,6 +87,9 @@ class OSGVIEWER_EXPORT CompositeViewer : public ViewerBase /** Check to see if the new frame is required, called by run() when FrameScheme is set to ON_DEMAND.*/ virtual bool checkNeedToDoFrame(); + /** check to see if events have been received, return true if events are now available.*/ + virtual bool checkEvents(); + virtual void advance(double simulationTime=USE_REFERENCE_TIME); virtual void eventTraversal(); diff --git a/include/osgViewer/GraphicsWindow b/include/osgViewer/GraphicsWindow index 6d1593e54..c0bef15e3 100644 --- a/include/osgViewer/GraphicsWindow +++ b/include/osgViewer/GraphicsWindow @@ -53,7 +53,8 @@ class OSGVIEWER_EXPORT GraphicsWindow : public osg::GraphicsContext, public osgG osgGA::EventQueue* getEventQueue() { return _eventQueue.get(); } const osgGA::EventQueue* getEventQueue() const { return _eventQueue.get(); } - virtual void checkEvents() {} + /** Check events, return true if events have been received.*/ + virtual bool checkEvents() { return false; } /** Set the window's position and size.*/ void setWindowRectangle(int x, int y, int width, int height) diff --git a/include/osgViewer/View b/include/osgViewer/View index b9de2ee52..a2955ed34 100644 --- a/include/osgViewer/View +++ b/include/osgViewer/View @@ -320,7 +320,7 @@ class OSGVIEWER_EXPORT View : public osg::View, public osgGA::GUIActionAdapter osg::Timer_t _startTick; - Devices _eventSources; + Devices _eventSources; osg::ref_ptr _scene; osg::ref_ptr _eventQueue; diff --git a/include/osgViewer/Viewer b/include/osgViewer/Viewer index 32958e88f..ca5bc82f4 100644 --- a/include/osgViewer/Viewer +++ b/include/osgViewer/Viewer @@ -87,6 +87,9 @@ class OSGVIEWER_EXPORT Viewer : public ViewerBase, public osgViewer::View /** check to see if the new frame is required, called by run(..) when FrameScheme is set to ON_DEMAND.*/ virtual bool checkNeedToDoFrame(); + /** check to see if events have been received, return true if events are now available.*/ + virtual bool checkEvents(); + virtual void advance(double simulationTime=USE_REFERENCE_TIME); virtual void eventTraversal(); diff --git a/include/osgViewer/ViewerBase b/include/osgViewer/ViewerBase index c6b9e09cd..80d3e5942 100644 --- a/include/osgViewer/ViewerBase +++ b/include/osgViewer/ViewerBase @@ -224,6 +224,9 @@ class OSGVIEWER_EXPORT ViewerBase : public virtual osg::Object /** check to see if the new frame is required, called by run(..) when FrameScheme is set to ON_DEMAND.*/ virtual bool checkNeedToDoFrame() = 0; + + /** check to see if events have been received, return true if events are now available.*/ + virtual bool checkEvents() = 0; /** Render a complete new frame. * Calls advance(), eventTraversal(), updateTraversal(), renderingTraversals(). */ diff --git a/include/osgViewer/api/Carbon/GraphicsWindowCarbon b/include/osgViewer/api/Carbon/GraphicsWindowCarbon index cc138a44b..3dc72d290 100644 --- a/include/osgViewer/api/Carbon/GraphicsWindowCarbon +++ b/include/osgViewer/api/Carbon/GraphicsWindowCarbon @@ -85,7 +85,7 @@ class GraphicsWindowCarbon : public osgViewer::GraphicsWindow, public osgViewer: virtual void swapBuffersImplementation(); /** Check to see if any events have been generated.*/ - virtual void checkEvents(); + virtual bool checkEvents(); /** Set the window's position and size.*/ virtual bool setWindowRectangleImplementation(int x, int y, int width, int height); diff --git a/include/osgViewer/api/Cocoa/GraphicsWindowCocoa b/include/osgViewer/api/Cocoa/GraphicsWindowCocoa index 62908780b..2247a9e71 100644 --- a/include/osgViewer/api/Cocoa/GraphicsWindowCocoa +++ b/include/osgViewer/api/Cocoa/GraphicsWindowCocoa @@ -113,7 +113,7 @@ class GraphicsWindowCocoa : public osgViewer::GraphicsWindow, public osgViewer:: virtual void swapBuffersImplementation(); /** Check to see if any events have been generated.*/ - virtual void checkEvents(); + virtual bool checkEvents(); /** Set Window decoration.*/ virtual bool setWindowDecorationImplementation(bool flag); diff --git a/include/osgViewer/api/IOS/GraphicsWindowIOS b/include/osgViewer/api/IOS/GraphicsWindowIOS index a02a7e13a..5e84b2c5c 100644 --- a/include/osgViewer/api/IOS/GraphicsWindowIOS +++ b/include/osgViewer/api/IOS/GraphicsWindowIOS @@ -109,7 +109,7 @@ class GraphicsWindowIOS : public osgViewer::GraphicsWindow virtual void swapBuffersImplementation(); /** Check to see if any events have been generated.*/ - virtual void checkEvents(); + virtual bool checkEvents(); /** Set Window decoration.*/ virtual bool setWindowDecorationImplementation(bool flag); diff --git a/include/osgViewer/api/Win32/GraphicsWindowWin32 b/include/osgViewer/api/Win32/GraphicsWindowWin32 index f7b7f4f7c..0cf7f7fef 100644 --- a/include/osgViewer/api/Win32/GraphicsWindowWin32 +++ b/include/osgViewer/api/Win32/GraphicsWindowWin32 @@ -58,7 +58,7 @@ class OSGVIEWER_EXPORT GraphicsWindowWin32 : public osgViewer::GraphicsWindow, p virtual void swapBuffersImplementation(); /** Check to see if any events have been generated.*/ - virtual void checkEvents(); + virtual bool checkEvents(); /** Set the window's position and size.*/ virtual bool setWindowRectangleImplementation(int x, int y, int width, int height); diff --git a/include/osgViewer/api/X11/GraphicsWindowX11 b/include/osgViewer/api/X11/GraphicsWindowX11 index 1628b0998..9086bda1e 100644 --- a/include/osgViewer/api/X11/GraphicsWindowX11 +++ b/include/osgViewer/api/X11/GraphicsWindowX11 @@ -97,7 +97,7 @@ class OSGVIEWER_EXPORT GraphicsWindowX11 : public osgViewer::GraphicsWindow, pub virtual void swapBuffersImplementation(); /** Check to see if any events have been generated.*/ - virtual void checkEvents(); + virtual bool checkEvents(); /** Set Window decoration.*/ virtual bool setWindowDecorationImplementation(bool flag); diff --git a/src/osgPlugins/RestHttpDevice/RestHttpDevice.hpp b/src/osgPlugins/RestHttpDevice/RestHttpDevice.hpp index 5c2197148..b0f5f3c89 100755 --- a/src/osgPlugins/RestHttpDevice/RestHttpDevice.hpp +++ b/src/osgPlugins/RestHttpDevice/RestHttpDevice.hpp @@ -169,7 +169,7 @@ public: - virtual void checkEvents() + virtual bool checkEvents() { if ((fabs(_currentMouseX - _targetMouseY) > 0.1f) || (fabs(_currentMouseY - _targetMouseY) > 0.1)) { @@ -178,6 +178,7 @@ public: _currentMouseY = (1.0f - scalar) * _currentMouseY + scalar * _targetMouseY; getEventQueue()->mouseMotion(_currentMouseX, _currentMouseY, getEventQueue()->getTime()); } + return !(getEventQueue()->empty()); } void setTargetMousePosition(float x, float y, bool force = false) diff --git a/src/osgPlugins/ZeroConfDevice/ReaderWriterZeroConfDevice.cpp b/src/osgPlugins/ZeroConfDevice/ReaderWriterZeroConfDevice.cpp index de9e6cc77..e18ff30b8 100755 --- a/src/osgPlugins/ZeroConfDevice/ReaderWriterZeroConfDevice.cpp +++ b/src/osgPlugins/ZeroConfDevice/ReaderWriterZeroConfDevice.cpp @@ -37,9 +37,10 @@ public: _autoDiscovery->registerService(type, port); } - virtual void checkEvents() + virtual bool checkEvents() { _autoDiscovery->update(); + return !(getEventQueue()->empty()); } virtual void sendEvent(const osgGA::GUIEventAdapter& event) @@ -72,9 +73,10 @@ class ZeroConfDiscoverDevice : public osgGA::Device { public: ZeroConfDiscoverDevice(const std::string& type); - virtual void checkEvents() + virtual bool checkEvents() { _autoDiscovery->update(); + return !(getEventQueue()->empty()); } private: diff --git a/src/osgPlugins/osc/OscReceivingDevice.hpp b/src/osgPlugins/osc/OscReceivingDevice.hpp index b994fea4e..33ef33c4c 100755 --- a/src/osgPlugins/osc/OscReceivingDevice.hpp +++ b/src/osgPlugins/osc/OscReceivingDevice.hpp @@ -71,7 +71,6 @@ public: ~OscReceivingDevice(); - virtual void checkEvents() {} virtual void run(); diff --git a/src/osgPlugins/sdl/JoystickDevice.cpp b/src/osgPlugins/sdl/JoystickDevice.cpp index 2369cff7a..307c1e55c 100644 --- a/src/osgPlugins/sdl/JoystickDevice.cpp +++ b/src/osgPlugins/sdl/JoystickDevice.cpp @@ -103,7 +103,7 @@ void JoystickDevice::capture(ValueList& axisValues, ValueList& buttonValues) con } } -void JoystickDevice::checkEvents() +bool JoystickDevice::checkEvents() { if (_joystick) { @@ -180,6 +180,6 @@ void JoystickDevice::checkEvents() _buttonValues.swap(newButtonValues); } - + return !(getEventQueue()->empty()); } diff --git a/src/osgPlugins/sdl/JoystickDevice.h b/src/osgPlugins/sdl/JoystickDevice.h index da20ba6a8..b8b7b5f10 100644 --- a/src/osgPlugins/sdl/JoystickDevice.h +++ b/src/osgPlugins/sdl/JoystickDevice.h @@ -31,7 +31,7 @@ class JoystickDevice : public osgGA::Device typedef std::vector ValueList; typedef std::map ButtonMap; - virtual void checkEvents(); + virtual bool checkEvents(); void addMouseButtonMapping(int joystickButton, int mouseButton) { diff --git a/src/osgViewer/CompositeViewer.cpp b/src/osgViewer/CompositeViewer.cpp index 5ac9dcaf8..f0f08311f 100644 --- a/src/osgViewer/CompositeViewer.cpp +++ b/src/osgViewer/CompositeViewer.cpp @@ -266,8 +266,8 @@ bool CompositeViewer::checkNeedToDoFrame() } } - // now do a eventTraversal to see if any events might require a new frame. - eventTraversal(); + // check if events are available and need processing + if (checkEvents()) return true; if (_requestRedraw) return true; if (_requestContinousUpdate) return true; @@ -275,6 +275,44 @@ bool CompositeViewer::checkNeedToDoFrame() return false; } + +bool CompositeViewer::checkEvents() +{ + for(RefViews::iterator itr = _views.begin(); + itr != _views.end(); + ++itr) + { + osgViewer::View* view = itr->get(); + if (view) + { + // check events from any attached sources + for(View::Devices::iterator eitr = view->getDevices().begin(); + eitr != view->getDevices().end(); + ++eitr) + { + osgGA::Device* es = eitr->get(); + if (es->getCapabilities() & osgGA::Device::RECEIVE_EVENTS) + { + if (es->checkEvents()) return true; + } + + } + } + } + + // get events from all windows attached to Viewer. + Windows windows; + getWindows(windows); + for(Windows::iterator witr = windows.begin(); + witr != windows.end(); + ++witr) + { + if ((*witr)->checkEvents()) return true; + } + + return false; +} + int CompositeViewer::run() { for(RefViews::iterator itr = _views.begin(); @@ -874,7 +912,11 @@ void CompositeViewer::eventTraversal() if (_views.empty()) return; +#if 1 + double cutOffTime = _frameStamp->getReferenceTime(); +#else double cutOffTime = (_runFrameScheme==ON_DEMAND) ? DBL_MAX : _frameStamp->getReferenceTime(); +#endif double beginEventTraversal = osg::Timer::instance()->delta_s(_startTick, osg::Timer::instance()->tick()); diff --git a/src/osgViewer/GraphicsWindowCarbon.cpp b/src/osgViewer/GraphicsWindowCarbon.cpp index aec2de60b..f656ca2ef 100644 --- a/src/osgViewer/GraphicsWindowCarbon.cpp +++ b/src/osgViewer/GraphicsWindowCarbon.cpp @@ -844,9 +844,9 @@ bool GraphicsWindowCarbon::handleModifierKeys(EventRef theEvent) -void GraphicsWindowCarbon::checkEvents() +bool GraphicsWindowCarbon::checkEvents() { - if (!_realized) return; + if (!_realized) return false; EventRef theEvent; EventTargetRef theTarget = GetEventDispatcherTarget(); @@ -869,7 +869,7 @@ void GraphicsWindowCarbon::checkEvents() if ((fwres == inMenuBar) && (mouseButton >= 1)) { MenuSelect(wheresMyMouse); HiliteMenu(0); - return; + return !(getEventQueue()->empty()); } break; } @@ -903,6 +903,7 @@ void GraphicsWindowCarbon::checkEvents() s_quit_requested = false; } + return !(getEventQueue()->empty()); } diff --git a/src/osgViewer/GraphicsWindowCocoa.mm b/src/osgViewer/GraphicsWindowCocoa.mm index 2e08601ca..b2801ae5d 100644 --- a/src/osgViewer/GraphicsWindowCocoa.mm +++ b/src/osgViewer/GraphicsWindowCocoa.mm @@ -1327,10 +1327,10 @@ void GraphicsWindowCocoa::swapBuffersImplementation() // checkEvents // process all pending events // ---------------------------------------------------------------------------------------------------------- -void GraphicsWindowCocoa::checkEvents() +bool GraphicsWindowCocoa::checkEvents() { if (!_checkForEvents) - return; + return false; NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init]; @@ -1362,6 +1362,8 @@ void GraphicsWindowCocoa::checkEvents() } [pool release]; + + return !(getEventQueue()->empty()); } diff --git a/src/osgViewer/GraphicsWindowIOS.mm b/src/osgViewer/GraphicsWindowIOS.mm index 0ffacd5e1..c788294fb 100644 --- a/src/osgViewer/GraphicsWindowIOS.mm +++ b/src/osgViewer/GraphicsWindowIOS.mm @@ -1069,10 +1069,10 @@ bool GraphicsWindowIOS::setWindowRectangleImplementation(int x, int y, int width } -void GraphicsWindowIOS::checkEvents() +bool GraphicsWindowIOS::checkEvents() { - - + + return !(getEventQueue()->empty()); } diff --git a/src/osgViewer/GraphicsWindowWin32.cpp b/src/osgViewer/GraphicsWindowWin32.cpp index 21622c1fb..3168fcefd 100644 --- a/src/osgViewer/GraphicsWindowWin32.cpp +++ b/src/osgViewer/GraphicsWindowWin32.cpp @@ -2054,9 +2054,9 @@ void GraphicsWindowWin32::swapBuffersImplementation() } } -void GraphicsWindowWin32::checkEvents() +bool GraphicsWindowWin32::checkEvents() { - if (!_realized) return; + if (!_realized) return false; MSG msg; while (::PeekMessage(&msg, _hwnd, 0, 0, PM_REMOVE)) @@ -2076,6 +2076,8 @@ void GraphicsWindowWin32::checkEvents() _destroyWindow = false; destroyWindow(false); } + + return !(getEventQueue()->empty()); } void GraphicsWindowWin32::grabFocus() diff --git a/src/osgViewer/GraphicsWindowX11.cpp b/src/osgViewer/GraphicsWindowX11.cpp index 08c935d05..d845b62ab 100644 --- a/src/osgViewer/GraphicsWindowX11.cpp +++ b/src/osgViewer/GraphicsWindowX11.cpp @@ -1197,9 +1197,9 @@ void GraphicsWindowX11::swapBuffersImplementation() } } -void GraphicsWindowX11::checkEvents() +bool GraphicsWindowX11::checkEvents() { - if (!_realized) return; + if (!_realized) return false; Display* display = _eventDisplay; @@ -1564,6 +1564,8 @@ void GraphicsWindowX11::checkEvents() requestRedraw(); } } + + return !(getEventQueue()->empty()); } void GraphicsWindowX11::grabFocus() diff --git a/src/osgViewer/Viewer.cpp b/src/osgViewer/Viewer.cpp index 48aa7df7a..e6f47f14b 100644 --- a/src/osgViewer/Viewer.cpp +++ b/src/osgViewer/Viewer.cpp @@ -361,9 +361,9 @@ bool Viewer::checkNeedToDoFrame() if (_camera->getUpdateCallback()) return true; if (getSceneData()!=0 && getSceneData()->getNumChildrenRequiringUpdateTraversal()>0) return true; - // now do a eventTraversal to see if any events might require a new frame. - eventTraversal(); - + // check if events are available and need processing + if (checkEvents()) return true; + // now check if any of the event handles have prompted a redraw. if (_requestRedraw) return true; if (_requestContinousUpdate) return true; @@ -371,6 +371,34 @@ bool Viewer::checkNeedToDoFrame() return false; } +bool Viewer::checkEvents() +{ + // check events from any attached sources + for(Devices::iterator eitr = _eventSources.begin(); + eitr != _eventSources.end(); + ++eitr) + { + osgGA::Device* es = eitr->get(); + if (es->getCapabilities() & osgGA::Device::RECEIVE_EVENTS) + { + if (es->checkEvents()) return true; + } + + } + + // get events from all windows attached to Viewer. + Windows windows; + getWindows(windows); + for(Windows::iterator witr = windows.begin(); + witr != windows.end(); + ++witr) + { + if ((*witr)->checkEvents()) return true; + } + + return false; +} + int Viewer::run() { if (!getCameraManipulator() && getCamera()->getAllowEventFocus()) @@ -798,8 +826,12 @@ void Viewer::eventTraversal() { if (_done) return; +#if 1 + double cutOffTime = _frameStamp->getReferenceTime(); +#else double cutOffTime = (_runFrameScheme==ON_DEMAND) ? DBL_MAX : _frameStamp->getReferenceTime(); - +#endif + double beginEventTraversal = osg::Timer::instance()->delta_s(_startTick, osg::Timer::instance()->tick()); // OSG_NOTICE<<"Viewer::frameEventTraversal()."<