mirror of
https://github.com/robbert-vdh/yabridge.git
synced 2026-05-07 20:10:13 +02:00
39984ad442
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.
166 lines
5.4 KiB
C++
166 lines
5.4 KiB
C++
// yabridge: a Wine VST bridge
|
|
// Copyright (C) 2020 Robbert van der Helm
|
|
//
|
|
// This program is free software: you can redistribute it and/or modify
|
|
// it under the terms of the GNU General Public License as published by
|
|
// the Free Software Foundation, either version 3 of the License, or
|
|
// (at your option) any later version.
|
|
//
|
|
// This program is distributed in the hope that it will be useful,
|
|
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
// GNU General Public License for more details.
|
|
//
|
|
// You should have received a copy of the GNU General Public License
|
|
// along with this program. If not, see <https://www.gnu.org/licenses/>.
|
|
|
|
#include "plugin-factory.h"
|
|
|
|
#include <iostream>
|
|
#include <type_traits>
|
|
|
|
#include <public.sdk/source/vst/utility/stringconvert.h>
|
|
|
|
YaPluginFactory::ConstructArgs::ConstructArgs() {}
|
|
|
|
YaPluginFactory::ConstructArgs::ConstructArgs(
|
|
Steinberg::IPtr<Steinberg::IPluginFactory> factory) {
|
|
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`
|
|
class_infos_1.resize(num_classes);
|
|
for (int i = 0; i < num_classes; i++) {
|
|
Steinberg::PClassInfo info;
|
|
if (factory->getClassInfo(i, &info) == Steinberg::kResultOk) {
|
|
class_infos_1[i] = info;
|
|
}
|
|
}
|
|
|
|
auto factory2 = Steinberg::FUnknownPtr<Steinberg::IPluginFactory2>(factory);
|
|
if (!factory2) {
|
|
return;
|
|
}
|
|
|
|
known_iids.insert(factory2->iid);
|
|
// `IpluginFactory2::getClassInfo2`
|
|
class_infos_2.resize(num_classes);
|
|
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<Steinberg::IPluginFactory3>(factory);
|
|
if (!factory3) {
|
|
return;
|
|
}
|
|
|
|
known_iids.insert(factory3->iid);
|
|
// `IpluginFactory3::getClassInfoUnicode`
|
|
class_infos_unicode.resize(num_classes);
|
|
for (int i = 0; i < num_classes; i++) {
|
|
Steinberg::PClassInfoW info;
|
|
if (factory3->getClassInfoUnicode(i, &info) == Steinberg::kResultOk) {
|
|
class_infos_unicode[i] = info;
|
|
}
|
|
}
|
|
}
|
|
|
|
YaPluginFactory::YaPluginFactory(const ConstructArgs&& args)
|
|
: arguments(std::move(args)){FUNKNOWN_CTOR}
|
|
|
|
// clang-format just doesn't understand these macros, I guess
|
|
YaPluginFactory::~YaPluginFactory() {
|
|
FUNKNOWN_DTOR
|
|
}
|
|
|
|
#pragma GCC diagnostic push
|
|
#pragma GCC diagnostic ignored "-Wdelete-non-virtual-dtor"
|
|
IMPLEMENT_REFCOUNT(YaPluginFactory)
|
|
#pragma GCC diagnostic pop
|
|
|
|
tresult PLUGIN_API YaPluginFactory::queryInterface(Steinberg::FIDString _iid,
|
|
void** obj) {
|
|
QUERY_INTERFACE(_iid, obj, Steinberg::FUnknown::iid,
|
|
Steinberg::IPluginFactory)
|
|
if (arguments.known_iids.contains(Steinberg::IPluginFactory::iid)) {
|
|
QUERY_INTERFACE(_iid, obj, Steinberg::IPluginFactory::iid,
|
|
Steinberg::IPluginFactory)
|
|
}
|
|
if (arguments.known_iids.contains(Steinberg::IPluginFactory2::iid)) {
|
|
QUERY_INTERFACE(_iid, obj, Steinberg::IPluginFactory2::iid,
|
|
Steinberg::IPluginFactory2)
|
|
}
|
|
if (arguments.known_iids.contains(Steinberg::IPluginFactory3::iid)) {
|
|
QUERY_INTERFACE(_iid, obj, Steinberg::IPluginFactory3::iid,
|
|
Steinberg::IPluginFactory3)
|
|
}
|
|
|
|
*obj = nullptr;
|
|
return Steinberg::kNoInterface;
|
|
}
|
|
|
|
tresult PLUGIN_API
|
|
YaPluginFactory::getFactoryInfo(Steinberg::PFactoryInfo* info) {
|
|
if (info && arguments.factory_info) {
|
|
*info = *arguments.factory_info;
|
|
return Steinberg::kResultOk;
|
|
} else {
|
|
return Steinberg::kNotInitialized;
|
|
}
|
|
}
|
|
|
|
int32 PLUGIN_API YaPluginFactory::countClasses() {
|
|
return arguments.num_classes;
|
|
}
|
|
|
|
tresult PLUGIN_API YaPluginFactory::getClassInfo(Steinberg::int32 index,
|
|
Steinberg::PClassInfo* info) {
|
|
if (index >= static_cast<int32>(arguments.class_infos_unicode.size())) {
|
|
return Steinberg::kInvalidArgument;
|
|
}
|
|
|
|
if (arguments.class_infos_1[index]) {
|
|
*info = *arguments.class_infos_1[index];
|
|
return Steinberg::kResultOk;
|
|
} else {
|
|
return Steinberg::kResultFalse;
|
|
}
|
|
}
|
|
|
|
tresult PLUGIN_API
|
|
YaPluginFactory::getClassInfo2(int32 index, Steinberg::PClassInfo2* info) {
|
|
if (index >= static_cast<int32>(arguments.class_infos_1.size())) {
|
|
return Steinberg::kInvalidArgument;
|
|
}
|
|
|
|
if (arguments.class_infos_2[index]) {
|
|
*info = *arguments.class_infos_2[index];
|
|
return Steinberg::kResultOk;
|
|
} else {
|
|
return Steinberg::kResultFalse;
|
|
}
|
|
}
|
|
|
|
tresult PLUGIN_API
|
|
YaPluginFactory::getClassInfoUnicode(int32 index,
|
|
Steinberg::PClassInfoW* info) {
|
|
if (index >= static_cast<int32>(arguments.class_infos_unicode.size())) {
|
|
return Steinberg::kInvalidArgument;
|
|
}
|
|
|
|
if (arguments.class_infos_unicode[index]) {
|
|
*info = *arguments.class_infos_unicode[index];
|
|
return Steinberg::kResultOk;
|
|
} else {
|
|
return Steinberg::kResultFalse;
|
|
}
|
|
}
|