diff --git a/src/common/logging/vst3.cpp b/src/common/logging/vst3.cpp index 83dd5c88..d7a8f10d 100644 --- a/src/common/logging/vst3.cpp +++ b/src/common/logging/vst3.cpp @@ -700,6 +700,16 @@ bool Vst3Logger::log_request(bool is_host_vst, }); } +bool Vst3Logger::log_request( + bool is_host_vst, + const YaUnitHandler::NotifyUnitSelection& request) { + return log_request_base(is_host_vst, [&](auto& message) { + message << request.owner_instance_id + << ": IUnitHandler::notifyUnitSelection(unitId = " + << request.unit_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 9077f66a..72696842 100644 --- a/src/common/logging/vst3.h +++ b/src/common/logging/vst3.h @@ -139,6 +139,8 @@ class Vst3Logger { const YaComponentHandler::RestartComponent&); bool log_request(bool is_host_vst, const YaHostApplication::GetName&); bool log_request(bool is_host_vst, const YaPlugFrame::ResizeView&); + bool log_request(bool is_host_vst, + const YaUnitHandler::NotifyUnitSelection&); 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 87d4551a..5fea6574 100644 --- a/src/common/serialization/vst3.h +++ b/src/common/serialization/vst3.h @@ -153,7 +153,8 @@ using CallbackRequest = std::variant; + YaPlugFrame::ResizeView, + YaUnitHandler::NotifyUnitSelection>; template void serialize(S& s, CallbackRequest& payload) { diff --git a/src/common/serialization/vst3/component-handler/unit-handler.h b/src/common/serialization/vst3/component-handler/unit-handler.h index b861eb70..0f322a40 100644 --- a/src/common/serialization/vst3/component-handler/unit-handler.h +++ b/src/common/serialization/vst3/component-handler/unit-handler.h @@ -61,6 +61,25 @@ class YaUnitHandler : public Steinberg::Vst::IUnitHandler { inline bool supported() const { return arguments.supported; } + /** + * Message to pass through a call to + * `IUnitHandler::notifyUnitSelection(unit_id)` to the unit handler provided + * by the host. + */ + struct NotifyUnitSelection { + using Response = UniversalTResult; + + native_size_t owner_instance_id; + + Steinberg::Vst::UnitID unit_id; + + template + void serialize(S& s) { + s.value8b(owner_instance_id); + s.value4b(unit_id); + } + }; + virtual tresult PLUGIN_API notifyUnitSelection(Steinberg::Vst::UnitID unitId) override = 0; virtual tresult PLUGIN_API diff --git a/src/plugin/bridges/vst3-impls/plugin-factory.h b/src/plugin/bridges/vst3-impls/plugin-factory.h index 3e2d93a6..209ce765 100644 --- a/src/plugin/bridges/vst3-impls/plugin-factory.h +++ b/src/plugin/bridges/vst3-impls/plugin-factory.h @@ -28,8 +28,8 @@ class YaPluginFactoryImpl : public YaPluginFactory { void** obj) override; tresult PLUGIN_API setHostContext(Steinberg::FUnknown* context) override; - // The following pointers are cast from `host_context` if `setHostContext()` - // has been called + // The following pointers are cast from `host_context` if + // `IPluginFactory3::setHostContext()` has been called Steinberg::FUnknownPtr host_application; diff --git a/src/plugin/bridges/vst3-impls/plugin-proxy.cpp b/src/plugin/bridges/vst3-impls/plugin-proxy.cpp index de7c1deb..bf94bbd7 100644 --- a/src/plugin/bridges/vst3-impls/plugin-proxy.cpp +++ b/src/plugin/bridges/vst3-impls/plugin-proxy.cpp @@ -357,6 +357,10 @@ tresult PLUGIN_API Vst3PluginProxyImpl::setComponentHandler( // this component handler component_handler = handler; + // Automatically converted smart pointers for when the plugin performs a + // callback later + unit_handler = component_handler; + return bridge.send_message(YaEditController::SetComponentHandler{ .instance_id = instance_id(), .component_handler_proxy_args = diff --git a/src/plugin/bridges/vst3-impls/plugin-proxy.h b/src/plugin/bridges/vst3-impls/plugin-proxy.h index d767cd2b..c9ca866f 100644 --- a/src/plugin/bridges/vst3-impls/plugin-proxy.h +++ b/src/plugin/bridges/vst3-impls/plugin-proxy.h @@ -152,11 +152,16 @@ class Vst3PluginProxyImpl : public Vst3PluginProxy { */ Vst3PlugViewProxyImpl* last_created_plug_view = nullptr; - // The following pointers are cast from `host_context` if `setHostContext()` - // has been called + // The following pointers are cast from `host_context` if + // `IPluginBase::initialize()` has been called Steinberg::FUnknownPtr host_application; + // The following pointers are cast from `component_handler` if + // `IEditController::setComponentHandler()` has been called + + Steinberg::FUnknownPtr unit_handler; + private: Vst3PluginBridge& bridge; diff --git a/src/plugin/bridges/vst3.cpp b/src/plugin/bridges/vst3.cpp index 61a4e43e..c0480f2b 100644 --- a/src/plugin/bridges/vst3.cpp +++ b/src/plugin/bridges/vst3.cpp @@ -145,6 +145,12 @@ Vst3PluginBridge::Vst3PluginBridge() return plug_view->plug_frame->resizeView(plug_view, &request.new_size); }, + [&](const YaUnitHandler::NotifyUnitSelection& request) + -> YaUnitHandler::NotifyUnitSelection::Response { + return plugin_proxies.at(request.owner_instance_id) + .get() + .unit_handler->notifyUnitSelection(request.unit_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 690501e1..f16ae185 100644 --- a/src/wine-host/bridges/vst3-impls/component-handler-proxy.cpp +++ b/src/wine-host/bridges/vst3-impls/component-handler-proxy.cpp @@ -69,9 +69,8 @@ Vst3ComponentHandlerProxyImpl::restartComponent(int32 flags) { tresult PLUGIN_API Vst3ComponentHandlerProxyImpl::notifyUnitSelection( Steinberg::Vst::UnitID unitId) { - // TODO: Implement - std::cerr << "TODO: IUnitHandler::notifyUnitSelection" << std::endl; - return Steinberg::kNotImplemented; + return bridge.send_message(YaUnitHandler::NotifyUnitSelection{ + .owner_instance_id = owner_instance_id(), .unit_id = unitId}); } tresult PLUGIN_API Vst3ComponentHandlerProxyImpl::notifyProgramListChange(