From 85fb3a2588092285d379895fab10cfe599433b67 Mon Sep 17 00:00:00 2001 From: Robbert van der Helm Date: Mon, 25 May 2020 15:03:03 +0200 Subject: [PATCH] Conditionally disiable the message loop from Based on a function. This is needed because the message loop should be skipped while any of the plugins is opening their GUI, similar to how `EditorOpening` worked for individually hosted plugins. --- src/wine-host/bridges/vst2.cpp | 37 ---------------------------- src/wine-host/bridges/vst2.h | 44 +++++++++++++++++++++++++++++++++- 2 files changed, 43 insertions(+), 38 deletions(-) diff --git a/src/wine-host/bridges/vst2.cpp b/src/wine-host/bridges/vst2.cpp index 1f6b1a21..56763662 100644 --- a/src/wine-host/bridges/vst2.cpp +++ b/src/wine-host/bridges/vst2.cpp @@ -19,9 +19,6 @@ #include #include -#include "../../common/communication.h" -#include "../../common/events.h" - /** * A function pointer to what should be the entry point of a VST plugin. */ @@ -163,40 +160,6 @@ void Vst2Bridge::handle_dispatch() { } } -void Vst2Bridge::handle_dispatch(boost::asio::io_context& main_context) { - using namespace std::placeholders; - - // This works exactly the same as the function above, but execute the actual - // event and run the message loop from the main thread that's also - // instantiating these plugins. This is required for a few plugins to run - // multiple instances in the same process - try { - while (true) { - receive_event( - host_vst_dispatch, std::nullopt, - passthrough_event( - plugin, - [&](AEffect* plugin, int opcode, int index, intptr_t value, - void* data, float option) -> intptr_t { - std::promise dispatch_result; - boost::asio::dispatch(main_context, [&]() { - const intptr_t result = dispatch_wrapper( - plugin, opcode, index, value, data, option); - - dispatch_result.set_value(result); - }); - - return dispatch_result.get_future().get(); - })); - - boost::asio::post(main_context, [&]() { pump_message_loop(); }); - } - } catch (const boost::system::system_error&) { - // The plugin has cut off communications, so we can shut down this host - // application - } -} - void Vst2Bridge::handle_dispatch_midi_events() { try { while (true) { diff --git a/src/wine-host/bridges/vst2.h b/src/wine-host/bridges/vst2.h index d86a6338..44128c7f 100644 --- a/src/wine-host/bridges/vst2.h +++ b/src/wine-host/bridges/vst2.h @@ -26,9 +26,13 @@ #include #include +#include #include +#include #include +#include "../../common/communication.h" +#include "../../common/events.h" #include "../../common/logging.h" #include "../editor.h" #include "../utils.h" @@ -93,11 +97,49 @@ class Vst2Bridge { * * @param main_context The main IO context that's handling the event * handling for all plugins. + * @param message_loop_blocked A function that returns true if the message + * loop is blocked. This is used to temporarily postpone running the + * message loop while a plugin is opening its GUI. * * @note With this approach you'll have to make sure that the object was * instantiated from the same thread as the one that runs the IO context. */ - void handle_dispatch(boost::asio::io_context& main_context); + template + void handle_dispatch(boost::asio::io_context& main_context, + const F& message_loop_blocked) { + // This works exactly the same as the function above, but execute the + // actual event and run the message loop from the main thread that's + // also instantiating these plugins. This is required for a few plugins + // to run multiple instances in the same process + try { + while (true) { + receive_event( + host_vst_dispatch, std::nullopt, + passthrough_event( + plugin, + [&](AEffect* plugin, int opcode, int index, + intptr_t value, void* data, + float option) -> intptr_t { + std::promise dispatch_result; + boost::asio::dispatch(main_context, [&]() { + const intptr_t result = dispatch_wrapper( + plugin, opcode, index, value, data, option); + + dispatch_result.set_value(result); + + if (!message_loop_blocked()) { + pump_message_loop(); + } + }); + + return dispatch_result.get_future().get(); + })); + } + } catch (const boost::system::system_error&) { + // The plugin has cut off communications, so we can shut down this + // host application + } + } // These functions are the entry points for the `*_handler` threads // defined below. They're defined here because we can't use lambdas with