From 4f8eaaaa755b023ba8accce264718b3a73396c30 Mon Sep 17 00:00:00 2001 From: Robbert van der Helm Date: Sat, 13 Feb 2021 15:42:05 +0100 Subject: [PATCH] Refactor plugin factories into Vst3*Proxy format Now every proxy object that's directly created by the host or plugin shares the same structure. --- meson.build | 8 +- src/common/logging/vst3.cpp | 41 +++++---- src/common/logging/vst3.h | 8 +- src/common/serialization/vst3.h | 8 +- src/common/serialization/vst3/README.md | 3 +- .../vst3/plugin-factory-proxy.cpp | 58 +++++++++++++ .../serialization/vst3/plugin-factory-proxy.h | 86 +++++++++++++++++++ .../{ => plugin-factory}/plugin-factory.cpp | 65 +++++--------- .../{ => plugin-factory}/plugin-factory.h | 71 +++++++-------- ...n-factory.cpp => plugin-factory-proxy.cpp} | 29 +++++-- ...lugin-factory.h => plugin-factory-proxy.h} | 19 ++-- src/plugin/bridges/vst3.cpp | 7 +- src/plugin/bridges/vst3.h | 5 +- src/wine-host/bridges/vst3.cpp | 14 +-- 14 files changed, 289 insertions(+), 133 deletions(-) create mode 100644 src/common/serialization/vst3/plugin-factory-proxy.cpp create mode 100644 src/common/serialization/vst3/plugin-factory-proxy.h rename src/common/serialization/vst3/{ => plugin-factory}/plugin-factory.cpp (71%) rename src/common/serialization/vst3/{ => plugin-factory}/plugin-factory.h (81%) rename src/plugin/bridges/vst3-impls/{plugin-factory.cpp => plugin-factory-proxy.cpp} (82%) rename src/plugin/bridges/vst3-impls/{plugin-factory.h => plugin-factory-proxy.h} (70%) diff --git a/meson.build b/meson.build index 52247c46..dadc0fe0 100644 --- a/meson.build +++ b/meson.build @@ -147,6 +147,7 @@ vst3_plugin_sources = [ 'src/common/serialization/vst3/plugin/unit-data.cpp', 'src/common/serialization/vst3/plugin/unit-info.cpp', 'src/common/serialization/vst3/plugin/xml-representation-controller.cpp', + 'src/common/serialization/vst3/plugin-factory/plugin-factory.cpp', 'src/common/serialization/vst3/attribute-list.cpp', 'src/common/serialization/vst3/base.cpp', 'src/common/serialization/vst3/bstream.cpp', @@ -163,14 +164,14 @@ vst3_plugin_sources = [ 'src/common/serialization/vst3/plug-frame-proxy.cpp', 'src/common/serialization/vst3/plug-view-proxy.cpp', 'src/common/serialization/vst3/plugin-proxy.cpp', - 'src/common/serialization/vst3/plugin-factory.cpp', + 'src/common/serialization/vst3/plugin-factory-proxy.cpp', 'src/common/serialization/vst3/process-data.cpp', 'src/common/configuration.cpp', 'src/common/plugins.cpp', 'src/common/utils.cpp', 'src/plugin/bridges/vst3.cpp', 'src/plugin/bridges/vst3-impls/context-menu-target.cpp', - 'src/plugin/bridges/vst3-impls/plugin-factory.cpp', + 'src/plugin/bridges/vst3-impls/plugin-factory-proxy.cpp', 'src/plugin/bridges/vst3-impls/plug-view-proxy.cpp', 'src/plugin/bridges/vst3-impls/plugin-proxy.cpp', 'src/plugin/host-process.cpp', @@ -234,6 +235,7 @@ if with_vst3 'src/common/serialization/vst3/plugin/unit-data.cpp', 'src/common/serialization/vst3/plugin/unit-info.cpp', 'src/common/serialization/vst3/plugin/xml-representation-controller.cpp', + 'src/common/serialization/vst3/plugin-factory/plugin-factory.cpp', 'src/common/serialization/vst3/attribute-list.cpp', 'src/common/serialization/vst3/base.cpp', 'src/common/serialization/vst3/bstream.cpp', @@ -250,7 +252,7 @@ if with_vst3 'src/common/serialization/vst3/plug-frame-proxy.cpp', 'src/common/serialization/vst3/plug-view-proxy.cpp', 'src/common/serialization/vst3/plugin-proxy.cpp', - 'src/common/serialization/vst3/plugin-factory.cpp', + 'src/common/serialization/vst3/plugin-factory-proxy.cpp', 'src/common/serialization/vst3/process-data.cpp', 'src/wine-host/bridges/vst3-impls/component-handler-proxy.cpp', 'src/wine-host/bridges/vst3-impls/connection-point-proxy.cpp', diff --git a/src/common/logging/vst3.cpp b/src/common/logging/vst3.cpp index d08849c3..cd900fd9 100644 --- a/src/common/logging/vst3.cpp +++ b/src/common/logging/vst3.cpp @@ -66,6 +66,12 @@ void Vst3Logger::log_query_interface( } } +bool Vst3Logger::log_request(bool is_host_vst, + const Vst3PluginFactoryProxy::Construct&) { + return log_request_base( + is_host_vst, [&](auto& message) { message << "GetPluginFactory()"; }); +} + bool Vst3Logger::log_request(bool is_host_vst, const Vst3PlugViewProxy::Destruct& request) { return log_request_base(is_host_vst, [&](auto& message) { @@ -690,13 +696,7 @@ bool Vst3Logger::log_request(bool is_host_vst, } bool Vst3Logger::log_request(bool is_host_vst, - const YaPluginFactory::Construct&) { - return log_request_base( - is_host_vst, [&](auto& message) { message << "GetPluginFactory()"; }); -} - -bool Vst3Logger::log_request(bool is_host_vst, - const YaPluginFactory::SetHostContext&) { + const YaPluginFactory3::SetHostContext&) { return log_request_base(is_host_vst, [&](auto& message) { message << "IPluginFactory3::setHostContext(context = )"; }); @@ -1381,6 +1381,25 @@ void Vst3Logger::log_response(bool is_host_vst, const Ack&) { log_response_base(is_host_vst, [&](auto& message) { message << "ACK"; }); } +void Vst3Logger::log_response( + bool is_host_vst, + const Vst3PluginFactoryProxy::ConstructArgs& args) { + log_response_base(is_host_vst, [&](auto& message) { + message << "<"; + if (args.plugin_factory_args.supports_plugin_factory_3) { + message << "IPluginFactory3*"; + } else if (args.plugin_factory_args.supports_plugin_factory_2) { + message << "IPluginFactory2*"; + } else if (args.plugin_factory_args.supports_plugin_factory) { + message << "IPluginFactory*"; + } else { + message << "FUnknown*"; + } + message << " with " << args.plugin_factory_args.num_classes + << " registered classes>"; + }); +} + void Vst3Logger::log_response(bool is_host_vst, const std::variant& result) { @@ -1591,14 +1610,6 @@ void Vst3Logger::log_response( }); } -void Vst3Logger::log_response(bool is_host_vst, - const YaPluginFactory::ConstructArgs& args) { - log_response_base(is_host_vst, [&](auto& message) { - message << ""; - }); -} - void Vst3Logger::log_response(bool is_host_vst, const Configuration&) { log_response_base(is_host_vst, [&](auto& message) { message << ""; }); diff --git a/src/common/logging/vst3.h b/src/common/logging/vst3.h index 89db7214..a1b79cc3 100644 --- a/src/common/logging/vst3.h +++ b/src/common/logging/vst3.h @@ -61,6 +61,8 @@ class Vst3Logger { // `log_request()` call returned `true`. This way we can filter out the // log message for the response together with the request. + bool log_request(bool is_host_vst, + const Vst3PluginFactoryProxy::Construct&); bool log_request(bool is_host_vst, const Vst3PlugViewProxy::Destruct&); bool log_request(bool is_host_vst, const Vst3PluginProxy::Construct&); bool log_request(bool is_host_vst, const Vst3PluginProxy::Destruct&); @@ -149,8 +151,7 @@ class Vst3Logger { const YaPlugViewContentScaleSupport::SetContentScaleFactor&); bool log_request(bool is_host_vst, const YaPluginBase::Initialize&); bool log_request(bool is_host_vst, const YaPluginBase::Terminate&); - bool log_request(bool is_host_vst, const YaPluginFactory::Construct&); - bool log_request(bool is_host_vst, const YaPluginFactory::SetHostContext&); + bool log_request(bool is_host_vst, const YaPluginFactory3::SetHostContext&); bool log_request( bool is_host_vst, const YaProcessContextRequirements::GetProcessContextRequirements&); @@ -241,6 +242,8 @@ class Vst3Logger { const YaUnitHandler2::NotifyUnitByBusChange&); void log_response(bool is_host_vst, const Ack&); + void log_response(bool is_host_vst, + const Vst3PluginFactoryProxy::ConstructArgs&); void log_response( bool is_host_vst, const std::variant&); @@ -280,7 +283,6 @@ class Vst3Logger { void log_response(bool is_host_vst, const YaPlugView::GetSizeResponse&); void log_response(bool is_host_vst, const YaPlugView::CheckSizeConstraintResponse&); - void log_response(bool is_host_vst, const YaPluginFactory::ConstructArgs&); void log_response(bool is_host_vst, const Configuration&); void log_response(bool is_host_vst, const YaProgramListData::GetProgramDataResponse&); diff --git a/src/common/serialization/vst3.h b/src/common/serialization/vst3.h index b54b2e50..3f922a1a 100644 --- a/src/common/serialization/vst3.h +++ b/src/common/serialization/vst3.h @@ -30,7 +30,7 @@ #include "vst3/host-context-proxy.h" #include "vst3/plug-frame-proxy.h" #include "vst3/plug-view-proxy.h" -#include "vst3/plugin-factory.h" +#include "vst3/plugin-factory-proxy.h" #include "vst3/plugin-proxy.h" // Event handling for our VST3 plugins works slightly different from how we @@ -65,7 +65,8 @@ struct WantsConfiguration { * request of type `ControlRequest(T)` should send back a `T::Response`. */ using ControlRequest = - std::variant. + +#include "plugin-factory-proxy.h" + +Vst3PluginFactoryProxy::ConstructArgs::ConstructArgs() {} + +Vst3PluginFactoryProxy::ConstructArgs::ConstructArgs( + Steinberg::IPtr object) + : plugin_factory_args(object) {} + +Vst3PluginFactoryProxy::Vst3PluginFactoryProxy(const ConstructArgs&& args) + : YaPluginFactory3(std::move(args.plugin_factory_args)), + arguments(std::move(args)){FUNKNOWN_CTOR} + + // clang-format just doesn't understand these macros, I guess + Vst3PluginFactoryProxy::~Vst3PluginFactoryProxy() { + FUNKNOWN_DTOR +} + +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wdelete-non-virtual-dtor" +IMPLEMENT_REFCOUNT(Vst3PluginFactoryProxy) +#pragma GCC diagnostic pop + +tresult PLUGIN_API +Vst3PluginFactoryProxy::queryInterface(Steinberg::FIDString _iid, void** obj) { + if (YaPluginFactory3::supports_plugin_factory()) { + QUERY_INTERFACE(_iid, obj, Steinberg::FUnknown::iid, + Steinberg::IPluginFactory) + QUERY_INTERFACE(_iid, obj, Steinberg::IPluginFactory::iid, + Steinberg::IPluginFactory) + } + if (YaPluginFactory3::supports_plugin_factory_2()) { + QUERY_INTERFACE(_iid, obj, Steinberg::IPluginFactory2::iid, + Steinberg::IPluginFactory2) + } + if (YaPluginFactory3::supports_plugin_factory_3()) { + QUERY_INTERFACE(_iid, obj, Steinberg::IPluginFactory3::iid, + Steinberg::IPluginFactory3) + } + + *obj = nullptr; + return Steinberg::kNoInterface; +} diff --git a/src/common/serialization/vst3/plugin-factory-proxy.h b/src/common/serialization/vst3/plugin-factory-proxy.h new file mode 100644 index 00000000..804befa3 --- /dev/null +++ b/src/common/serialization/vst3/plugin-factory-proxy.h @@ -0,0 +1,86 @@ +// yabridge: a Wine VST bridge +// Copyright (C) 2020-2021 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 . + +#pragma once + +#include "../common.h" +#include "plugin-factory/plugin-factory.h" + +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wnon-virtual-dtor" + +/** + * An abstract class that `IPluginFactory`, and optionally also + * `IPluginFactory2` and `IPluginFactory3` depending on what the Windows VST3 + * plugin's plugin factory supports. All information is read once the Wine + * plugin host side, so the only callbacks that we'll make from here are to + * create new objects and to set a host context for the factory (if the host and + * the plugin supports that). + */ +class Vst3PluginFactoryProxy : public YaPluginFactory3 { + public: + /** + * These are the arguments for constructing a `Vst3PluginFactoryProxyImpl`. + */ + struct ConstructArgs { + ConstructArgs(); + + /** + * Read from an existing object. We will try to mimic this object, so + * we'll support any interfaces this object also supports. + */ + ConstructArgs(Steinberg::IPtr object); + + YaPluginFactory3::ConstructArgs plugin_factory_args; + + template + void serialize(S& s) { + s.object(plugin_factory_args); + } + }; + + /** + * Message to request the Windows VST3 plugin's plugin factory information + * from the Wine plugin host. + */ + struct Construct { + using Response = ConstructArgs; + + template + void serialize(S&) {} + }; + + /** + * Instantiate this instance with arguments read from an actual plugin + * factory. The is done once during startup and the plugin factory gets + * reused for the lifetime of the module. + */ + Vst3PluginFactoryProxy(const ConstructArgs&& args); + + /** + * We do not need special handling here since the Window VST3 plugin's + * plugin factory will also be destroyed when we terminate the Wine plugin + * host or unload the plugin there. + */ + virtual ~Vst3PluginFactoryProxy(); + + DECLARE_FUNKNOWN_METHODS + + private: + ConstructArgs arguments; +}; + +#pragma GCC diagnostic pop diff --git a/src/common/serialization/vst3/plugin-factory.cpp b/src/common/serialization/vst3/plugin-factory/plugin-factory.cpp similarity index 71% rename from src/common/serialization/vst3/plugin-factory.cpp rename to src/common/serialization/vst3/plugin-factory/plugin-factory.cpp index ceb7c606..ea3a0108 100644 --- a/src/common/serialization/vst3/plugin-factory.cpp +++ b/src/common/serialization/vst3/plugin-factory/plugin-factory.cpp @@ -21,10 +21,16 @@ #include -YaPluginFactory::ConstructArgs::ConstructArgs() {} +YaPluginFactory3::ConstructArgs::ConstructArgs() {} -YaPluginFactory::ConstructArgs::ConstructArgs( - Steinberg::IPtr factory) { +YaPluginFactory3::ConstructArgs::ConstructArgs( + Steinberg::IPtr object) { + Steinberg::FUnknownPtr factory(object); + if (!factory) { + return; + } + + supports_plugin_factory = true; // `IPluginFactory::getFactoryInfo` if (Steinberg::PFactoryInfo info; factory->getFactoryInfo(&info) == Steinberg::kResultOk) { @@ -93,40 +99,11 @@ YaPluginFactory::ConstructArgs::ConstructArgs( } } -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) - QUERY_INTERFACE(_iid, obj, Steinberg::IPluginFactory::iid, - Steinberg::IPluginFactory) - if (arguments.supports_plugin_factory_2) { - QUERY_INTERFACE(_iid, obj, Steinberg::IPluginFactory2::iid, - Steinberg::IPluginFactory2) - } - if (arguments.supports_plugin_factory_3) { - QUERY_INTERFACE(_iid, obj, Steinberg::IPluginFactory3::iid, - Steinberg::IPluginFactory3) - } - - *obj = nullptr; - return Steinberg::kNoInterface; -} +YaPluginFactory3::YaPluginFactory3(const ConstructArgs&& args) + : arguments(std::move(args)) {} tresult PLUGIN_API -YaPluginFactory::getFactoryInfo(Steinberg::PFactoryInfo* info) { +YaPluginFactory3::getFactoryInfo(Steinberg::PFactoryInfo* info) { if (info && arguments.factory_info) { *info = *arguments.factory_info; return Steinberg::kResultOk; @@ -135,18 +112,18 @@ YaPluginFactory::getFactoryInfo(Steinberg::PFactoryInfo* info) { } } -int32 PLUGIN_API YaPluginFactory::countClasses() { +int32 PLUGIN_API YaPluginFactory3::countClasses() { return arguments.num_classes; } -tresult PLUGIN_API YaPluginFactory::getClassInfo(Steinberg::int32 index, - Steinberg::PClassInfo* info) { +tresult PLUGIN_API YaPluginFactory3::getClassInfo(Steinberg::int32 index, + Steinberg::PClassInfo* info) { if (index >= static_cast(arguments.class_infos_1.size())) { return Steinberg::kInvalidArgument; } // We will have already converted these class IDs to the native - // representation in `YaPluginFactory::ConstructArgs` + // representation in `YaPluginFactory3::ConstructArgs` if (arguments.class_infos_1[index]) { *info = *arguments.class_infos_1[index]; return Steinberg::kResultOk; @@ -156,13 +133,13 @@ tresult PLUGIN_API YaPluginFactory::getClassInfo(Steinberg::int32 index, } tresult PLUGIN_API -YaPluginFactory::getClassInfo2(int32 index, Steinberg::PClassInfo2* info) { +YaPluginFactory3::getClassInfo2(int32 index, Steinberg::PClassInfo2* info) { if (index >= static_cast(arguments.class_infos_2.size())) { return Steinberg::kInvalidArgument; } // We will have already converted these class IDs to the native - // representation in `YaPluginFactory::ConstructArgs` + // representation in `YaPluginFactory3::ConstructArgs` if (arguments.class_infos_2[index]) { *info = *arguments.class_infos_2[index]; return Steinberg::kResultOk; @@ -172,14 +149,14 @@ YaPluginFactory::getClassInfo2(int32 index, Steinberg::PClassInfo2* info) { } tresult PLUGIN_API -YaPluginFactory::getClassInfoUnicode(int32 index, - Steinberg::PClassInfoW* info) { +YaPluginFactory3::getClassInfoUnicode(int32 index, + Steinberg::PClassInfoW* info) { if (index >= static_cast(arguments.class_infos_unicode.size())) { return Steinberg::kInvalidArgument; } // We will have already converted these class IDs to the native - // representation in `YaPluginFactory::ConstructArgs` + // representation in `YaPluginFactory3::ConstructArgs` if (arguments.class_infos_unicode[index]) { *info = *arguments.class_infos_unicode[index]; return Steinberg::kResultOk; diff --git a/src/common/serialization/vst3/plugin-factory.h b/src/common/serialization/vst3/plugin-factory/plugin-factory.h similarity index 81% rename from src/common/serialization/vst3/plugin-factory.h rename to src/common/serialization/vst3/plugin-factory/plugin-factory.h index e4bc6028..ceb3664f 100644 --- a/src/common/serialization/vst3/plugin-factory.h +++ b/src/common/serialization/vst3/plugin-factory/plugin-factory.h @@ -20,40 +20,45 @@ #include #include -#include "base.h" -#include "host-context-proxy.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. See - * `docs/vst3.md` for more information on how this works. - * - * TODO: Redo this in the new 'Vst3PluginFactoryProxy' style + * Wraps around `IPluginFactory{1,2,3}` for serialization purposes. This is + * instantiated as part of `Vst3PluginFactoryProxy`. */ -class YaPluginFactory : public Steinberg::IPluginFactory3 { +class YaPluginFactory3 : public Steinberg::IPluginFactory3 { public: /** - * These are the arguments for constructing a `YaPluginFactoryImpl`. + * 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(); /** - * 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 `known_iids` will be set accordingly. + * Check whether an existing implementation implements + * `IPluginFactory1`, `IPluginFactory2`, and ``IPluginFactory3`` and + * read arguments from it. */ - ConstructArgs(Steinberg::IPtr factory); + ConstructArgs(Steinberg::IPtr object); /** - * Whether `factory` supported `IPluginFactory2`. + * Whether the object supported `IPluginFactory`. + */ + bool supports_plugin_factory = false; + + /** + * Whether the object supported `IPluginFactory2`. */ bool supports_plugin_factory_2 = false; /** - * Whether `factory` supported `IPluginFactory3`. + * Whether the object supported `IPluginFactory3`. */ bool supports_plugin_factory_3 = false; @@ -93,6 +98,7 @@ class YaPluginFactory : public Steinberg::IPluginFactory3 { template 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::StdOptional{}); @@ -112,31 +118,27 @@ class YaPluginFactory : public Steinberg::IPluginFactory3 { } }; - /** - * Message to request the `IPluginFactory{,2,3}`'s information from the Wine - * plugin host. - */ - struct Construct { - using Response = ConstructArgs; - - template - void serialize(S&) {} - }; - /** * Instantiate this instance with arguments read from the Windows VST3 * plugin's plugin factory. */ - YaPluginFactory(const ConstructArgs&& args); + YaPluginFactory3(const ConstructArgs&& args); - /** - * We do not need to implement the destructor in `YaPluginFactoryImpl`, - * since when the sockets are closed, RAII will clean up the Windows VST3 - * module we loaded along with its factory for us. - */ - virtual ~YaPluginFactory(); + inline bool supports_plugin_factory() const { + return arguments.supports_plugin_factory; + } - DECLARE_FUNKNOWN_METHODS + inline bool supports_plugin_factory_2() const { + return arguments.supports_plugin_factory_2; + } + + inline bool supports_plugin_factory_3() const { + 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; @@ -144,7 +146,8 @@ class YaPluginFactory : public Steinberg::IPluginFactory3 { tresult PLUGIN_API getClassInfo(Steinberg::int32 index, Steinberg::PClassInfo* info) override; /** - * See the implementation in `YaPluginFactoryImpl` for how this is handled. + * 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, diff --git a/src/plugin/bridges/vst3-impls/plugin-factory.cpp b/src/plugin/bridges/vst3-impls/plugin-factory-proxy.cpp similarity index 82% rename from src/plugin/bridges/vst3-impls/plugin-factory.cpp rename to src/plugin/bridges/vst3-impls/plugin-factory-proxy.cpp index 0317c788..b2b7ba91 100644 --- a/src/plugin/bridges/vst3-impls/plugin-factory.cpp +++ b/src/plugin/bridges/vst3-impls/plugin-factory-proxy.cpp @@ -14,21 +14,32 @@ // You should have received a copy of the GNU General Public License // along with this program. If not, see . -#include "plugin-factory.h" +#include "plugin-factory-proxy.h" #include #include "../vst3.h" #include "plugin-proxy.h" -YaPluginFactoryImpl::YaPluginFactoryImpl(Vst3PluginBridge& bridge, - YaPluginFactory::ConstructArgs&& args) - : YaPluginFactory(std::move(args)), bridge(bridge) {} +Vst3PluginFactoryProxyImpl::Vst3PluginFactoryProxyImpl( + Vst3PluginBridge& bridge, + Vst3PluginFactoryProxy::ConstructArgs&& args) + : Vst3PluginFactoryProxy(std::move(args)), bridge(bridge) {} tresult PLUGIN_API -YaPluginFactoryImpl::createInstance(Steinberg::FIDString cid, - Steinberg::FIDString _iid, - void** obj) { +Vst3PluginFactoryProxyImpl::queryInterface(const Steinberg::TUID _iid, + void** obj) { + const tresult result = Vst3PluginFactoryProxy::queryInterface(_iid, obj); + bridge.logger.log_query_interface("In IPluginFactory::queryInterface()", + result, Steinberg::FUID::fromTUID(_iid)); + + return result; +} + +tresult PLUGIN_API +Vst3PluginFactoryProxyImpl::createInstance(Steinberg::FIDString cid, + Steinberg::FIDString _iid, + void** obj) { // Class IDs may be padded with null bytes constexpr size_t uid_size = sizeof(Steinberg::TUID); if (!cid || !_iid || !obj || strnlen(_iid, uid_size) < uid_size) { @@ -94,7 +105,7 @@ YaPluginFactoryImpl::createInstance(Steinberg::FIDString cid, } tresult PLUGIN_API -YaPluginFactoryImpl::setHostContext(Steinberg::FUnknown* context) { +Vst3PluginFactoryProxyImpl::setHostContext(Steinberg::FUnknown* context) { if (context) { // We will create a proxy object that that supports all the same // interfaces as `context`, and then we'll store `context` in this @@ -107,7 +118,7 @@ YaPluginFactoryImpl::setHostContext(Steinberg::FUnknown* context) { host_application = host_context; plug_interface_support = host_context; - return bridge.send_message(YaPluginFactory::SetHostContext{ + return bridge.send_message(YaPluginFactory3::SetHostContext{ .host_context_args = Vst3HostContextProxy::ConstructArgs( host_context, std::nullopt)}); } else { diff --git a/src/plugin/bridges/vst3-impls/plugin-factory.h b/src/plugin/bridges/vst3-impls/plugin-factory-proxy.h similarity index 70% rename from src/plugin/bridges/vst3-impls/plugin-factory.h rename to src/plugin/bridges/vst3-impls/plugin-factory-proxy.h index 86c84bfe..9615989f 100644 --- a/src/plugin/bridges/vst3-impls/plugin-factory.h +++ b/src/plugin/bridges/vst3-impls/plugin-factory-proxy.h @@ -16,16 +16,23 @@ #pragma once -#include "../../../common/serialization/vst3/plugin-factory.h" +#include "../../../common/serialization/vst3/plugin-factory-proxy.h" -// We need an `IPtr` in `Vst3PluginBridge`, so we need to -// declare this slightly differently to avoid circular includes. +// We need an `IPtr` in `Vst3PluginBridge`, so we +// need to declare this slightly differently to avoid circular includes. class Vst3PluginBridge; -class YaPluginFactoryImpl : public YaPluginFactory { +class Vst3PluginFactoryProxyImpl : public Vst3PluginFactoryProxy { public: - YaPluginFactoryImpl(Vst3PluginBridge& bridge, - YaPluginFactory::ConstructArgs&& args); + Vst3PluginFactoryProxyImpl(Vst3PluginBridge& bridge, + Vst3PluginFactoryProxy::ConstructArgs&& args); + + /** + * We'll override the query interface to log queries for interfaces we do + * not (yet) support. + */ + tresult PLUGIN_API queryInterface(const Steinberg::TUID _iid, + void** obj) override; tresult PLUGIN_API createInstance(Steinberg::FIDString cid, Steinberg::FIDString _iid, diff --git a/src/plugin/bridges/vst3.cpp b/src/plugin/bridges/vst3.cpp index d67617dd..1f6ed9fc 100644 --- a/src/plugin/bridges/vst3.cpp +++ b/src/plugin/bridges/vst3.cpp @@ -18,7 +18,6 @@ #include "src/common/serialization/vst3.h" #include "vst3-impls/context-menu-target.h" -#include "vst3-impls/plugin-factory.h" #include "vst3-impls/plugin-proxy.h" using namespace std::literals::string_literals; @@ -368,12 +367,12 @@ Steinberg::IPluginFactory* Vst3PluginBridge::get_plugin_factory() { // will request after loading the module. Host callback handlers should // have started before this since the Wine plugin host will request a // copy of the configuration during its initialization. - YaPluginFactory::ConstructArgs factory_args = + Vst3PluginFactoryProxy::ConstructArgs factory_args = sockets.host_vst_control.send_message( - YaPluginFactory::Construct{}, + Vst3PluginFactoryProxy::Construct{}, std::pair(logger, true)); plugin_factory = Steinberg::owned( - new YaPluginFactoryImpl(*this, std::move(factory_args))); + new Vst3PluginFactoryProxyImpl(*this, std::move(factory_args))); } // Because we're returning a raw pointer, we have to increase the reference diff --git a/src/plugin/bridges/vst3.h b/src/plugin/bridges/vst3.h index 19cd3776..0dd1c6c5 100644 --- a/src/plugin/bridges/vst3.h +++ b/src/plugin/bridges/vst3.h @@ -18,11 +18,10 @@ #include -#include "../..//common/serialization/vst3/plugin-factory.h" #include "../../common/communication/vst3.h" #include "../../common/logging/vst3.h" #include "common.h" -#include "vst3-impls/plugin-factory.h" +#include "vst3-impls/plugin-factory-proxy.h" // Forward declarations class Vst3PluginProxyImpl; @@ -143,7 +142,7 @@ class Vst3PluginBridge : PluginBridge> { * * @related get_plugin_factory */ - Steinberg::IPtr plugin_factory = nullptr; + Steinberg::IPtr plugin_factory = nullptr; private: /** diff --git a/src/wine-host/bridges/vst3.cpp b/src/wine-host/bridges/vst3.cpp index 7b9e9cb8..5402ce63 100644 --- a/src/wine-host/bridges/vst3.cpp +++ b/src/wine-host/bridges/vst3.cpp @@ -113,6 +113,11 @@ void Vst3Bridge::run() { sockets.host_vst_control.receive_messages( std::nullopt, overload{ + [&](const Vst3PluginFactoryProxy::Construct&) + -> Vst3PluginFactoryProxy::Construct::Response { + return Vst3PluginFactoryProxy::ConstructArgs( + module->getFactory().get()); + }, [&](const Vst3PlugViewProxy::Destruct& request) -> Vst3PlugViewProxy::Destruct::Response { main_context @@ -927,13 +932,8 @@ void Vst3Bridge::run() { return object_instances[request.instance_id] .unit_data->setUnitData(request.unit_id, &request.data); }, - [&](const YaPluginFactory::Construct&) - -> YaPluginFactory::Construct::Response { - return YaPluginFactory::ConstructArgs( - module->getFactory().get()); - }, - [&](YaPluginFactory::SetHostContext& request) - -> YaPluginFactory::SetHostContext::Response { + [&](YaPluginFactory3::SetHostContext& request) + -> YaPluginFactory3::SetHostContext::Response { plugin_factory_host_context = Steinberg::owned(new Vst3HostContextProxyImpl( *this, std::move(request.host_context_args)));