diff --git a/src/plugin/bridges/clap.cpp b/src/plugin/bridges/clap.cpp index bf3f0de5..3226b161 100644 --- a/src/plugin/bridges/clap.cpp +++ b/src/plugin/bridges/clap.cpp @@ -73,6 +73,28 @@ ClapPluginBridge::~ClapPluginBridge() noexcept { } const void* ClapPluginBridge::get_factory(const char* factory_id) { - // FIXME: Implement - return nullptr; + assert(factory_id); + + if (strcmp(factory_id, CLAP_PLUGIN_FACTORY_ID) == 0) { + // We'll initialize the factory the first time it's requested + if (!plugin_factory_) { + // If the plugin does not support this factory type, then we'll also + // return a null poitner + const clap::plugin_factory::ListResponse response = + send_main_thread_message(clap::plugin_factory::List{}); + if (!response.descriptors) { + return nullptr; + } + + plugin_factory_ = std::make_unique( + *this, *response.descriptors); + } + + return &plugin_factory_->plugin_factory_vtable; + } else { + logger_.log_trace([factory_id]() { + return "Unknown factory type '" + std::string(factory_id) + "'"; + }); + return nullptr; + } } diff --git a/src/plugin/bridges/clap.h b/src/plugin/bridges/clap.h index bb1c9a70..03e09c17 100644 --- a/src/plugin/bridges/clap.h +++ b/src/plugin/bridges/clap.h @@ -22,6 +22,7 @@ #include "../../common/communication/clap.h" #include "../../common/logging/clap.h" #include "../../common/mutual-recursion.h" +#include "clap-impls/plugin-factory-proxy.h" #include "common.h" /** @@ -108,21 +109,17 @@ class ClapPluginBridge : PluginBridge> { // */ // void unregister_plugin_proxy(ClapPluginProxyImpl& proxy_object); - // // TODO: - // /** - // * Send a control message to the Wine plugin host and return the - // response. - // * This is intended for main thread function calls, and it's a shorthand - // for - // * `sockets_.host_plugin_control_.send_message()` for use in CLAP - // interface - // * implementations. - // */ - // template - // typename T::Response send_main_thread_message(const T& object) { - // return sockets_.host_plugin_control_.send_message( - // object, std::pair(logger_, true)); - // } + /** + * Send a control message to the Wine plugin host and return the response. + * This is intended for main thread function calls, and it's a shorthand for + * `sockets_.host_plugin_control_.send_message()` for use in CLAP interface + * implementations. + */ + template + typename T::Response send_main_thread_message(const T& object) { + return sockets_.host_plugin_main_thread_control_.send_message( + object, std::pair(logger_, true)); + } // /** // * Send an a message to a plugin instance's audio thread. This is @@ -206,16 +203,14 @@ class ClapPluginBridge : PluginBridge> { */ std::jthread host_callback_handler_; - // /** - // * Our plugin factory. All information about the plugin and its supported - // * classes are copied directly from the Windows CLAP plugin's factory on - // the - // * Wine side, and we'll provide an implementation that can send control - // * messages to the Wine plugin host. - // * - // * @related get_plugin_factory - // */ - // Steinberg::IPtr plugin_factory_ = nullptr; + /** + * Our plugin factory, containing information about all plugins supported by + * the bridged CLAP plugin's factory. This is initialized the first time the + * host tries to query this in `clap_entry->get_factory()`. + * + * @related get_factory + */ + std::unique_ptr plugin_factory_; // TODO: Implement // /**