From 7306809991fe3949a3845d6a83394824a2e88c49 Mon Sep 17 00:00:00 2001 From: Robbert van der Helm Date: Sat, 19 Dec 2020 22:17:10 +0100 Subject: [PATCH] Drop IPlugView pointer when host drops proxy --- src/common/logging/vst3.cpp | 9 +++++++++ src/common/logging/vst3.h | 1 + src/common/serialization/vst3.h | 3 ++- src/common/serialization/vst3/plug-view-proxy.h | 16 ++++++++++++++++ .../bridges/vst3-impls/plug-view-proxy.cpp | 9 ++++----- src/wine-host/bridges/vst3.cpp | 8 ++++++++ 6 files changed, 40 insertions(+), 6 deletions(-) diff --git a/src/common/logging/vst3.cpp b/src/common/logging/vst3.cpp index 541373a1..6a173766 100644 --- a/src/common/logging/vst3.cpp +++ b/src/common/logging/vst3.cpp @@ -35,6 +35,15 @@ void Vst3Logger::log_unknown_interface( } } +bool Vst3Logger::log_request(bool is_host_vst, + const Vst3PlugViewProxy::Destruct& request) { + return log_request_base(is_host_vst, [&](auto& message) { + // We don't know what class this instance was originally instantiated + // as, but it also doesn't really matter + message << request.owner_instance_id << ": IPlugView::~IPlugView()"; + }); +} + bool Vst3Logger::log_request(bool is_host_vst, const Vst3PluginProxy::Construct& request) { return log_request_base(is_host_vst, [&](auto& message) { diff --git a/src/common/logging/vst3.h b/src/common/logging/vst3.h index de5a73d5..3e02db4f 100644 --- a/src/common/logging/vst3.h +++ b/src/common/logging/vst3.h @@ -59,6 +59,7 @@ class Vst3Logger { // `log_request()` call returned `true`. This way we can filter out the // log message for the response together with the request. + bool log_request(bool is_host_vst, const Vst3PlugViewProxy::Destruct&); bool log_request(bool is_host_vst, const Vst3PluginProxy::Construct&); bool log_request(bool is_host_vst, const Vst3PluginProxy::Destruct&); bool log_request(bool is_host_vst, const Vst3PluginProxy::SetState&); diff --git a/src/common/serialization/vst3.h b/src/common/serialization/vst3.h index 2b1d554d..f870e2ed 100644 --- a/src/common/serialization/vst3.h +++ b/src/common/serialization/vst3.h @@ -59,7 +59,8 @@ struct WantsConfiguration { * encodes the information we request or the operation we want to perform. A * request of type `ControlRequest(T)` should send back a `T::Response`. */ -using ControlRequest = std::variant + void serialize(S& s) { + s.value8b(owner_instance_id); + } + }; + /** * @remark The plugin side implementation should send a control message to * clean up the instance on the Wine side in its destructor. diff --git a/src/plugin/bridges/vst3-impls/plug-view-proxy.cpp b/src/plugin/bridges/vst3-impls/plug-view-proxy.cpp index 0ab49fa0..808f84f2 100644 --- a/src/plugin/bridges/vst3-impls/plug-view-proxy.cpp +++ b/src/plugin/bridges/vst3-impls/plug-view-proxy.cpp @@ -22,11 +22,10 @@ Vst3PlugViewProxyImpl::Vst3PlugViewProxyImpl( : Vst3PlugViewProxy(std::move(args)), bridge(bridge) {} Vst3PlugViewProxyImpl::~Vst3PlugViewProxyImpl() { - // TODO: Implement this: - // // Also drop the plug view smart pointer on the Wine side when this gets - // // dropped - // bridge.send_message( - // Vst3PlugViewProxy::Destruct{.instance_id = instance_id()}); + // Also drop the plug view smart pointer on the Wine side when this gets + // dropped + bridge.send_message( + Vst3PlugViewProxy::Destruct{.owner_instance_id = owner_instance_id()}); } tresult PLUGIN_API diff --git a/src/wine-host/bridges/vst3.cpp b/src/wine-host/bridges/vst3.cpp index a0ce3426..f4ca651f 100644 --- a/src/wine-host/bridges/vst3.cpp +++ b/src/wine-host/bridges/vst3.cpp @@ -67,6 +67,14 @@ void Vst3Bridge::run() { sockets.host_vst_control.receive_messages( std::nullopt, overload{ + [&](const Vst3PlugViewProxy::Destruct& request) + -> Vst3PlugViewProxy::Destruct::Response { + // When the pointer gets dropped by the host, we want to drop it + // here as well + object_instances[request.owner_instance_id].plug_view.reset(); + + return Ack{}; + }, [&](const Vst3PluginProxy::Construct& request) -> Vst3PluginProxy::Construct::Response { Steinberg::TUID cid;