From 3be5836c071476b2f522600d2d29d8ee0d88e096 Mon Sep 17 00:00:00 2001 From: Robbert van der Helm Date: Sun, 6 Dec 2020 00:51:20 +0100 Subject: [PATCH] Log and ignore unsupported interfaces --- .../serialization/vst3/plugin-factory.cpp | 64 ++++++++++++++++++- 1 file changed, 61 insertions(+), 3 deletions(-) diff --git a/src/common/serialization/vst3/plugin-factory.cpp b/src/common/serialization/vst3/plugin-factory.cpp index 9ea34214..08a21ac3 100644 --- a/src/common/serialization/vst3/plugin-factory.cpp +++ b/src/common/serialization/vst3/plugin-factory.cpp @@ -16,6 +16,28 @@ #include "plugin-factory.h" +#include +#include + +#include +#include +#include +#include +#include +#include +#include + +/** + * Return whether yabridge supports this class or not. This way we can skip over + * any classes that the plugin might support but we have not implemented yet. If + * we do not support a class, we will log it. + * + * @tparam Any of `Steinberg::PClassInfo`, `Steinberg::PClassInfo2` or + * `Steinberg::PClassInfoW`. + */ +template +bool is_supported_interface(const T& class_info); + YaPluginFactory::YaPluginFactory(){FUNKNOWN_CTOR} YaPluginFactory::YaPluginFactory( @@ -36,7 +58,8 @@ YaPluginFactory::YaPluginFactory( class_infos_1.resize(num_classes); for (int i = 0; i < num_classes; i++) { Steinberg::PClassInfo info; - if (factory->getClassInfo(i, &info) == Steinberg::kResultOk) { + if (factory->getClassInfo(i, &info) == Steinberg::kResultOk && + is_supported_interface(info)) { class_infos_1[i] = info; } } @@ -50,7 +73,8 @@ YaPluginFactory::YaPluginFactory( // `IpluginFactory2::getClassInfo2` for (int i = 0; i < num_classes; i++) { Steinberg::PClassInfo2 info; - if (factory2->getClassInfo2(i, &info) == Steinberg::kResultOk) { + if (factory2->getClassInfo2(i, &info) == Steinberg::kResultOk && + is_supported_interface(info)) { class_infos_2[i] = info; } } @@ -64,7 +88,8 @@ YaPluginFactory::YaPluginFactory( // `IpluginFactory3::getClassInfoUnicode` for (int i = 0; i < num_classes; i++) { Steinberg::PClassInfoW info; - if (factory3->getClassInfoUnicode(i, &info) == Steinberg::kResultOk) { + if (factory3->getClassInfoUnicode(i, &info) == Steinberg::kResultOk && + is_supported_interface(info)) { class_infos_unicode[i] = info; } } @@ -156,3 +181,36 @@ YaPluginFactory::getClassInfoUnicode(int32 index, return Steinberg::kResultFalse; } } + +template +bool is_supported_interface(const T& class_info) { + // I feel like we're not supposed to use this comparison function, but they + // don't offer any other ways to compare FUIDs/TUIDs + // TODO: Add these interfaces as we go along + if (Steinberg::FUnknownPrivate::iidEqual(class_info.cid, + Steinberg::Vst::IComponent::iid) + // || + // Steinberg::FUnknownPrivate::iidEqual( + // cid, Steinberg::Vst::IAudioProcessor::iid) || + // Steinberg::FUnknownPrivate::iidEqual( + // cid, Steinberg::Vst::IEditController::iid) + ) { + return true; + } else { + // TODO: These prints get logged correctly because we do this from the + // Wine side, but for neater logging we should add these to a list + // instead and then print them all when we receive the factory + // instance on the plugin's side + std::string class_name = VST3::StringConvert::convert( + class_info.name, Steinberg::PClassInfo::kNameSize); + + char interface_id_str[128]; + Steinberg::FUID(class_info.cid) + .print(interface_id_str, Steinberg::FUID::UIDPrintStyle::kFUID); + + std::cerr << "Unsupported interface '" << class_name + << "': " << interface_id_str << std::endl; + + return false; + } +}