mirror of
https://github.com/robbert-vdh/yabridge.git
synced 2026-06-16 16:33:55 +02:00
Use the new approach for creating plugin factory
Directly serializing and deserializing into objects was and more boilerplate heavy (since we now need two implementations even though we only use one), and also much less flexible because we can't wrap payloads in structs or provide optional values that way.
This commit is contained in:
@@ -28,8 +28,6 @@
|
||||
|
||||
// TODO: After implementing one or two more of these, abstract away some of the
|
||||
// nasty bits
|
||||
// TODO: Should we have some clearer way to indicate to us which fields are
|
||||
// going to return copied results directly and which make a callback?
|
||||
|
||||
#pragma GCC diagnostic push
|
||||
#pragma GCC diagnostic ignored "-Wnon-virtual-dtor"
|
||||
@@ -40,16 +38,99 @@
|
||||
*/
|
||||
class YaPluginFactory : public Steinberg::IPluginFactory3 {
|
||||
public:
|
||||
YaPluginFactory();
|
||||
/**
|
||||
* These are the arguments for creating a `YaPluginFactoryPluginImpl`.
|
||||
*/
|
||||
struct ConstructArgs {
|
||||
ConstructArgs();
|
||||
|
||||
/**
|
||||
* Create a copy of an existing plugin factory. Depending on the
|
||||
* supported interface function more or less of this struct will be left
|
||||
* empty, and `iid` will be set accordingly.
|
||||
*/
|
||||
ConstructArgs(Steinberg::IPtr<Steinberg::IPluginFactory> factory);
|
||||
|
||||
/**
|
||||
* The IIDs that the interface we serialized supports.
|
||||
*/
|
||||
std::set<Steinberg::FUID> known_iids;
|
||||
|
||||
/**
|
||||
* 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.
|
||||
*/
|
||||
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.ext(known_iids, bitsery::ext::StdSet{32},
|
||||
[](S& s, Steinberg::FUID& iid) {
|
||||
s.ext(iid, bitsery::ext::FUID{});
|
||||
});
|
||||
s.ext(factory_info, bitsery::ext::StdOptional{});
|
||||
s.value4b(num_classes);
|
||||
s.container(class_infos_1, 2048,
|
||||
[](S& s, std::optional<Steinberg::PClassInfo>& info) {
|
||||
s.ext(info, bitsery::ext::StdOptional{});
|
||||
});
|
||||
s.container(class_infos_2, 2048,
|
||||
[](S& s, std::optional<Steinberg::PClassInfo2>& info) {
|
||||
s.ext(info, bitsery::ext::StdOptional{});
|
||||
});
|
||||
s.container(class_infos_unicode, 2048,
|
||||
[](S& s, std::optional<Steinberg::PClassInfoW>& info) {
|
||||
s.ext(info, bitsery::ext::StdOptional{});
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Create a copy of an existing plugin factory. Depending on the supported
|
||||
* interface function more or less of this struct will be left empty, and
|
||||
* `iid` will be set accordingly.
|
||||
* Message to request the `IPluginFactory{,2,3}`'s information from the Wine
|
||||
* plugin host.
|
||||
*/
|
||||
explicit YaPluginFactory(
|
||||
Steinberg::IPtr<Steinberg::IPluginFactory> factory);
|
||||
struct Construct {
|
||||
using Response = ConstructArgs;
|
||||
|
||||
template <typename S>
|
||||
void serialize(S&) {}
|
||||
};
|
||||
|
||||
/**
|
||||
* Instantiate this instance with arguments read from the Windows VST3
|
||||
* plugin's plugin factory.
|
||||
*/
|
||||
YaPluginFactory(const ConstructArgs&& args);
|
||||
|
||||
/**
|
||||
* We do not need to implement the destructor, since when the sockets are
|
||||
* closed, RAII will clean up the Windows VST3 module we loaded along with
|
||||
* its factory for us.
|
||||
*/
|
||||
virtual ~YaPluginFactory();
|
||||
|
||||
DECLARE_FUNKNOWN_METHODS
|
||||
@@ -81,58 +162,8 @@ class YaPluginFactory : public Steinberg::IPluginFactory3 {
|
||||
virtual tresult PLUGIN_API
|
||||
setHostContext(Steinberg::FUnknown* context) override = 0;
|
||||
|
||||
template <typename S>
|
||||
void serialize(S& s) {
|
||||
s.ext(known_iids, bitsery::ext::StdSet{32},
|
||||
[](S& s, Steinberg::FUID& iid) {
|
||||
s.ext(iid, bitsery::ext::FUID{});
|
||||
});
|
||||
s.ext(factory_info, bitsery::ext::StdOptional{});
|
||||
s.value4b(num_classes);
|
||||
s.container(class_infos_1, 2048,
|
||||
[](S& s, std::optional<Steinberg::PClassInfo>& info) {
|
||||
s.ext(info, bitsery::ext::StdOptional{});
|
||||
});
|
||||
s.container(class_infos_2, 2048,
|
||||
[](S& s, std::optional<Steinberg::PClassInfo2>& info) {
|
||||
s.ext(info, bitsery::ext::StdOptional{});
|
||||
});
|
||||
s.container(class_infos_unicode, 2048,
|
||||
[](S& s, std::optional<Steinberg::PClassInfoW>& info) {
|
||||
s.ext(info, bitsery::ext::StdOptional{});
|
||||
});
|
||||
}
|
||||
|
||||
private:
|
||||
/**
|
||||
* The IIDs that the interface we serialized supports.
|
||||
*/
|
||||
std::set<Steinberg::FUID> known_iids;
|
||||
|
||||
/**
|
||||
* 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.
|
||||
*/
|
||||
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;
|
||||
protected:
|
||||
ConstructArgs arguments;
|
||||
};
|
||||
|
||||
#pragma GCC diagnostic pop
|
||||
|
||||
Reference in New Issue
Block a user