mirror of
https://github.com/robbert-vdh/yabridge.git
synced 2026-05-09 20:29:10 +02:00
Add messages for creating plugin instances
This commit is contained in:
@@ -12,12 +12,6 @@ Yabridge currently tracks CLAP 1.1.1. The implementation status for CLAP's core
|
|||||||
| `clap.plugin-factory` | :heavy_check_mark: |
|
| `clap.plugin-factory` | :heavy_check_mark: |
|
||||||
| `clap.plugin-invalidation-factory/draft0` | :x: Not supported yet |
|
| `clap.plugin-invalidation-factory/draft0` | :x: Not supported yet |
|
||||||
|
|
||||||
| extension | status |
|
|
||||||
| ----------------------------------------- | --------------------- |
|
|
||||||
| Core plugin and host functionality | :x: Work in progress |
|
|
||||||
| `clap.plugin-factory` | :x: Work in progress |
|
|
||||||
| `clap.plugin-invalidation-factory/draft0` | :x: Not supported yet |
|
|
||||||
|
|
||||||
| extension | status |
|
| extension | status |
|
||||||
| ------------------------- | --------------------- |
|
| ------------------------- | --------------------- |
|
||||||
| `clap.audio-ports` | :x: Not supported yet |
|
| `clap.audio-ports` | :x: Not supported yet |
|
||||||
|
|||||||
@@ -16,6 +16,8 @@
|
|||||||
|
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
|
#include "../common.h"
|
||||||
|
#include "host.h"
|
||||||
#include "plugin.h"
|
#include "plugin.h"
|
||||||
|
|
||||||
// Serialization messages for `clap/plugin-factory.h`
|
// Serialization messages for `clap/plugin-factory.h`
|
||||||
@@ -24,7 +26,7 @@ namespace clap {
|
|||||||
namespace plugin_factory {
|
namespace plugin_factory {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The response to the `clap::plugin_factory::list` message defined below.
|
* The response to the `clap::plugin_factory::List` message defined below.
|
||||||
*/
|
*/
|
||||||
struct ListResponse {
|
struct ListResponse {
|
||||||
/**
|
/**
|
||||||
@@ -54,243 +56,47 @@ struct List {
|
|||||||
void serialize(S&) {}
|
void serialize(S&) {}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The response to the `clap::plugin_factory::Create` message defined below.
|
||||||
|
*/
|
||||||
|
struct CreateResponse {
|
||||||
|
/**
|
||||||
|
* The new plugin instance's ID, if it was initialized correctly. We'll
|
||||||
|
* assume the instance's plugin descriptor is the same as the one from the
|
||||||
|
* factory.
|
||||||
|
*/
|
||||||
|
std::optional<native_size_t> instance_id;
|
||||||
|
|
||||||
|
template <typename S>
|
||||||
|
void serialize(S& s) {
|
||||||
|
s.ext(instance_id, bitsery::ext::InPlaceOptional{},
|
||||||
|
[](S& s, auto& v) { s.value8b(v); });
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Message struct for `clap_plugin_factory::create()`. Contains information
|
||||||
|
* about the host for the `clap_host_t*`. If the plugin instance was created
|
||||||
|
* successfully, then the Wine host side will generate a unique identifier for
|
||||||
|
* the instance that is used to refer to it in further messages.
|
||||||
|
*/
|
||||||
|
struct Create {
|
||||||
|
using Response = CreateResponse;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Information about the native host that can be used to construct a
|
||||||
|
* `clap_host_t*` proxy.
|
||||||
|
*/
|
||||||
|
clap::host::Host host;
|
||||||
|
|
||||||
|
std::string plugin_id;
|
||||||
|
|
||||||
|
template <typename S>
|
||||||
|
void serialize(S& s) {
|
||||||
|
s.object(host);
|
||||||
|
s.text1b(plugin_id, 4096);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
} // namespace plugin_factory
|
} // namespace plugin_factory
|
||||||
} // namespace clap
|
} // namespace clap
|
||||||
|
|
||||||
// #include <bitsery/traits/string.h>
|
|
||||||
// #include <pluginterfaces/base/ipluginbase.h>
|
|
||||||
|
|
||||||
// #include "../../../bitsery/ext/in-place-optional.h"
|
|
||||||
// #include "../base.h"
|
|
||||||
// #include "../host-context-proxy.h"
|
|
||||||
|
|
||||||
// #pragma GCC diagnostic push
|
|
||||||
// #pragma GCC diagnostic ignored "-Wnon-virtual-dtor"
|
|
||||||
|
|
||||||
// /**
|
|
||||||
// * Wraps around `IPluginFactory{1,2,3}` for serialization purposes. This is
|
|
||||||
// * instantiated as part of `Vst3PluginFactoryProxy`.
|
|
||||||
// */
|
|
||||||
// class YaPluginFactory3 : public Steinberg::IPluginFactory3 {
|
|
||||||
// public:
|
|
||||||
// /**
|
|
||||||
// * These are the arguments for creating a `YaPluginFactory3`. All class
|
|
||||||
// * infos in all available formats are read from the plugin so the host
|
|
||||||
// can
|
|
||||||
// * query them.
|
|
||||||
// */
|
|
||||||
// struct ConstructArgs {
|
|
||||||
// ConstructArgs() noexcept;
|
|
||||||
|
|
||||||
// /**
|
|
||||||
// * Check whether an existing implementation implements
|
|
||||||
// * `IPluginFactory1`, `IPluginFactory2`, and ``IPluginFactory3`` and
|
|
||||||
// * read arguments from it.
|
|
||||||
// */
|
|
||||||
// ConstructArgs(Steinberg::IPtr<Steinberg::FUnknown> object);
|
|
||||||
|
|
||||||
// /**
|
|
||||||
// * Whether the object supported `IPluginFactory`.
|
|
||||||
// */
|
|
||||||
// bool supports_plugin_factory = false;
|
|
||||||
|
|
||||||
// /**
|
|
||||||
// * Whether the object supported `IPluginFactory2`.
|
|
||||||
// */
|
|
||||||
// bool supports_plugin_factory_2 = false;
|
|
||||||
|
|
||||||
// /**
|
|
||||||
// * Whether the object supported `IPluginFactory3`.
|
|
||||||
// */
|
|
||||||
// bool supports_plugin_factory_3 = false;
|
|
||||||
|
|
||||||
// /**
|
|
||||||
// * For `IPluginFactory::getFactoryInfo`.
|
|
||||||
// */
|
|
||||||
// std::optional<Steinberg::PFactoryInfo> factory_info;
|
|
||||||
|
|
||||||
// /**
|
|
||||||
// * For `IPluginFactory::countClasses`.
|
|
||||||
// */
|
|
||||||
// int num_classes;
|
|
||||||
|
|
||||||
// /**
|
|
||||||
// * For `IPluginFactory::getClassInfo`. We need to store all four
|
|
||||||
// class
|
|
||||||
// * info versions if the plugin can provide them since we don't know
|
|
||||||
// * which version of the interface the host will use. Will be
|
|
||||||
// * `std::nullopt` if the plugin doesn't return a class info.
|
|
||||||
// *
|
|
||||||
// * NOTE: We'll have already converted all returned class IDs to
|
|
||||||
// native
|
|
||||||
// * class IDs using `WineUID::to_native_uid()` for
|
|
||||||
// cross-platform
|
|
||||||
// * compatibility. This applies to all `class_info_*` fields
|
|
||||||
// here.
|
|
||||||
// */
|
|
||||||
// std::vector<std::optional<Steinberg::PClassInfo>> class_infos_1;
|
|
||||||
|
|
||||||
// /**
|
|
||||||
// * For `IPluginFactory2::getClassInfo2`, works the same way as the
|
|
||||||
// * above.
|
|
||||||
// */
|
|
||||||
// std::vector<std::optional<Steinberg::PClassInfo2>> class_infos_2;
|
|
||||||
|
|
||||||
// /**
|
|
||||||
// * For `IPluginFactory3::getClassInfoUnicode`, works the same way as
|
|
||||||
// the
|
|
||||||
// * above.
|
|
||||||
// */
|
|
||||||
// std::vector<std::optional<Steinberg::PClassInfoW>>
|
|
||||||
// class_infos_unicode;
|
|
||||||
|
|
||||||
// template <typename S>
|
|
||||||
// void serialize(S& s) {
|
|
||||||
// s.value1b(supports_plugin_factory);
|
|
||||||
// s.value1b(supports_plugin_factory_2);
|
|
||||||
// s.value1b(supports_plugin_factory_3);
|
|
||||||
// s.ext(factory_info, bitsery::ext::InPlaceOptional{});
|
|
||||||
// s.value4b(num_classes);
|
|
||||||
// s.container(class_infos_1, 2048,
|
|
||||||
// [](S& s, std::optional<Steinberg::PClassInfo>& info)
|
|
||||||
// {
|
|
||||||
// s.ext(info, bitsery::ext::InPlaceOptional{});
|
|
||||||
// });
|
|
||||||
// s.container(class_infos_2, 2048,
|
|
||||||
// [](S& s, std::optional<Steinberg::PClassInfo2>& info)
|
|
||||||
// {
|
|
||||||
// s.ext(info, bitsery::ext::InPlaceOptional{});
|
|
||||||
// });
|
|
||||||
// s.container(class_infos_unicode, 2048,
|
|
||||||
// [](S& s, std::optional<Steinberg::PClassInfoW>& info)
|
|
||||||
// {
|
|
||||||
// s.ext(info, bitsery::ext::InPlaceOptional{});
|
|
||||||
// });
|
|
||||||
// }
|
|
||||||
// };
|
|
||||||
|
|
||||||
// /**
|
|
||||||
// * Instantiate this instance with arguments read from the Windows VST3
|
|
||||||
// * plugin's plugin factory.
|
|
||||||
// */
|
|
||||||
// YaPluginFactory3(ConstructArgs&& args) noexcept;
|
|
||||||
|
|
||||||
// virtual ~YaPluginFactory3() noexcept = default;
|
|
||||||
|
|
||||||
// inline bool supports_plugin_factory() const noexcept {
|
|
||||||
// return arguments_.supports_plugin_factory;
|
|
||||||
// }
|
|
||||||
|
|
||||||
// inline bool supports_plugin_factory_2() const noexcept {
|
|
||||||
// return arguments_.supports_plugin_factory_2;
|
|
||||||
// }
|
|
||||||
|
|
||||||
// inline bool supports_plugin_factory_3() const noexcept {
|
|
||||||
// return arguments_.supports_plugin_factory_3;
|
|
||||||
// }
|
|
||||||
|
|
||||||
// // All of these functiosn returning class information are fetched once on
|
|
||||||
// // the Wine side since they'll be static so we can just copy over the
|
|
||||||
// // responses
|
|
||||||
|
|
||||||
// // From `IPluginFactory`
|
|
||||||
// tresult PLUGIN_API getFactoryInfo(Steinberg::PFactoryInfo* info)
|
|
||||||
// override; int32 PLUGIN_API countClasses() override; tresult PLUGIN_API
|
|
||||||
// getClassInfo(Steinberg::int32 index,
|
|
||||||
// Steinberg::PClassInfo* info) override;
|
|
||||||
// /**
|
|
||||||
// * See the implementation in `Vst3PluginFactoryProxyImpl` for how this is
|
|
||||||
// * handled. We'll create new managed `Vst3PluginProxy` objects from here.
|
|
||||||
// */
|
|
||||||
// virtual tresult PLUGIN_API createInstance(Steinberg::FIDString cid,
|
|
||||||
// Steinberg::FIDString _iid,
|
|
||||||
// void** obj) override = 0;
|
|
||||||
|
|
||||||
// // From `IPluginFactory2`
|
|
||||||
// tresult PLUGIN_API getClassInfo2(int32 index,
|
|
||||||
// Steinberg::PClassInfo2* info) override;
|
|
||||||
|
|
||||||
// // From `IPluginFactory3`
|
|
||||||
// tresult PLUGIN_API
|
|
||||||
// getClassInfoUnicode(int32 index, Steinberg::PClassInfoW* info) override;
|
|
||||||
|
|
||||||
// /**
|
|
||||||
// * Message to pass through a call to `IPluginFactory3::setHostContext()`
|
|
||||||
// to
|
|
||||||
// * the Wine plugin host. A `Vst3HostContextProxy` should be created on
|
|
||||||
// the
|
|
||||||
// * Wine plugin host and then passed as an argument to
|
|
||||||
// * `IPluginFactory3::setHostContext()`.
|
|
||||||
// */
|
|
||||||
// struct SetHostContext {
|
|
||||||
// using Response = UniversalTResult;
|
|
||||||
|
|
||||||
// Vst3HostContextProxy::ConstructArgs host_context_args;
|
|
||||||
|
|
||||||
// template <typename S>
|
|
||||||
// void serialize(S& s) {
|
|
||||||
// s.object(host_context_args);
|
|
||||||
// }
|
|
||||||
// };
|
|
||||||
|
|
||||||
// virtual tresult PLUGIN_API
|
|
||||||
// setHostContext(Steinberg::FUnknown* context) override = 0;
|
|
||||||
|
|
||||||
// protected:
|
|
||||||
// ConstructArgs arguments_;
|
|
||||||
// };
|
|
||||||
|
|
||||||
// #pragma GCC diagnostic pop
|
|
||||||
|
|
||||||
// // Serialization functions have to live in the same namespace as the objects
|
|
||||||
// // they're serializing
|
|
||||||
// namespace Steinberg {
|
|
||||||
// template <typename S>
|
|
||||||
// void serialize(S& s, PClassInfo& class_info) {
|
|
||||||
// s.container1b(class_info.cid);
|
|
||||||
// s.value4b(class_info.cardinality);
|
|
||||||
// s.text1b(class_info.category);
|
|
||||||
// s.text1b(class_info.name);
|
|
||||||
// }
|
|
||||||
|
|
||||||
// template <typename S>
|
|
||||||
// void serialize(S& s, PClassInfo2& class_info) {
|
|
||||||
// s.container1b(class_info.cid);
|
|
||||||
// s.value4b(class_info.cardinality);
|
|
||||||
// s.text1b(class_info.category);
|
|
||||||
// s.text1b(class_info.name);
|
|
||||||
// s.value4b(class_info.classFlags);
|
|
||||||
// s.text1b(class_info.subCategories);
|
|
||||||
// s.text1b(class_info.vendor);
|
|
||||||
// s.text1b(class_info.version);
|
|
||||||
// s.text1b(class_info.sdkVersion);
|
|
||||||
// }
|
|
||||||
|
|
||||||
// template <typename S>
|
|
||||||
// void serialize(S& s, PClassInfoW& class_info) {
|
|
||||||
// s.container1b(class_info.cid);
|
|
||||||
// s.value4b(class_info.cardinality);
|
|
||||||
// s.text1b(class_info.category);
|
|
||||||
// // FIXME: Bitsery uses `std::char_traits<wchar_t>::length()` under the hood
|
|
||||||
// // for `text2b()` on the Wine side, and under winegcc this function
|
|
||||||
// // this length is incorrect. As a workaround we're just serializing
|
|
||||||
// // the entire container. This applies to every place where we use
|
|
||||||
// // `container2b()` to serialize a `String128`, so if we end up fixing
|
|
||||||
// // this we should replace all of the instances of `container2b()`
|
|
||||||
// // that serialize a `String128`.
|
|
||||||
// s.container2b(class_info.name);
|
|
||||||
// s.value4b(class_info.classFlags);
|
|
||||||
// s.text1b(class_info.subCategories);
|
|
||||||
// s.container2b(class_info.vendor);
|
|
||||||
// s.container2b(class_info.version);
|
|
||||||
// s.container2b(class_info.sdkVersion);
|
|
||||||
// }
|
|
||||||
|
|
||||||
// template <typename S>
|
|
||||||
// void serialize(S& s, PFactoryInfo& factory_info) {
|
|
||||||
// s.text1b(factory_info.vendor);
|
|
||||||
// s.text1b(factory_info.url);
|
|
||||||
// s.text1b(factory_info.email);
|
|
||||||
// s.value4b(factory_info.flags);
|
|
||||||
// }
|
|
||||||
// } // namespace Steinberg
|
|
||||||
|
|||||||
Reference in New Issue
Block a user