From 3b06bca95ef0019280b5bf63b3223d19dfbcba1a Mon Sep 17 00:00:00 2001 From: Robbert van der Helm Date: Sat, 19 Dec 2020 15:36:50 +0100 Subject: [PATCH] Implement IComponentHandler::beginEdit() --- src/common/logging/vst3.cpp | 8 ++++++++ src/common/logging/vst3.h | 2 ++ src/common/serialization/vst3.h | 3 ++- .../vst3/component-handler/component-handler.h | 18 ++++++++++++++++++ src/plugin/bridges/vst3-impls/plugin-proxy.h | 6 +++--- src/plugin/bridges/vst3.cpp | 13 +++++++++++-- .../vst3-impls/component-handler-proxy.cpp | 5 ++--- src/wine-host/bridges/vst3.h | 10 ++++++++++ 8 files changed, 56 insertions(+), 9 deletions(-) diff --git a/src/common/logging/vst3.cpp b/src/common/logging/vst3.cpp index 233ea3c7..f0a3aa6e 100644 --- a/src/common/logging/vst3.cpp +++ b/src/common/logging/vst3.cpp @@ -446,6 +446,14 @@ bool Vst3Logger::log_request(bool is_host_vst, const WantsConfiguration&) { }); } +bool Vst3Logger::log_request(bool is_host_vst, + const YaComponentHandler::BeginEdit& request) { + return log_request_base(is_host_vst, [&](auto& message) { + message << request.owner_instance_id + << ": IComponentHandler::beginEdit(" << request.id << ")"; + }); +} + void Vst3Logger::log_response(bool is_host_vst, const Ack&) { log_response_base(is_host_vst, [&](auto& message) { message << "ACK"; }); } diff --git a/src/common/logging/vst3.h b/src/common/logging/vst3.h index 7174986a..20a1abd0 100644 --- a/src/common/logging/vst3.h +++ b/src/common/logging/vst3.h @@ -108,7 +108,9 @@ class Vst3Logger { bool log_request(bool is_host_vst, const YaPluginBase::Terminate&); bool log_request(bool is_host_vst, const YaPluginFactory::Construct&); bool log_request(bool is_host_vst, const YaPluginFactory::SetHostContext&); + bool log_request(bool is_host_vst, const WantsConfiguration&); + bool log_request(bool is_host_vst, const YaComponentHandler::BeginEdit&); void log_response(bool is_host_vst, const Ack&); void log_response( diff --git a/src/common/serialization/vst3.h b/src/common/serialization/vst3.h index a8415102..0172facf 100644 --- a/src/common/serialization/vst3.h +++ b/src/common/serialization/vst3.h @@ -105,7 +105,8 @@ void serialize(S& s, ControlRequest& payload) { * information we want or the operation we want to perform. A request of type * `CallbackRequest(T)` should send back a `T::Response`. */ -using CallbackRequest = std::variant; +using CallbackRequest = + std::variant; template void serialize(S& s, CallbackRequest& payload) { diff --git a/src/common/serialization/vst3/component-handler/component-handler.h b/src/common/serialization/vst3/component-handler/component-handler.h index edca75f3..b907d297 100644 --- a/src/common/serialization/vst3/component-handler/component-handler.h +++ b/src/common/serialization/vst3/component-handler/component-handler.h @@ -61,6 +61,24 @@ class YaComponentHandler : public Steinberg::Vst::IComponentHandler { inline bool supported() const { return arguments.supported; } + /** + * Message to pass through a call to `IComponentHandler::beginEdit(id)` to + * the component handler provided by the host. + */ + struct BeginEdit { + using Response = UniversalTResult; + + native_size_t owner_instance_id; + + Steinberg::Vst::ParamID id; + + template + void serialize(S& s) { + s.value8b(owner_instance_id); + s.value4b(id); + } + }; + virtual tresult PLUGIN_API beginEdit(Steinberg::Vst::ParamID id) override = 0; virtual tresult PLUGIN_API diff --git a/src/plugin/bridges/vst3-impls/plugin-proxy.h b/src/plugin/bridges/vst3-impls/plugin-proxy.h index 2b5c2c25..202e1cec 100644 --- a/src/plugin/bridges/vst3-impls/plugin-proxy.h +++ b/src/plugin/bridges/vst3-impls/plugin-proxy.h @@ -122,9 +122,6 @@ class Vst3PluginProxyImpl : public Vst3PluginProxy { tresult PLUGIN_API initialize(FUnknown* context) override; tresult PLUGIN_API terminate() override; - private: - Vst3PluginBridge& bridge; - /** * An `IHostApplication` instance if we get one through * `IPluginBase::initialize()`. This should be the same for all plugin @@ -141,4 +138,7 @@ class Vst3PluginProxyImpl : public Vst3PluginProxy { * to this object. */ Steinberg::IPtr component_handler; + + private: + Vst3PluginBridge& bridge; }; diff --git a/src/plugin/bridges/vst3.cpp b/src/plugin/bridges/vst3.cpp index 5df60b9a..ab8a44fe 100644 --- a/src/plugin/bridges/vst3.cpp +++ b/src/plugin/bridges/vst3.cpp @@ -79,8 +79,17 @@ Vst3PluginBridge::Vst3PluginBridge() host_callback_handler = std::jthread([&]() { sockets.vst_host_callback.receive_messages( std::pair(logger, false), - overload{[&](const WantsConfiguration&) - -> WantsConfiguration::Response { return config; }}); + overload{ + [&](const WantsConfiguration&) -> WantsConfiguration::Response { + return config; + }, + [&](const YaComponentHandler::BeginEdit& request) + -> YaComponentHandler::BeginEdit::Response { + return plugin_proxies.at(request.owner_instance_id) + .get() + .component_handler->beginEdit(request.id); + }, + }); }); } diff --git a/src/wine-host/bridges/vst3-impls/component-handler-proxy.cpp b/src/wine-host/bridges/vst3-impls/component-handler-proxy.cpp index 273d8fe8..7f76a54f 100644 --- a/src/wine-host/bridges/vst3-impls/component-handler-proxy.cpp +++ b/src/wine-host/bridges/vst3-impls/component-handler-proxy.cpp @@ -41,9 +41,8 @@ Vst3ComponentHandlerProxyImpl::queryInterface(const Steinberg::TUID _iid, tresult PLUGIN_API Vst3ComponentHandlerProxyImpl::beginEdit(Steinberg::Vst::ParamID id) { - // TODO: Implement - std::cerr << "TODO: IComponentHandler::beginEdit()" << std::endl; - return Steinberg::kNotImplemented; + return bridge.send_message(YaComponentHandler::BeginEdit{ + .owner_instance_id = owner_instance_id(), .id = id}); } tresult PLUGIN_API Vst3ComponentHandlerProxyImpl::performEdit( diff --git a/src/wine-host/bridges/vst3.h b/src/wine-host/bridges/vst3.h index 7a9b1259..8e2f2d88 100644 --- a/src/wine-host/bridges/vst3.h +++ b/src/wine-host/bridges/vst3.h @@ -103,6 +103,16 @@ class Vst3Bridge : public HostBridge { */ void run() override; + /** + * Send a callback message to the host return the response. This is a + * shorthand for `sockets.vst_host_callback.send_message` for use in VST3 + * interface implementations. + */ + template + typename T::Response send_message(const T& object) { + return sockets.vst_host_callback.send_message(object, std::nullopt); + } + private: /** * Generate a nique instance identifier using an atomic fetch-and-add. This