From ef3f82e00fb6781d33c8c2f567189c209e181dc3 Mon Sep 17 00:00:00 2001 From: Robbert van der Helm Date: Sat, 5 Dec 2020 23:23:11 +0100 Subject: [PATCH] Implement IpluginFactory2::getClassInfo2 --- .../serialization/vst3/plugin-factory.cpp | 32 ++++++++++++------- .../serialization/vst3/plugin-factory.h | 32 ++++++++++++------- 2 files changed, 42 insertions(+), 22 deletions(-) diff --git a/src/common/serialization/vst3/plugin-factory.cpp b/src/common/serialization/vst3/plugin-factory.cpp index e86ee90c..4291ff9b 100644 --- a/src/common/serialization/vst3/plugin-factory.cpp +++ b/src/common/serialization/vst3/plugin-factory.cpp @@ -22,18 +22,15 @@ YaPluginFactory::YaPluginFactory( Steinberg::IPtr factory) { FUNKNOWN_CTOR - // TODO: Copy data from `IPluginFactory` - // TODO: We should only copy the interfaces that we support. This should use - // the same list as that used in `createInstance()`. known_iids.insert(factory->iid); - + // `IPluginFactory::getFactoryInfo` if (Steinberg::PFactoryInfo info; factory->getFactoryInfo(&info) == Steinberg::kResultOk) { factory_info = info; } - + // `IPluginFactory::countClasses` num_classes = factory->countClasses(); - + // `IPluginFactory::getClassInfo` // TODO: At this point we don't know what this class is and thus we can't // filter unsupported classes, right? class_infos_1.resize(num_classes); @@ -49,8 +46,14 @@ YaPluginFactory::YaPluginFactory( return; } - // TODO: Copy data from `IPluginFactory2` known_iids.insert(factory2->iid); + // `IpluginFactory2::getClassInfo2` + for (int i = 0; i < num_classes; i++) { + Steinberg::PClassInfo2 info; + if (factory2->getClassInfo2(i, &info) == Steinberg::kResultOk) { + class_infos_2[i] = info; + } + } auto factory3 = Steinberg::FUnknownPtr(factory); if (!factory3) { @@ -120,10 +123,17 @@ tresult PLUGIN_API YaPluginFactory::getClassInfo(Steinberg::int32 index, } tresult PLUGIN_API -YaPluginFactory::getClassInfo2(int32 /*index*/, - Steinberg::PClassInfo2* /*info*/) { - // TODO: Implement - return 0; +YaPluginFactory::getClassInfo2(int32 index, Steinberg::PClassInfo2* info) { + if (index >= static_cast(class_infos_1.size())) { + return Steinberg::kInvalidArgument; + } + + if (class_infos_2[index]) { + *info = *class_infos_2[index]; + return Steinberg::kResultOk; + } else { + return Steinberg::kResultFalse; + } } tresult PLUGIN_API diff --git a/src/common/serialization/vst3/plugin-factory.h b/src/common/serialization/vst3/plugin-factory.h index 55b2acde..926c97f4 100644 --- a/src/common/serialization/vst3/plugin-factory.h +++ b/src/common/serialization/vst3/plugin-factory.h @@ -25,9 +25,7 @@ #include "../../bitsery/ext/vst3.h" -namespace { using Steinberg::int32, Steinberg::tresult; -} // namespace // TODO: After implementing one or two more of these, abstract away some of the // nasty bits @@ -43,14 +41,6 @@ using Steinberg::int32, Steinberg::tresult; */ class YaPluginFactory : public Steinberg::IPluginFactory3 { public: - /** - * TODO: Instead of a having a default constructor, we should probably be - * passing a callback to this constructor that lets us communicate - * with the Wine plugin host. - * TODO: Alternative to requiring a bunch of `fu::unique_function<>` - * callbacks would be to make the callback functions pure virtual, and - * then implement those functions directly using `Vst3MessageHandler`. - */ YaPluginFactory(); /** @@ -116,7 +106,10 @@ class YaPluginFactory : public Steinberg::IPluginFactory3 { * doesn't return a class info. */ std::vector> class_infos_1; - // TODO: Callback interface for `createInstance()` + /** + * For `IPluginFactory2::getClassInfo2`, works the same way as the above. + */ + std::vector> class_infos_2; template void serialize(S& s) { @@ -130,6 +123,10 @@ class YaPluginFactory : public Steinberg::IPluginFactory3 { [](S& s, std::optional& info) { s.ext(info, bitsery::ext::StdOptional{}); }); + s.container(class_infos_2, 2048, + [](S& s, std::optional& info) { + s.ext(info, bitsery::ext::StdOptional{}); + }); } }; @@ -146,6 +143,19 @@ void serialize(S& s, PClassInfo& class_info) { s.text1b(class_info.name); } +template +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 void serialize(S& s, PFactoryInfo& factory_info) { s.text1b(factory_info.vendor);