mirror of
https://github.com/robbert-vdh/yabridge.git
synced 2026-05-13 20:09:59 +02:00
Split off IComponent and create a monolithic class
We can now use implement all VST3 plugin interfaces through this class, check whether the object from the plugin also supports these classes, and then conditionally allow casting to the supported classes. This should give us a one-to-one proxy of the original object.
This commit is contained in:
@@ -23,8 +23,8 @@
|
||||
#include "../configuration.h"
|
||||
#include "../utils.h"
|
||||
#include "common.h"
|
||||
#include "vst3/component.h"
|
||||
#include "vst3/plugin-factory.h"
|
||||
#include "vst3/plugin-monolith.h"
|
||||
|
||||
// Event handling for our VST3 plugins works slightly different from how we
|
||||
// handle VST2 plugins. VST3 does not have a centralized event dispatching
|
||||
@@ -57,8 +57,16 @@ struct WantsConfiguration {
|
||||
* encodes the information we request or the operation we want to perform. A
|
||||
* request of type `ControlRequest(T)` should send back a `T::Response`.
|
||||
*/
|
||||
using ControlRequest = std::variant<YaComponent::Construct,
|
||||
YaComponent::Destruct,
|
||||
using ControlRequest = std::variant<YaPluginMonolith::Construct,
|
||||
YaPluginMonolith::Destruct,
|
||||
YaAudioProcessor::SetBusArrangements,
|
||||
YaAudioProcessor::GetBusArrangement,
|
||||
YaAudioProcessor::CanProcessSampleSize,
|
||||
YaAudioProcessor::GetLatencySamples,
|
||||
YaAudioProcessor::SetupProcessing,
|
||||
YaAudioProcessor::SetProcessing,
|
||||
YaAudioProcessor::Process,
|
||||
YaAudioProcessor::GetTailSamples,
|
||||
YaComponent::SetIoMode,
|
||||
YaComponent::GetBusCount,
|
||||
YaComponent::GetBusInfo,
|
||||
@@ -67,14 +75,6 @@ using ControlRequest = std::variant<YaComponent::Construct,
|
||||
YaComponent::SetActive,
|
||||
YaComponent::SetState,
|
||||
YaComponent::GetState,
|
||||
YaComponent::SetBusArrangements,
|
||||
YaComponent::GetBusArrangement,
|
||||
YaComponent::CanProcessSampleSize,
|
||||
YaComponent::GetLatencySamples,
|
||||
YaComponent::SetupProcessing,
|
||||
YaComponent::SetProcessing,
|
||||
YaComponent::Process,
|
||||
YaComponent::GetTailSamples,
|
||||
YaPluginBase::Initialize,
|
||||
YaPluginBase::Terminate,
|
||||
YaPluginFactory::Construct,
|
||||
|
||||
@@ -7,13 +7,14 @@ serialization works.
|
||||
|
||||
VST3 interfaces are implemented as follows:
|
||||
|
||||
| Yabridge class | Included in | Interfaces |
|
||||
| ------------------- | ------------- | ------------------------------------------------------ |
|
||||
| `YaComponent` | | `IComponent` |
|
||||
| `YaAudioProcessor` | `YaComponent` | `IAudioProcessor` |
|
||||
| `YaPluginBase` | `YaComponent` | `IPluginBase` |
|
||||
| `YaHostApplication` | | `iHostAPplication` |
|
||||
| `YaPluginFactory` | | `IPluginFactory`, `IPluginFactory2`, `IPluginFactory3` |
|
||||
| Yabridge class | Included in | Interfaces |
|
||||
| ------------------- | ------------------ | ------------------------------------------------------ |
|
||||
| `YaPluginMonolith` | | All of the below |
|
||||
| `YaAudioProcessor` | `YaPluginMonolith` | `IAudioProcessor` |
|
||||
| `YaComponent` | `YaPluginMonolith` | `IComponent` |
|
||||
| `YaPluginBase` | `YaPluginMonolith` | `IPluginBase` |
|
||||
| `YaHostApplication` | | `iHostAPplication` |
|
||||
| `YaPluginFactory` | | `IPluginFactory`, `IPluginFactory2`, `IPluginFactory3` |
|
||||
|
||||
The following interfaces are implemented purely fur serialization purposes:
|
||||
|
||||
|
||||
@@ -19,9 +19,9 @@
|
||||
YaAudioProcessor::ConstructArgs::ConstructArgs() {}
|
||||
|
||||
YaAudioProcessor::ConstructArgs::ConstructArgs(
|
||||
Steinberg::IPtr<Steinberg::FUnknown> component)
|
||||
Steinberg::IPtr<Steinberg::FUnknown> object)
|
||||
: supported(
|
||||
Steinberg::FUnknownPtr<Steinberg::Vst::IAudioProcessor>(component)) {}
|
||||
Steinberg::FUnknownPtr<Steinberg::Vst::IAudioProcessor>(object)) {}
|
||||
|
||||
YaAudioProcessor::YaAudioProcessor(const ConstructArgs&& args)
|
||||
: arguments(std::move(args)) {}
|
||||
|
||||
@@ -29,7 +29,7 @@
|
||||
|
||||
/**
|
||||
* Wraps around `IAudioProcessor` for serialization purposes. This is
|
||||
* instantiated as part of `YaComponent`.
|
||||
* instantiated as part of `YaPluginMonolith`.
|
||||
*/
|
||||
class YaAudioProcessor : public Steinberg::Vst::IAudioProcessor {
|
||||
public:
|
||||
@@ -40,8 +40,8 @@ class YaAudioProcessor : public Steinberg::Vst::IAudioProcessor {
|
||||
ConstructArgs();
|
||||
|
||||
/**
|
||||
* Check whether an existing implementation implements `IPluginBase` and
|
||||
* read arguments from it.
|
||||
* Check whether an existing implementation implements `IAudioProcessor`
|
||||
* and read arguments from it.
|
||||
*/
|
||||
ConstructArgs(Steinberg::IPtr<Steinberg::FUnknown> object);
|
||||
|
||||
|
||||
@@ -19,57 +19,22 @@
|
||||
YaComponent::ConstructArgs::ConstructArgs() {}
|
||||
|
||||
YaComponent::ConstructArgs::ConstructArgs(
|
||||
Steinberg::IPtr<Steinberg::Vst::IComponent> component,
|
||||
size_t instance_id)
|
||||
: instance_id(instance_id),
|
||||
audio_processor_args(component),
|
||||
plugin_base_args(component) {
|
||||
// `IComponent::getControllerClassId`
|
||||
Steinberg::TUID cid;
|
||||
if (component->getControllerClassId(cid) == Steinberg::kResultOk) {
|
||||
edit_controller_cid = std::to_array(cid);
|
||||
Steinberg::IPtr<Steinberg::FUnknown> object) {
|
||||
auto component = Steinberg::FUnknownPtr<Steinberg::Vst::IComponent>(object);
|
||||
|
||||
if (component) {
|
||||
supported = true;
|
||||
|
||||
// `IComponent::getControllerClassId`
|
||||
Steinberg::TUID cid;
|
||||
if (component->getControllerClassId(cid) == Steinberg::kResultOk) {
|
||||
edit_controller_cid = std::to_array(cid);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
YaComponent::YaComponent(const ConstructArgs&& args)
|
||||
: YaAudioProcessor(std::move(args.audio_processor_args)),
|
||||
YaPluginBase(std::move(args.plugin_base_args)),
|
||||
arguments(std::move(args)){FUNKNOWN_CTOR}
|
||||
|
||||
YaComponent::~YaComponent() {
|
||||
FUNKNOWN_DTOR
|
||||
}
|
||||
|
||||
#pragma GCC diagnostic push
|
||||
#pragma GCC diagnostic ignored "-Wdelete-non-virtual-dtor"
|
||||
IMPLEMENT_REFCOUNT(YaComponent)
|
||||
#pragma GCC diagnostic pop
|
||||
|
||||
tresult PLUGIN_API YaComponent::queryInterface(Steinberg::FIDString _iid,
|
||||
void** obj) {
|
||||
QUERY_INTERFACE(_iid, obj, Steinberg::FUnknown::iid,
|
||||
Steinberg::Vst::IComponent)
|
||||
if (YaPluginBase::supported()) {
|
||||
// We had to expand the macro here because we need to cast through
|
||||
// `YaPluginBase`, since `IpluginBase` is also a base of `IComponent`
|
||||
if (Steinberg::FUnknownPrivate ::iidEqual(
|
||||
_iid, Steinberg::IPluginBase::iid)) {
|
||||
addRef();
|
||||
*obj = static_cast<Steinberg ::IPluginBase*>(
|
||||
static_cast<YaPluginBase*>(this));
|
||||
return ::Steinberg ::kResultOk;
|
||||
}
|
||||
}
|
||||
QUERY_INTERFACE(_iid, obj, Steinberg::Vst::IComponent::iid,
|
||||
Steinberg::Vst::IComponent)
|
||||
if (YaAudioProcessor::supported()) {
|
||||
QUERY_INTERFACE(_iid, obj, Steinberg::Vst::IAudioProcessor::iid,
|
||||
Steinberg::Vst::IAudioProcessor)
|
||||
}
|
||||
|
||||
*obj = nullptr;
|
||||
return Steinberg::kNoInterface;
|
||||
}
|
||||
: arguments(std::move(args)) {}
|
||||
|
||||
tresult PLUGIN_API YaComponent::getControllerClassId(Steinberg::TUID classId) {
|
||||
if (arguments.edit_controller_cid) {
|
||||
|
||||
@@ -16,68 +16,41 @@
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <optional>
|
||||
#include <set>
|
||||
#include <variant>
|
||||
|
||||
#include <bitsery/ext/pointer.h>
|
||||
#include <bitsery/ext/std_optional.h>
|
||||
#include <bitsery/ext/std_set.h>
|
||||
#include <bitsery/ext/std_variant.h>
|
||||
#include <bitsery/traits/array.h>
|
||||
#include <pluginterfaces/vst/ivstcomponent.h>
|
||||
|
||||
#include "../../bitsery/ext/vst3.h"
|
||||
#include "../common.h"
|
||||
#include "audio-processor.h"
|
||||
#include "base.h"
|
||||
#include "host-application.h"
|
||||
#include "plugin-base.h"
|
||||
|
||||
#pragma GCC diagnostic push
|
||||
#pragma GCC diagnostic ignored "-Wnon-virtual-dtor"
|
||||
|
||||
/**
|
||||
* Wraps around `IComponent` for serialization purposes. See `README.md` for
|
||||
* more information on how this works. On the Wine plugin host side this is only
|
||||
* used for serialization, and on the plugin side have an implementation that
|
||||
* can send control messages.
|
||||
*
|
||||
* This implements all interfaces that an `IComponent` might also implement.
|
||||
*
|
||||
* We might be able to do some caching here with the buss infos, but since that
|
||||
* sounds like a huge potential source of errors we'll just do pure callbacks
|
||||
* for everything other than the edit controller's class ID.
|
||||
*
|
||||
* TODO: Rework this into `YaPluginMonolith`
|
||||
* TODO: Eventually this should (optionally) implement everything supported by
|
||||
* the SDK's `AudioEffect` component.
|
||||
* Wraps around `IComponent` for serialization purposes. This is instantiated as
|
||||
* part of `YaPluginMonolith`. Event though `IComponent` inherits from
|
||||
* `IPlguinBase`, we'll implement that separately in `YaPluginBase` because
|
||||
* `IEditController` also inherits from `IPluginBase`.
|
||||
*/
|
||||
class YaComponent : public Steinberg::Vst::IComponent,
|
||||
public YaAudioProcessor,
|
||||
public YaPluginBase {
|
||||
class YaComponent : public Steinberg::Vst::IComponent {
|
||||
public:
|
||||
/**
|
||||
* These are the arguments for creating a `YaComponentPluginImpl`.
|
||||
* These are the arguments for creating a `YaComponent`.
|
||||
*/
|
||||
struct ConstructArgs {
|
||||
ConstructArgs();
|
||||
|
||||
/**
|
||||
* Read arguments from an existing implementation. 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 `IComponent` and
|
||||
* read arguments from it.
|
||||
*/
|
||||
ConstructArgs(Steinberg::IPtr<Steinberg::Vst::IComponent> component,
|
||||
size_t instance_id);
|
||||
ConstructArgs(Steinberg::IPtr<Steinberg::FUnknown> object);
|
||||
|
||||
/**
|
||||
* The unique identifier for this specific instance.
|
||||
* Whether the object supported this interface.
|
||||
*/
|
||||
native_size_t instance_id;
|
||||
|
||||
YaAudioProcessor::ConstructArgs audio_processor_args;
|
||||
YaPluginBase::ConstructArgs plugin_base_args;
|
||||
bool supported;
|
||||
|
||||
/**
|
||||
* The class ID of this component's corresponding editor controller. You
|
||||
@@ -87,59 +60,19 @@ class YaComponent : public Steinberg::Vst::IComponent,
|
||||
|
||||
template <typename S>
|
||||
void serialize(S& s) {
|
||||
s.value8b(instance_id);
|
||||
s.object(audio_processor_args);
|
||||
s.object(plugin_base_args);
|
||||
s.value1b(supported);
|
||||
s.ext(edit_controller_cid, bitsery::ext::StdOptional{},
|
||||
[](S& s, auto& cid) { s.container1b(cid); });
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Message to request the Wine plugin host to instantiate a new IComponent
|
||||
* to pass through a call to `IComponent::createInstance(cid,
|
||||
* IComponent::iid, ...)`.
|
||||
*/
|
||||
struct Construct {
|
||||
using Response = std::variant<ConstructArgs, UniversalTResult>;
|
||||
|
||||
ArrayUID cid;
|
||||
|
||||
template <typename S>
|
||||
void serialize(S& s) {
|
||||
s.container1b(cid);
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Instantiate this instance with arguments read from another interface
|
||||
* implementation.
|
||||
*/
|
||||
YaComponent(const ConstructArgs&& args);
|
||||
|
||||
/**
|
||||
* Message to request the Wine plugin host to destroy the IComponent
|
||||
* instance with the given instance ID. Sent from the destructor of
|
||||
* `YaComponentPluginImpl`.
|
||||
*/
|
||||
struct Destruct {
|
||||
using Response = Ack;
|
||||
|
||||
native_size_t instance_id;
|
||||
|
||||
template <typename S>
|
||||
void serialize(S& s) {
|
||||
s.value8b(instance_id);
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* @remark The plugin side implementation should send a control message to
|
||||
* clean up the instance on the Wine side in its destructor.
|
||||
*/
|
||||
virtual ~YaComponent() = 0;
|
||||
|
||||
DECLARE_FUNKNOWN_METHODS
|
||||
inline bool supported() { return arguments.supported; }
|
||||
|
||||
tresult PLUGIN_API getControllerClassId(Steinberg::TUID classId) override;
|
||||
|
||||
@@ -381,10 +314,3 @@ class YaComponent : public Steinberg::Vst::IComponent,
|
||||
};
|
||||
|
||||
#pragma GCC diagnostic pop
|
||||
|
||||
template <typename S>
|
||||
void serialize(
|
||||
S& s,
|
||||
std::variant<YaComponent::ConstructArgs, UniversalTResult>& result) {
|
||||
s.ext(result, bitsery::ext::StdVariant{});
|
||||
}
|
||||
|
||||
@@ -34,6 +34,9 @@
|
||||
* application context passed during `IPluginBase::intialize()` as well as for
|
||||
* `IPluginFactory3::setHostContext()`. This interface is thus implemented on
|
||||
* both the native plugin side as well as the Wine plugin host side.
|
||||
*
|
||||
* TODO: When implementing more host interfaces, also rework this into a
|
||||
* monolith class like with the plugin.
|
||||
*/
|
||||
class YaHostApplication : public Steinberg::Vst::IHostApplication {
|
||||
public:
|
||||
|
||||
@@ -19,8 +19,8 @@
|
||||
YaPluginBase::ConstructArgs::ConstructArgs() {}
|
||||
|
||||
YaPluginBase::ConstructArgs::ConstructArgs(
|
||||
Steinberg::IPtr<Steinberg::FUnknown> component)
|
||||
: supported(Steinberg::FUnknownPtr<Steinberg::IPluginBase>(component)) {}
|
||||
Steinberg::IPtr<Steinberg::FUnknown> object)
|
||||
: supported(Steinberg::FUnknownPtr<Steinberg::IPluginBase>(object)) {}
|
||||
|
||||
YaPluginBase::YaPluginBase(const ConstructArgs&& args)
|
||||
: arguments(std::move(args)) {}
|
||||
|
||||
@@ -29,7 +29,7 @@
|
||||
/**
|
||||
* Wraps around `IPluginBase` for serialization purposes. Both components and
|
||||
* edit controllers inherit from this. This is instantiated as part of
|
||||
* `YaComponent` or `YaEditController`.
|
||||
* `YaPluginMonolith`.
|
||||
*/
|
||||
class YaPluginBase : public Steinberg::IPluginBase {
|
||||
public:
|
||||
|
||||
@@ -0,0 +1,75 @@
|
||||
// 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-monolith.h"
|
||||
|
||||
YaPluginMonolith::ConstructArgs::ConstructArgs() {}
|
||||
|
||||
YaPluginMonolith::ConstructArgs::ConstructArgs(
|
||||
Steinberg::IPtr<Steinberg::FUnknown> object,
|
||||
size_t instance_id)
|
||||
: instance_id(instance_id),
|
||||
audio_processor_args(object),
|
||||
component_args(object),
|
||||
plugin_base_args(object) {}
|
||||
|
||||
YaPluginMonolith::YaPluginMonolith(const ConstructArgs&& args)
|
||||
: YaAudioProcessor(std::move(args.audio_processor_args)),
|
||||
YaComponent(std::move(args.component_args)),
|
||||
YaPluginBase(std::move(args.plugin_base_args)),
|
||||
arguments(std::move(args)){FUNKNOWN_CTOR}
|
||||
|
||||
YaPluginMonolith::~YaPluginMonolith() {
|
||||
FUNKNOWN_DTOR
|
||||
}
|
||||
|
||||
#pragma GCC diagnostic push
|
||||
#pragma GCC diagnostic ignored "-Wdelete-non-virtual-dtor"
|
||||
IMPLEMENT_REFCOUNT(YaPluginMonolith)
|
||||
#pragma GCC diagnostic pop
|
||||
|
||||
tresult PLUGIN_API YaPluginMonolith::queryInterface(Steinberg::FIDString _iid,
|
||||
void** obj) {
|
||||
if (YaPluginBase::supported()) {
|
||||
// We had to expand the macro here because we need to cast through
|
||||
// `YaPluginBase`, since `IpluginBase` is also a base of `IComponent`
|
||||
if (Steinberg::FUnknownPrivate ::iidEqual(_iid,
|
||||
Steinberg::FUnknown::iid)) {
|
||||
addRef();
|
||||
*obj = static_cast<Steinberg ::IPluginBase*>(
|
||||
static_cast<YaPluginBase*>(this));
|
||||
return ::Steinberg ::kResultOk;
|
||||
}
|
||||
if (Steinberg::FUnknownPrivate ::iidEqual(
|
||||
_iid, Steinberg::IPluginBase::iid)) {
|
||||
addRef();
|
||||
*obj = static_cast<Steinberg ::IPluginBase*>(
|
||||
static_cast<YaPluginBase*>(this));
|
||||
return ::Steinberg ::kResultOk;
|
||||
}
|
||||
}
|
||||
if (YaComponent::supported()) {
|
||||
QUERY_INTERFACE(_iid, obj, Steinberg::Vst::IComponent::iid,
|
||||
Steinberg::Vst::IComponent)
|
||||
}
|
||||
if (YaAudioProcessor::supported()) {
|
||||
QUERY_INTERFACE(_iid, obj, Steinberg::Vst::IAudioProcessor::iid,
|
||||
Steinberg::Vst::IAudioProcessor)
|
||||
}
|
||||
|
||||
*obj = nullptr;
|
||||
return Steinberg::kNoInterface;
|
||||
}
|
||||
@@ -0,0 +1,151 @@
|
||||
// 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/>.
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <bitsery/ext/std_variant.h>
|
||||
#include <pluginterfaces/vst/ivstcomponent.h>
|
||||
|
||||
#include "../common.h"
|
||||
#include "audio-processor.h"
|
||||
#include "base.h"
|
||||
#include "component.h"
|
||||
#include "host-application.h"
|
||||
#include "plugin-base.h"
|
||||
|
||||
#pragma GCC diagnostic push
|
||||
#pragma GCC diagnostic ignored "-Wnon-virtual-dtor"
|
||||
|
||||
/**
|
||||
* An abstract class that optionally implements all VST3 interfaces a plugin
|
||||
* object could implement. A more in depth explanation can be found in
|
||||
* `docs/vst3.md`, but the way this works is that we begin with an `FUnknown`
|
||||
* pointer from the Windows VST3 plugin obtained by a call to
|
||||
* `IPluginFactory::createInstance()` (with an interface decided by the host).
|
||||
* We then go through all the plugin interfaces and check whether that object
|
||||
* supports them one by one. For each supported interface we remember that the
|
||||
* plugin supports it, and we'll optionally write down some static data (such as
|
||||
* the edit controller cid) that can't change over the lifetime of the
|
||||
* application. On the plugin side we then return a `YaPluginMonolith`
|
||||
* implementation that contains all of this information about interfaces the
|
||||
* object we're proxying might support. This way we can allow casts to all of
|
||||
* those object types in `queryInterface()`, essentially perfectly mimicing the
|
||||
* original object.
|
||||
*
|
||||
* This monolith approach is also important when it comes to `IConnectionPoint`.
|
||||
* The host should be able to connect arbitrary objects together, and the plugin
|
||||
* can then use the query interface smart pointer casting system to cast those
|
||||
* objects to the types they want. By having a huge monolithic class that
|
||||
* implements any interface such an object might also implement, we can allow
|
||||
* perfect proxying behaviour for connecting components.
|
||||
*/
|
||||
class YaPluginMonolith : public YaAudioProcessor,
|
||||
public YaComponent,
|
||||
public YaPluginBase {
|
||||
public:
|
||||
/**
|
||||
* These are the arguments for creating a `YaPluginMonolithImpl`.
|
||||
*/
|
||||
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<FUnknown> object, size_t instance_id);
|
||||
|
||||
/**
|
||||
* The unique identifier for this specific object instance.
|
||||
*/
|
||||
native_size_t instance_id;
|
||||
|
||||
YaAudioProcessor::ConstructArgs audio_processor_args;
|
||||
YaComponent::ConstructArgs component_args;
|
||||
YaPluginBase::ConstructArgs plugin_base_args;
|
||||
|
||||
template <typename S>
|
||||
void serialize(S& s) {
|
||||
s.value8b(instance_id);
|
||||
s.object(audio_processor_args);
|
||||
s.object(component_args);
|
||||
s.object(plugin_base_args);
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Message to request the Wine plugin host to instantiate a new IComponent
|
||||
* to pass through a call to `IComponent::createInstance(cid,
|
||||
* IComponent::iid, ...)`.
|
||||
*/
|
||||
struct Construct {
|
||||
using Response = std::variant<ConstructArgs, UniversalTResult>;
|
||||
|
||||
ArrayUID cid;
|
||||
|
||||
// TODO: Add an enum class to reify the type of object we want to
|
||||
// instantiate so we can initialize things other than
|
||||
// `IComponent`, like `IEditController.`
|
||||
|
||||
template <typename S>
|
||||
void serialize(S& s) {
|
||||
s.container1b(cid);
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Instantiate this object instance with arguments read from another
|
||||
* interface implementation.
|
||||
*/
|
||||
YaPluginMonolith(const ConstructArgs&& args);
|
||||
|
||||
/**
|
||||
* Message to request the Wine plugin host to destroy this object instance
|
||||
* with the given instance ID. Sent from the destructor of
|
||||
* `YaPluginMonolithImpl`. This will cause all smart pointers to the actual
|
||||
* object in the Wine plugin host to be dropped.
|
||||
*/
|
||||
struct Destruct {
|
||||
using Response = Ack;
|
||||
|
||||
native_size_t instance_id;
|
||||
|
||||
template <typename S>
|
||||
void serialize(S& s) {
|
||||
s.value8b(instance_id);
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* @remark The plugin side implementation should send a control message to
|
||||
* clean up the instance on the Wine side in its destructor.
|
||||
*/
|
||||
virtual ~YaPluginMonolith() = 0;
|
||||
|
||||
DECLARE_FUNKNOWN_METHODS
|
||||
|
||||
protected:
|
||||
ConstructArgs arguments;
|
||||
};
|
||||
|
||||
#pragma GCC diagnostic pop
|
||||
|
||||
template <typename S>
|
||||
void serialize(
|
||||
S& s,
|
||||
std::variant<YaPluginMonolith::ConstructArgs, UniversalTResult>& result) {
|
||||
s.ext(result, bitsery::ext::StdVariant{});
|
||||
}
|
||||
Reference in New Issue
Block a user