mirror of
https://github.com/robbert-vdh/yabridge.git
synced 2026-05-07 03:50:11 +02:00
Add CLAP plugin destroying
Everything else is still a stub, but at least the lifecycle now works correctly.
This commit is contained in:
@@ -38,16 +38,22 @@ bool ClapLogger::log_request(bool is_host_plugin,
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool ClapLogger::log_request(bool is_host_plugin,
|
||||||
|
const clap::plugin::Destroy& request) {
|
||||||
|
return log_request_base(is_host_plugin, [&](auto& message) {
|
||||||
|
message << request.instance_id << ": clap_plugin::destroy()";
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
bool ClapLogger::log_request(bool is_host_plugin, const WantsConfiguration&) {
|
bool ClapLogger::log_request(bool is_host_plugin, const WantsConfiguration&) {
|
||||||
return log_request_base(is_host_plugin, [&](auto& message) {
|
return log_request_base(is_host_plugin, [&](auto& message) {
|
||||||
message << "Requesting <Configuration>";
|
message << "Requesting <Configuration>";
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
// void ClapLogger::log_response(bool is_host_plugin, const Ack&) {
|
void ClapLogger::log_response(bool is_host_plugin, const Ack&) {
|
||||||
// log_response_base(is_host_plugin, [&](auto& message) { message << "ACK";
|
log_response_base(is_host_plugin, [&](auto& message) { message << "ACK"; });
|
||||||
// });
|
}
|
||||||
// }
|
|
||||||
|
|
||||||
void ClapLogger::log_response(
|
void ClapLogger::log_response(
|
||||||
bool is_host_plugin,
|
bool is_host_plugin,
|
||||||
|
|||||||
@@ -47,6 +47,7 @@ class ClapLogger {
|
|||||||
|
|
||||||
bool log_request(bool is_host_plugin, const clap::plugin_factory::List&);
|
bool log_request(bool is_host_plugin, const clap::plugin_factory::List&);
|
||||||
bool log_request(bool is_host_plugin, const clap::plugin_factory::Create&);
|
bool log_request(bool is_host_plugin, const clap::plugin_factory::Create&);
|
||||||
|
bool log_request(bool is_host_plugin, const clap::plugin::Destroy&);
|
||||||
|
|
||||||
// TODO: Audio thread requests
|
// TODO: Audio thread requests
|
||||||
// bool log_request(bool is_host_plugin,
|
// bool log_request(bool is_host_plugin,
|
||||||
@@ -54,7 +55,7 @@ class ClapLogger {
|
|||||||
|
|
||||||
bool log_request(bool is_host_plugin, const WantsConfiguration&);
|
bool log_request(bool is_host_plugin, const WantsConfiguration&);
|
||||||
|
|
||||||
// void log_response(bool is_host_plugin, const Ack&);
|
void log_response(bool is_host_plugin, const Ack&);
|
||||||
void log_response(bool is_host_plugin,
|
void log_response(bool is_host_plugin,
|
||||||
const clap::plugin_factory::ListResponse&);
|
const clap::plugin_factory::ListResponse&);
|
||||||
void log_response(bool is_host_plugin,
|
void log_response(bool is_host_plugin,
|
||||||
|
|||||||
@@ -41,7 +41,8 @@
|
|||||||
// serialize this without it.
|
// serialize this without it.
|
||||||
using ClapMainThreadControlRequest = std::variant<WantsConfiguration,
|
using ClapMainThreadControlRequest = std::variant<WantsConfiguration,
|
||||||
clap::plugin_factory::List,
|
clap::plugin_factory::List,
|
||||||
clap::plugin_factory::Create>;
|
clap::plugin_factory::Create,
|
||||||
|
clap::plugin::Destroy>;
|
||||||
|
|
||||||
template <typename S>
|
template <typename S>
|
||||||
void serialize(S& s, ClapMainThreadControlRequest& payload) {
|
void serialize(S& s, ClapMainThreadControlRequest& payload) {
|
||||||
|
|||||||
@@ -24,6 +24,7 @@
|
|||||||
#include <clap/plugin.h>
|
#include <clap/plugin.h>
|
||||||
|
|
||||||
#include "../../bitsery/ext/in-place-optional.h"
|
#include "../../bitsery/ext/in-place-optional.h"
|
||||||
|
#include "../common.h"
|
||||||
|
|
||||||
// Serialization messages for `clap/plugin.h`
|
// Serialization messages for `clap/plugin.h`
|
||||||
|
|
||||||
@@ -104,6 +105,22 @@ struct Descriptor {
|
|||||||
mutable clap_plugin_descriptor_t clap_descriptor;
|
mutable clap_plugin_descriptor_t clap_descriptor;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Message struct for `clap_plugin::destroy()`. The Wine plugin host should
|
||||||
|
* clean up the plugin, and everything is also cleaned up on the plugin side
|
||||||
|
* after receiving acknowledgement
|
||||||
|
*/
|
||||||
|
struct Destroy {
|
||||||
|
using Response = Ack;
|
||||||
|
|
||||||
|
native_size_t instance_id;
|
||||||
|
|
||||||
|
template <typename S>
|
||||||
|
void serialize(S& s) {
|
||||||
|
s.value8b(instance_id);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
} // namespace plugin
|
} // namespace plugin
|
||||||
} // namespace clap
|
} // namespace clap
|
||||||
|
|
||||||
|
|||||||
@@ -54,9 +54,12 @@ clap_plugin_proxy::plugin_destroy(const struct clap_plugin* plugin) {
|
|||||||
assert(plugin && plugin->plugin_data);
|
assert(plugin && plugin->plugin_data);
|
||||||
auto self = static_cast<const clap_plugin_proxy*>(plugin->plugin_data);
|
auto self = static_cast<const clap_plugin_proxy*>(plugin->plugin_data);
|
||||||
|
|
||||||
// TODO: Destroy on the Wine side
|
// This will clean everything related to this instance up on the Wine plugin
|
||||||
|
// host side
|
||||||
|
self->bridge_.send_main_thread_message(
|
||||||
|
clap::plugin::Destroy{.instance_id = self->instance_id()});
|
||||||
|
|
||||||
// This deallocates and destroys `self`
|
// And this deallocates and destroys `self`
|
||||||
self->bridge_.unregister_plugin_proxy(self->instance_id());
|
self->bridge_.unregister_plugin_proxy(self->instance_id());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -209,6 +209,19 @@ void ClapBridge::run() {
|
|||||||
})
|
})
|
||||||
.get();
|
.get();
|
||||||
},
|
},
|
||||||
|
[&](clap::plugin::Destroy& request)
|
||||||
|
-> clap::plugin::Destroy::Response {
|
||||||
|
return main_context_
|
||||||
|
.run_in_context([&]() {
|
||||||
|
// This calls `clap_plugin::destroy()` as part of
|
||||||
|
// cleaning up the `unique_ptr` holding the plugin
|
||||||
|
// instance pointer
|
||||||
|
unregister_plugin_instance(request.instance_id);
|
||||||
|
|
||||||
|
return Ack{};
|
||||||
|
})
|
||||||
|
.get();
|
||||||
|
},
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -446,12 +459,8 @@ void ClapBridge::unregister_plugin_instance(size_t instance_id) {
|
|||||||
|
|
||||||
// Remove the instance from within the main IO context so
|
// Remove the instance from within the main IO context so
|
||||||
// removing it doesn't interfere with the Win32 message loop
|
// removing it doesn't interfere with the Win32 message loop
|
||||||
// XXX: I don't think we have to wait for the object to be
|
// NOTE: This will implicitly run `clap_plugin::destroy()` as part of the
|
||||||
// deleted most of the time, but I can imagine a situation
|
// `unique_ptr`'s cleanup
|
||||||
// where the plugin does a host callback triggered by a
|
|
||||||
// Win32 timer in between where the above closure is being
|
|
||||||
// executed and when the actual host application context on
|
|
||||||
// the plugin side gets deallocated.
|
|
||||||
main_context_
|
main_context_
|
||||||
.run_in_context([&, instance_id]() -> void {
|
.run_in_context([&, instance_id]() -> void {
|
||||||
std::unique_lock lock(object_instances_mutex_);
|
std::unique_lock lock(object_instances_mutex_);
|
||||||
|
|||||||
Reference in New Issue
Block a user