diff --git a/plugins/core-plugin.cc b/plugins/core-plugin.cc index cfd302e..0881d85 100644 --- a/plugins/core-plugin.cc +++ b/plugins/core-plugin.cc @@ -151,10 +151,14 @@ namespace clap { bool CorePlugin::guiCreate(const char *api, bool isFloating) noexcept { _guiFactory = LocalGuiFactory::getInstance(); - if (!_guiFactory) + if (_guiFactory) { + _guiHandle = _guiFactory->createGui(*this); + } else { _guiFactory = ThreadedGuiFactory::getInstance(); - - _guiHandle = _guiFactory->createGui(*this); + if (!_threadedGuiListenerProxy) + _threadedGuiListenerProxy = std::make_unique(*this); + _guiHandle = _guiFactory->createGui(*_threadedGuiListenerProxy); + } if (!_guiHandle) return false; @@ -282,6 +286,10 @@ namespace clap { //---------------------// // AbstractGuiListener // //---------------------// + void CorePlugin::onGuiRunOnMainThread(std::function callback) { + runOnMainThread(std::move(callback)); + } + void CorePlugin::onGuiPoll() { _pluginToGuiQueue.consume([this](clap_id paramId, const CorePlugin::PluginToGuiValue &value) { _guiHandle->gui().updateParameter(paramId, value.value, value.mod); diff --git a/plugins/core-plugin.hh b/plugins/core-plugin.hh index 2d259a4..c1e60a4 100644 --- a/plugins/core-plugin.hh +++ b/plugins/core-plugin.hh @@ -10,6 +10,7 @@ #include "context.hh" #include "gui/abstract-gui-factory.hh" #include "gui/abstract-gui-listener.hh" +#include "gui/threaded-gui-listener-proxy.hh" #include "intrusive-list.hh" #include "parameters.hh" #include "path-provider.hh" @@ -171,6 +172,7 @@ namespace clap { //---------------------// // AbstractGuiListener // //---------------------// + void onGuiRunOnMainThread(std::function callback) override; void onGuiPoll() override; void pollVoiceInfo(); void onGuiParamBeginAdjust(clap_id paramId) override; @@ -314,5 +316,7 @@ namespace clap { bool _canRedo{false}; std::optional _undoName; std::optional _redoName; + + std::unique_ptr _threadedGuiListenerProxy; }; } // namespace clap \ No newline at end of file diff --git a/plugins/gui/CMakeLists.txt b/plugins/gui/CMakeLists.txt index 0810e65..30abe7c 100644 --- a/plugins/gui/CMakeLists.txt +++ b/plugins/gui/CMakeLists.txt @@ -47,6 +47,8 @@ add_library( threaded-gui-factory.cc threaded-gui-proxy.hh threaded-gui-proxy.cc + threaded-gui-listener-proxy.hh + threaded-gui-listener-proxy.cc timer.hh timer.cc cf-timer.hh diff --git a/plugins/gui/abstract-gui-listener.hh b/plugins/gui/abstract-gui-listener.hh index b94ecae..be1e14b 100644 --- a/plugins/gui/abstract-gui-listener.hh +++ b/plugins/gui/abstract-gui-listener.hh @@ -3,6 +3,7 @@ #include #include #include +#include #include @@ -17,6 +18,8 @@ namespace clap { public: virtual ~AbstractGuiListener(); + virtual void onGuiRunOnMainThread(std::function callback) = 0; + // timer based polling of new parameter changes, transport value, ... // the plugin shall transmit them via virtual void onGuiPoll() = 0; diff --git a/plugins/gui/threaded-gui-listener-proxy.cc b/plugins/gui/threaded-gui-listener-proxy.cc new file mode 100644 index 0000000..6c85da7 --- /dev/null +++ b/plugins/gui/threaded-gui-listener-proxy.cc @@ -0,0 +1,48 @@ +#include "threaded-gui-listener-proxy.hh" + +namespace clap { + ThreadedGuiListenerProxy::ThreadedGuiListenerProxy(AbstractGuiListener &guiListener) + : _guiListener(guiListener) {} + + void ThreadedGuiListenerProxy::onGuiRunOnMainThread(std::function callback) { + _guiListener.onGuiRunOnMainThread(std::move(callback)); + } + + void ThreadedGuiListenerProxy::onGuiPoll() { + onGuiRunOnMainThread([this] { _guiListener.onGuiPoll(); }); + } + + void ThreadedGuiListenerProxy::onGuiParamBeginAdjust(clap_id paramId) { + onGuiRunOnMainThread([this, paramId] { _guiListener.onGuiParamBeginAdjust(paramId); }); + } + + void ThreadedGuiListenerProxy::onGuiParamAdjust(clap_id paramId, double value) { + onGuiRunOnMainThread([this, paramId, value] { _guiListener.onGuiParamAdjust(paramId, value); }); + } + + void ThreadedGuiListenerProxy::onGuiParamEndAdjust(clap_id paramId) { + onGuiRunOnMainThread([this, paramId] { _guiListener.onGuiParamEndAdjust(paramId); }); + } + + void ThreadedGuiListenerProxy::onGuiSetTransportIsSubscribed(bool isSubscribed) { + onGuiRunOnMainThread( + [this, isSubscribed] { _guiListener.onGuiSetTransportIsSubscribed(isSubscribed); }); + } + + void ThreadedGuiListenerProxy::onGuiWindowClosed(bool wasDestroyed) { + onGuiRunOnMainThread([this, wasDestroyed] { _guiListener.onGuiWindowClosed(wasDestroyed); }); + } + + void ThreadedGuiListenerProxy::onGuiUndo() { + onGuiRunOnMainThread([this] { _guiListener.onGuiUndo(); }); + } + + void ThreadedGuiListenerProxy::onGuiRedo() { + onGuiRunOnMainThread([this] { _guiListener.onGuiRedo(); }); + } + + void ThreadedGuiListenerProxy::onGuiInvoke(const std::string &method, + const InvocationArgumentsType &args) { + onGuiRunOnMainThread([this, method, args] { _guiListener.onGuiInvoke(method, args); }); + } +} // namespace clap \ No newline at end of file diff --git a/plugins/gui/threaded-gui-listener-proxy.hh b/plugins/gui/threaded-gui-listener-proxy.hh new file mode 100644 index 0000000..2dc46fc --- /dev/null +++ b/plugins/gui/threaded-gui-listener-proxy.hh @@ -0,0 +1,30 @@ +#pragma once + +#include "abstract-gui-listener.hh" + +namespace clap { + class ThreadedGuiListenerProxy final : public AbstractGuiListener { + public: + ThreadedGuiListenerProxy(AbstractGuiListener &guiListener); + + void onGuiRunOnMainThread(std::function callback) override; + + void onGuiPoll() override; + + void onGuiParamBeginAdjust(clap_id paramId) override; + void onGuiParamAdjust(clap_id paramId, double value) override; + void onGuiParamEndAdjust(clap_id paramId) override; + + void onGuiSetTransportIsSubscribed(bool isSubscribed) override; + + void onGuiWindowClosed(bool wasDestroyed) override; + + void onGuiUndo() override; + void onGuiRedo() override; + + void onGuiInvoke(const std::string &method, const InvocationArgumentsType &args) override; + + private: + AbstractGuiListener &_guiListener; + }; +} // namespace clap \ No newline at end of file