mirror of
https://github.com/robbert-vdh/yabridge.git
synced 2026-05-07 03:50:11 +02:00
Add functions for registering CLAP plugin proxies
This commit is contained in:
@@ -98,3 +98,32 @@ const void* ClapPluginBridge::get_factory(const char* factory_id) {
|
||||
return nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
std::pair<clap_plugin_proxy&, std::shared_lock<std::shared_mutex>>
|
||||
ClapPluginBridge::get_proxy(size_t instance_id) noexcept {
|
||||
std::shared_lock lock(plugin_proxies_mutex_);
|
||||
|
||||
return std::pair<clap_plugin_proxy&, std::shared_lock<std::shared_mutex>>(
|
||||
*plugin_proxies_.at(instance_id), std::move(lock));
|
||||
}
|
||||
|
||||
void ClapPluginBridge::register_plugin_proxy(
|
||||
std::unique_ptr<clap_plugin_proxy> plugin_proxy) {
|
||||
std::unique_lock lock(plugin_proxies_mutex_);
|
||||
|
||||
assert(plugin_proxy);
|
||||
|
||||
plugin_proxies_.emplace(plugin_proxy->instance_id(),
|
||||
std::move(plugin_proxy));
|
||||
|
||||
// For optimization reaons we use dedicated sockets for functions that will
|
||||
// be run in the audio processing loop
|
||||
sockets_.add_audio_thread_and_connect(plugin_proxy->instance_id());
|
||||
}
|
||||
|
||||
void ClapPluginBridge::unregister_plugin_proxy(size_t instance_id) {
|
||||
std::lock_guard lock(plugin_proxies_mutex_);
|
||||
|
||||
plugin_proxies_.erase(instance_id);
|
||||
sockets_.remove_audio_thread(instance_id);
|
||||
}
|
||||
|
||||
+44
-54
@@ -23,6 +23,7 @@
|
||||
#include "../../common/logging/clap.h"
|
||||
#include "../../common/mutual-recursion.h"
|
||||
#include "clap-impls/plugin-factory-proxy.h"
|
||||
#include "clap-impls/plugin-proxy.h"
|
||||
#include "common.h"
|
||||
|
||||
/**
|
||||
@@ -69,45 +70,38 @@ class ClapPluginBridge : PluginBridge<ClapSockets<std::jthread>> {
|
||||
*/
|
||||
const void* get_factory(const char* factory_id);
|
||||
|
||||
// TODO:
|
||||
// /**
|
||||
// * Fetch the plugin proxy instance along with a lock valid for the
|
||||
// * instance's lifetime. This is mostly just to save some boilerplate
|
||||
// * everywhere. Use C++17's structured binding as syntactic sugar to not
|
||||
// have
|
||||
// * to deal with the lock handle.
|
||||
// */
|
||||
// std::pair<ClapPluginProxyImpl&, std::shared_lock<std::shared_mutex>>
|
||||
// get_proxy(size_t instance_id) noexcept;
|
||||
/**
|
||||
* Fetch the plugin proxy instance along with a lock valid for the
|
||||
* instance's lifetime. This is mostly just to save some boilerplate
|
||||
* everywhere. Use C++17's structured binding as syntactic sugar to not have
|
||||
* to deal with the lock handle.
|
||||
*/
|
||||
std::pair<clap_plugin_proxy&, std::shared_lock<std::shared_mutex>>
|
||||
get_proxy(size_t instance_id) noexcept;
|
||||
|
||||
// /**
|
||||
// * Add a `ClapPluginProxyImpl` to the list of registered proxy objects so
|
||||
// we
|
||||
// * can handle host callbacks. This function is called in
|
||||
// * `ClapPluginProxyImpl`'s constructor. If the plugin supports the
|
||||
// * `IAudioProcessor` or `IComponent` interfaces, then we'll also connect
|
||||
// to
|
||||
// * a dedicated audio processing socket.
|
||||
// *
|
||||
// * @param proxy_object The proxy object so we can access its host context
|
||||
// * and unique instance identifier.
|
||||
// *
|
||||
// * @see plugin_proxies_
|
||||
// */
|
||||
// void register_plugin_proxy(ClapPluginProxyImpl& proxy_object);
|
||||
/**
|
||||
* Add a `clap_plugin_proxy` to the list of registered plugin proxies so we
|
||||
* can handle host callbacks. This function is called in
|
||||
* `clap_plugin_factory_proxy::create()`. This function also connects the
|
||||
* instance's audio thread socket.
|
||||
*
|
||||
* @param proxy_object The proxy object so we can access its host context
|
||||
* and unique instance identifier.
|
||||
*
|
||||
* @see plugin_proxies_
|
||||
*/
|
||||
void register_plugin_proxy(std::unique_ptr<clap_plugin_proxy> plugin_proxy);
|
||||
|
||||
// /**
|
||||
// * Remove a previously registered `ClapPluginProxyImpl` from the list of
|
||||
// * registered proxy objects. Called during the object's destructor after
|
||||
// * asking the Wine plugin host to destroy the component on its side.
|
||||
// *
|
||||
// * @param proxy_object The proxy object so we can access its unique
|
||||
// instance
|
||||
// * identifier.
|
||||
// *
|
||||
// * @see plugin_proxies_
|
||||
// */
|
||||
// void unregister_plugin_proxy(ClapPluginProxyImpl& proxy_object);
|
||||
/**
|
||||
* Remove a previously registered `clap_plugin_proxy` from the list of
|
||||
* registered plugin proxies. Called in `clap_plugin_proxy::destroy()`after
|
||||
* asking the Wine plugin host to destroy the component on its side.
|
||||
*
|
||||
* @param instance_id The instance ID of the proxy that should be removed.
|
||||
*
|
||||
* @see plugin_proxies_
|
||||
*/
|
||||
void unregister_plugin_proxy(size_t instance_id);
|
||||
|
||||
/**
|
||||
* Send a control message to the Wine plugin host and return the response.
|
||||
@@ -212,28 +206,24 @@ class ClapPluginBridge : PluginBridge<ClapSockets<std::jthread>> {
|
||||
*/
|
||||
std::unique_ptr<clap_plugin_factory_proxy> plugin_factory_;
|
||||
|
||||
// TODO: Implement
|
||||
// /**
|
||||
// * All CLAP plugin objects we created from this plugin. We keep track of
|
||||
// * these in case the plugin does a host callback, so we can associate
|
||||
// that
|
||||
// * call with the exact host context object passed to it during a call to
|
||||
// * `initialize()`. The IDs here are the same IDs as generated by the Wine
|
||||
// * plugin host. An instance is added here through a call by
|
||||
// * `register_plugin_proxy()` in `ClapPluginProxyImpl`'s constructor, and
|
||||
// an
|
||||
// * instance is then removed through a call to `unregister_plugin_proxy()`
|
||||
// in
|
||||
// * the destructor.
|
||||
// */
|
||||
// std::unordered_map<size_t, std::reference_wrapper<ClapPluginProxyImpl>>
|
||||
// plugin_proxies_;
|
||||
/**
|
||||
* Proxies for all CLAP plugin instances we created for this plugin library.
|
||||
* These are all keyed by an ID created on the Wine side when initializing
|
||||
* the plugin. That lets us send function calls from the host to the correct
|
||||
* plugin instance, and callbacks from a plugin instance to the correct host
|
||||
* instance. Instances are added here through a call by
|
||||
* `register_plugin_proxy()` in `clap_plugin_factory_proxy::create()`, and
|
||||
* they are removed again by a call to `unregister_plugin_proxy()` in
|
||||
* `clap_plugin_proxy::destroy()`.
|
||||
*/
|
||||
std::unordered_map<size_t, std::unique_ptr<clap_plugin_proxy>>
|
||||
plugin_proxies_;
|
||||
|
||||
/**
|
||||
* In theory all object handling is safe iff the host also doesn't do
|
||||
* anything weird even without locks, but we'll still prevent adding or
|
||||
* removing instances while accessing other instances at the same time
|
||||
* anyways. See `ClapBridge::object_instances_mutex` for more details.
|
||||
* anyways. See `ClapBridge::plugin_instances_mutex_` for more details.
|
||||
*
|
||||
* TODO: At some point replace this with a multiple reader single writer
|
||||
* lock based by a spinlock. Because this lock is rarely contested
|
||||
|
||||
@@ -77,9 +77,11 @@ if with_clap
|
||||
'../common/notifications.cpp',
|
||||
'../common/plugins.cpp',
|
||||
'../common/process.cpp',
|
||||
'../common/serialization/clap/host.cpp',
|
||||
'../common/serialization/clap/plugin.cpp',
|
||||
'../common/utils.cpp',
|
||||
'../include/llvm/small-vector.cpp',
|
||||
'bridges/clap-impls/plugin-proxy.cpp',
|
||||
'bridges/clap-impls/plugin-factory-proxy.cpp',
|
||||
'bridges/clap.cpp',
|
||||
'host-process.cpp',
|
||||
|
||||
@@ -52,7 +52,7 @@ class clap_host_proxy {
|
||||
/**
|
||||
* The instance ID of the plugin instance this proxy belongs to.
|
||||
*/
|
||||
inline size_t owner_isntance_id() const { return owner_instance_id_; }
|
||||
inline size_t owner_instance_id() const { return owner_instance_id_; }
|
||||
|
||||
static const void* CLAP_ABI host_get_extension(const struct clap_host* host,
|
||||
const char* extension_id);
|
||||
|
||||
@@ -406,7 +406,7 @@ void ClapBridge::register_plugin_instance(
|
||||
|
||||
// This instance ID has already been generated because the host proxy has to
|
||||
// be created before the plugin instance
|
||||
const size_t instance_id = host_proxy->owner_isntance_id();
|
||||
const size_t instance_id = host_proxy->owner_instance_id();
|
||||
object_instances_.emplace(
|
||||
instance_id, ClapPluginInstance(plugin, std::move(host_proxy)));
|
||||
|
||||
@@ -441,7 +441,7 @@ void ClapBridge::register_plugin_instance(
|
||||
socket_listening_latch.get_future().wait();
|
||||
}
|
||||
|
||||
void ClapBridge::unregister_object_instance(size_t instance_id) {
|
||||
void ClapBridge::unregister_plugin_instance(size_t instance_id) {
|
||||
sockets_.remove_audio_thread(instance_id);
|
||||
|
||||
// Remove the instance from within the main IO context so
|
||||
|
||||
@@ -358,7 +358,7 @@ class ClapBridge : public HostBridge {
|
||||
* Remove an object from `object_instances_`. Will also tear down the
|
||||
* instance's audio thread.
|
||||
*/
|
||||
void unregister_object_instance(size_t instance_id);
|
||||
void unregister_plugin_instance(size_t instance_id);
|
||||
|
||||
/**
|
||||
* The configuration for this instance of yabridge based on the path to the
|
||||
|
||||
Reference in New Issue
Block a user