From c2d2ac8fbfa37e1c7a17a073f8fd621fe6b6a030 Mon Sep 17 00:00:00 2001 From: Robbert van der Helm Date: Fri, 4 Dec 2020 00:12:05 +0100 Subject: [PATCH] Inherit Vst3PluginBridge init from PluginBridge --- src/plugin/bridges/common.h | 23 +++++++++++- src/plugin/bridges/vst3.cpp | 56 ++++++++-------------------- src/plugin/bridges/vst3.h | 73 +------------------------------------ 3 files changed, 38 insertions(+), 114 deletions(-) diff --git a/src/plugin/bridges/common.h b/src/plugin/bridges/common.h index c845a2c9..7f217ac4 100644 --- a/src/plugin/bridges/common.h +++ b/src/plugin/bridges/common.h @@ -25,8 +25,9 @@ #include "../host-process.h" /** - * Handles all common operations for hosting plugins such as setting up the - * plugin host process, the logger, and logging debug information on startup. + * Handles all common operations for hosting plugins such as initializing up the + * plugin host process, setting up the logger, and logging debug information on + * startup. * * @tparam Sockets the `Sockets` implementation to use. We have to initialize it * here because we need to pass it to our `HostProcess`. @@ -46,6 +47,12 @@ class PluginBridge { * @param create_socket_instance A function to create a socket instance. * Using a lambda here feels wrong, but I can't think of a better * solution right now. + * + * @tparam F A `TSockets(boost::asio::io_context&)` function to create the + * `TSockets` instance. + * + * @throw std::runtime_error Thrown when the Wine plugin host could not be + * found, or if it could not locate and load a VST3 module. */ template PluginBridge(PluginType plugin_type, @@ -55,6 +62,8 @@ class PluginBridge { plugin_path(plugin_path), io_context(), sockets(create_socket_instance(io_context)), + // This is still correct for VST3 plugins because we can configure an + // entire directory (the module's bundle) at once config(load_config_for(get_this_file_location())), generic_logger(Logger::create_from_environment( create_logger_prefix(sockets.base_dir))), @@ -197,6 +206,16 @@ class PluginBridge { /** * The path to the plugin (`.dll` or module) being loaded in the Wine plugin * host. + * + * Forst VST2 plugins this will be a `.dll` file. For VST3 plugins this is + * normally a directory called `MyPlugin.vst3` that contains + * `MyPlugin.vst3/Contents/x86-win/MyPlugin.vst3`, but there's also an older + * deprecated (but still ubiquitous) format where the top level + * `MyPlugin.vst3` is not a directory but a .dll file. This points to either + * of those things, and then `VST3::Hosting::Win32Module::create()` will be + * able to load it. + * + * https://developer.steinberg.help/pages/viewpage.action?pageId=9798275 */ const boost::filesystem::path plugin_path; diff --git a/src/plugin/bridges/vst3.cpp b/src/plugin/bridges/vst3.cpp index b81e81b4..095f0cd0 100644 --- a/src/plugin/bridges/vst3.cpp +++ b/src/plugin/bridges/vst3.cpp @@ -16,49 +16,23 @@ #include "vst3.h" -#include "../../common/utils.h" - -// TODO: Do all of the initialization stuff from `Vst2PluginBridge` Vst3PluginBridge::Vst3PluginBridge() - : // TODO: This is technically correct because we can configure the entire - // directory at once - config(load_config_for(get_this_file_location())), - // TODO: This is incorrect for VST3 modules - plugin_module_path(find_vst_plugin()), - io_context(), - sockets(io_context, - // TODO: This is incorrect - generate_endpoint_base( - plugin_module_path.filename().replace_extension("").string()), - true), - // This weird cast is not needed, but without it clang/ccls won't shut up - // TODO: Apparently this is UB even though it works fine, so we should - // probably just use composition here instead + : PluginBridge(PluginType::vst3, + // TODO: This is incorrect for VST3 modules + find_vst_plugin(), + [](boost::asio::io_context& io_context) { + return Vst3Sockets( + io_context, + generate_endpoint_base(find_vst_plugin() + .filename() + .replace_extension("") + .string()), + true); + }), + // TODO: This is UB, use composition with `generic_logger` instead logger(static_cast(Logger::create_from_environment( - create_logger_prefix(sockets.base_dir)))), - wine_version(get_wine_version()), - vst_host( - config.group - ? std::unique_ptr(std::make_unique( - io_context, - logger, - HostRequest{.plugin_type = PluginType::vst2, - .plugin_path = plugin_module_path.string(), - .endpoint_base_dir = sockets.base_dir.string()}, - sockets, - *config.group)) - : std::unique_ptr(std::make_unique( - io_context, - logger, - HostRequest{ - .plugin_type = PluginType::vst2, - .plugin_path = plugin_module_path.string(), - .endpoint_base_dir = sockets.base_dir.string()}))), - has_realtime_priority(set_realtime_priority()), - wine_io_handler([&]() { io_context.run(); }) { + create_logger_prefix(sockets.base_dir)))) { log_init_message(); -} -void Vst3PluginBridge::log_init_message() { - // TODO: Move `Vst2PluginBridge::log_init_message()` to utils and call that + // TODO: Call the host guard handler } diff --git a/src/plugin/bridges/vst3.h b/src/plugin/bridges/vst3.h index 106201d2..b1083304 100644 --- a/src/plugin/bridges/vst3.h +++ b/src/plugin/bridges/vst3.h @@ -16,14 +16,11 @@ #pragma once -#include -#include #include #include "../../common/communication/vst3.h" -#include "../../common/configuration.h" #include "../../common/logging/vst3.h" -#include "../host-process.h" +#include "common.h" /** * This handles the communication between the native host and a VST3 plugin @@ -42,10 +39,8 @@ * The naming scheme of all of these 'bridge' classes is `{,Plugin}Bridge` * for greppability reasons. The `Plugin` infix is added on the native plugin * side. - * - * TODO: Also inherit this from PluginBridge */ -class Vst3PluginBridge { +class Vst3PluginBridge : PluginBridge> { public: /** * Initializes the VST3 module by starting and setting up communicating with @@ -56,74 +51,10 @@ class Vst3PluginBridge { */ Vst3PluginBridge(); - /** - * The configuration for this instance of yabridge. Set based on the values - * from a `yabridge.toml`, if it exists. - * - * @see ../utils.h:load_config_for - */ - Configuration config; - - /** - * The path to the VST3 module being loaded in the Wine VST host. This is - * normally a directory called `MyPlugin.vst3` that contains - * `MyPlugin.vst3/Contents/x86-win/MyPlugin.vst3`, but there's also an older - * deprecated (but still ubiquitous) format where the top level - * `MyPlugin.vst3` is not a directory but a .dll file. This points to either - * of those things, and then `VST3::Hosting::Win32Module::create()` will be - * able to load it. - * - * https://developer.steinberg.help/pages/viewpage.action?pageId=9798275 - */ - const boost::filesystem::path plugin_module_path; - private: - /** - * Format and log all relevant debug information during initialization. - */ - void log_init_message(); - - boost::asio::io_context io_context; - Vst3Sockets sockets; - /** * The logging facility used for this instance of yabridge. Wraps around * `PluginBridge::generic_logger`. */ Vst3Logger logger; - - /** - * The version of Wine currently in use. Used in the debug output on plugin - * startup. - */ - const std::string wine_version; - - /** - * The Wine process hosting the Windows VST3 plugin. - * - * @see launch_vst_host - */ - std::unique_ptr vst_host; - - /** - * A thread used during the initialisation process to terminate listening on - * the sockets if the Wine process cannot start for whatever reason. This - * has to be defined here instead of in the constructor we can't simply - * detach the thread as it has to check whether the Wine plugin host is - * still running. - */ - std::jthread host_guard_handler; - - /** - * Whether this process runs with realtime priority. We'll set this _after_ - * spawning the Wine process because from my testing running wineserver with - * realtime priority can actually increase latency. - */ - bool has_realtime_priority; - - /** - * Runs the Boost.Asio `io_context` thread for logging the Wine process - * STDOUT and STDERR messages. - */ - std::jthread wine_io_handler; };