From 089998169de3efeb81786393b0898d0c94e4e7e2 Mon Sep 17 00:00:00 2001 From: Joseph Mirabel <jmirabel@laas.fr> Date: Sat, 9 Feb 2019 17:52:55 +0100 Subject: [PATCH] Add WindowsManager::refresh and provide asynchronous refresh. --- idl/gepetto/viewer/graphical-interface.idl | 5 ++ include/gepetto/gui/windows-manager.hh | 13 ++++- src/graphical-interface.impl.cpp | 2 + src/graphical-interface.impl.hh | 1 + src/gui/windows-manager.cc | 63 ++++++++++++++++++++++ 5 files changed, 82 insertions(+), 2 deletions(-) diff --git a/idl/gepetto/viewer/graphical-interface.idl b/idl/gepetto/viewer/graphical-interface.idl index 782ec99..2fc2306 100644 --- a/idl/gepetto/viewer/graphical-interface.idl +++ b/idl/gepetto/viewer/graphical-interface.idl @@ -351,6 +351,11 @@ typedef sequence<Transform> TransformSeq; /// Change configurations according to the last applyConfigurations.d void refresh() raises (Error); + + /// Set to false if you do not want refresh to be synchronized + /// with the rendering loop. + /// \note This is an experimental features. + void setRefreshIsSynchronous (in boolean synchonous) raises (Error); /// Return the Position + Quaternion orientation of an object in the global frame /// \param input nodeName : name of the node. diff --git a/include/gepetto/gui/windows-manager.hh b/include/gepetto/gui/windows-manager.hh index 1b3eaf6..080e406 100644 --- a/include/gepetto/gui/windows-manager.hh +++ b/include/gepetto/gui/windows-manager.hh @@ -54,8 +54,13 @@ namespace gepetto { const std::string& extension); bool stopCapture (const WindowID windowId); - public slots: - int createWindow(QString windowName); + void refresh (); + void setRefreshIsSynchronous (bool synchonous); + + public slots: + int createWindow(QString windowName); + void asyncRefresh (); + protected: WindowsManager (BodyTreeWidget* bodyTree); @@ -75,6 +80,10 @@ namespace gepetto { void deleteBodyItem(const std::string& nodeName); std::vector<OSGWidget*> widgets_; + + bool refreshIsSynchronous_; + graphics::Mutex configsAsyncMtx_; + NodeConfigurations_t configsAsync_; }; } // namespace gui } // namespace gepetto diff --git a/src/graphical-interface.impl.cpp b/src/graphical-interface.impl.cpp index 6ee2959..eb1b01c 100644 --- a/src/graphical-interface.impl.cpp +++ b/src/graphical-interface.impl.cpp @@ -292,6 +292,8 @@ namespace graphics { BIND_TO_WINDOWS_MANAGER_0(VOID, refresh) + BIND_TO_WINDOWS_MANAGER_1(VOID, setRefreshIsSynchronous, BOOL) + BIND_TO_WINDOWS_MANAGER_1(VOID, createScene, STRING) BIND_TO_WINDOWS_MANAGER_1(VOID, createSceneWithFloor, STRING) diff --git a/src/graphical-interface.impl.hh b/src/graphical-interface.impl.hh index 68968fa..3b70e61 100644 --- a/src/graphical-interface.impl.hh +++ b/src/graphical-interface.impl.hh @@ -56,6 +56,7 @@ public: virtual Names_t* getWindowList() throw (Error); virtual void refresh() throw (Error); + virtual void setRefreshIsSynchronous(bool synchronous) throw (Error); virtual WindowID createWindow(const char* windowNameCorba) throw (Error); virtual WindowID getWindowID (const char* windowNameCorba) throw (Error); diff --git a/src/gui/windows-manager.cc b/src/gui/windows-manager.cc index b0fffac..1589747 100644 --- a/src/gui/windows-manager.cc +++ b/src/gui/windows-manager.cc @@ -26,6 +26,8 @@ namespace gepetto { namespace gui { + using graphics::ScopedLock; + Qt::ConnectionType connectionType (QObject* o, int blocking) { if (o->thread() == QThread::currentThread()) @@ -72,6 +74,7 @@ namespace gepetto { WindowsManager::WindowsManager(BodyTreeWidget* bodyTree) : Parent_t () , bodyTree_ (bodyTree) + , refreshIsSynchronous_ (true) { } @@ -244,5 +247,65 @@ namespace gepetto { Q_RETURN_ARG (bool, res)); return res; } + + struct ApplyConfigurationFunctor + { + void operator() (const graphics::NodeConfiguration& nc) const + { + nc.node->applyConfiguration ( nc.position, nc.quat); + } + }; + + void WindowsManager::refresh () + { + if (refreshIsSynchronous_) { + { + ScopedLock lock(configListMtx_); + { + ScopedLock lock(osgFrameMutex()); + //refresh scene with the new configuration + std::for_each(newNodeConfigurations_.begin(), + newNodeConfigurations_.end(), ApplyConfigurationFunctor()); + } + newNodeConfigurations_.resize (0); + } + if (autoCaptureTransform_) captureTransform (); + } else { + { + ScopedLock lock1(configsAsyncMtx_); + ScopedLock lock2(configListMtx_); + if (configsAsync_.size() == 0) { + configsAsync_.swap (newNodeConfigurations_); + QMetaObject::invokeMethod (this, "asyncRefresh", Qt::QueuedConnection); + } else { + configsAsync_.insert (configsAsync_.end(), + newNodeConfigurations_.begin(), + newNodeConfigurations_.end()); + newNodeConfigurations_.resize(0); + // No need to reinvoke asyncRefresh as it hasn't been ran yet. + } + } + } + } + + void WindowsManager::asyncRefresh () + { + NodeConfigurations_t& cfgs = configsAsync_; + { + ScopedLock lock(configsAsyncMtx_); + { + ScopedLock lock(osgFrameMutex()); + //refresh scene with the new configuration + std::for_each(cfgs.begin(), cfgs.end(), ApplyConfigurationFunctor()); + } + cfgs.resize (0); + } + if (autoCaptureTransform_) captureTransform (); + } + + void WindowsManager::setRefreshIsSynchronous (bool synchonous) + { + refreshIsSynchronous_ = synchonous; + } } // namespace gui } // namespace gepetto -- GitLab