Drop IPlugView pointer when host drops proxy

This commit is contained in:
Robbert van der Helm
2020-12-19 22:17:10 +01:00
parent b7047a5281
commit 7306809991
6 changed files with 40 additions and 6 deletions
+9
View File
@@ -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, bool Vst3Logger::log_request(bool is_host_vst,
const Vst3PluginProxy::Construct& request) { const Vst3PluginProxy::Construct& request) {
return log_request_base(is_host_vst, [&](auto& message) { return log_request_base(is_host_vst, [&](auto& message) {
+1
View File
@@ -59,6 +59,7 @@ class Vst3Logger {
// `log_request()` call returned `true`. This way we can filter out the // `log_request()` call returned `true`. This way we can filter out the
// log message for the response together with the request. // 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::Construct&);
bool log_request(bool is_host_vst, const Vst3PluginProxy::Destruct&); bool log_request(bool is_host_vst, const Vst3PluginProxy::Destruct&);
bool log_request(bool is_host_vst, const Vst3PluginProxy::SetState&); bool log_request(bool is_host_vst, const Vst3PluginProxy::SetState&);
+2 -1
View File
@@ -59,7 +59,8 @@ struct WantsConfiguration {
* encodes the information we request or the operation we want to perform. A * encodes the information we request or the operation we want to perform. A
* request of type `ControlRequest(T)` should send back a `T::Response`. * request of type `ControlRequest(T)` should send back a `T::Response`.
*/ */
using ControlRequest = std::variant<Vst3PluginProxy::Construct, using ControlRequest = std::variant<Vst3PlugViewProxy::Destruct,
Vst3PluginProxy::Construct,
Vst3PluginProxy::Destruct, Vst3PluginProxy::Destruct,
Vst3PluginProxy::SetState, Vst3PluginProxy::SetState,
Vst3PluginProxy::GetState, Vst3PluginProxy::GetState,
@@ -72,6 +72,22 @@ class Vst3PlugViewProxy : public YaPlugView {
*/ */
Vst3PlugViewProxy(const ConstructArgs&& args); Vst3PlugViewProxy(const ConstructArgs&& args);
/**
* Message to request the Wine plugin host to destroy the `IPlugView*`
* returned by the object with the given instance ID. Sent from the
* destructor of `Vst3PlugViewProxyImpl`.
*/
struct Destruct {
using Response = Ack;
native_size_t owner_instance_id;
template <typename S>
void serialize(S& s) {
s.value8b(owner_instance_id);
}
};
/** /**
* @remark The plugin side implementation should send a control message to * @remark The plugin side implementation should send a control message to
* clean up the instance on the Wine side in its destructor. * clean up the instance on the Wine side in its destructor.
@@ -22,11 +22,10 @@ Vst3PlugViewProxyImpl::Vst3PlugViewProxyImpl(
: Vst3PlugViewProxy(std::move(args)), bridge(bridge) {} : Vst3PlugViewProxy(std::move(args)), bridge(bridge) {}
Vst3PlugViewProxyImpl::~Vst3PlugViewProxyImpl() { Vst3PlugViewProxyImpl::~Vst3PlugViewProxyImpl() {
// TODO: Implement this: // Also drop the plug view smart pointer on the Wine side when this gets
// // Also drop the plug view smart pointer on the Wine side when this gets // dropped
// // dropped bridge.send_message(
// bridge.send_message( Vst3PlugViewProxy::Destruct{.owner_instance_id = owner_instance_id()});
// Vst3PlugViewProxy::Destruct{.instance_id = instance_id()});
} }
tresult PLUGIN_API tresult PLUGIN_API
+8
View File
@@ -67,6 +67,14 @@ void Vst3Bridge::run() {
sockets.host_vst_control.receive_messages( sockets.host_vst_control.receive_messages(
std::nullopt, std::nullopt,
overload{ 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) [&](const Vst3PluginProxy::Construct& request)
-> Vst3PluginProxy::Construct::Response { -> Vst3PluginProxy::Construct::Response {
Steinberg::TUID cid; Steinberg::TUID cid;