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:
Robbert van der Helm
2020-12-17 12:48:10 +01:00
parent d6c28f48d9
commit d8b2646563
22 changed files with 422 additions and 285 deletions
+33 -32
View File
@@ -16,22 +16,23 @@
#include "component.h"
YaComponentPluginImpl::YaComponentPluginImpl(Vst3PluginBridge& bridge,
YaComponent::ConstructArgs&& args)
: YaComponent(std::move(args)), bridge(bridge) {
YaPluginMonolithImpl::YaPluginMonolithImpl(
Vst3PluginBridge& bridge,
YaPluginMonolith::ConstructArgs&& args)
: YaPluginMonolith(std::move(args)), bridge(bridge) {
bridge.register_component(arguments.instance_id, *this);
}
YaComponentPluginImpl::~YaComponentPluginImpl() {
YaPluginMonolithImpl::~YaPluginMonolithImpl() {
bridge.send_message(
YaComponent::Destruct{.instance_id = arguments.instance_id});
YaPluginMonolith::Destruct{.instance_id = arguments.instance_id});
bridge.unregister_component(arguments.instance_id);
}
tresult PLUGIN_API
YaComponentPluginImpl::queryInterface(const Steinberg::TUID _iid, void** obj) {
YaPluginMonolithImpl::queryInterface(const Steinberg::TUID _iid, void** obj) {
// TODO: Successful queries should also be logged
const tresult result = YaComponent::queryInterface(_iid, obj);
const tresult result = YaPluginMonolith::queryInterface(_iid, obj);
if (result != Steinberg::kResultOk) {
bridge.logger.log_unknown_interface("In IComponent::queryInterface()",
Steinberg::FUID::fromTUID(_iid));
@@ -40,7 +41,7 @@ YaComponentPluginImpl::queryInterface(const Steinberg::TUID _iid, void** obj) {
return result;
}
tresult PLUGIN_API YaComponentPluginImpl::setBusArrangements(
tresult PLUGIN_API YaPluginMonolithImpl::setBusArrangements(
Steinberg::Vst::SpeakerArrangement* inputs,
int32 numIns,
Steinberg::Vst::SpeakerArrangement* outputs,
@@ -57,7 +58,7 @@ tresult PLUGIN_API YaComponentPluginImpl::setBusArrangements(
});
}
tresult PLUGIN_API YaComponentPluginImpl::getBusArrangement(
tresult PLUGIN_API YaPluginMonolithImpl::getBusArrangement(
Steinberg::Vst::BusDirection dir,
int32 index,
Steinberg::Vst::SpeakerArrangement& arr) {
@@ -74,30 +75,30 @@ tresult PLUGIN_API YaComponentPluginImpl::getBusArrangement(
}
tresult PLUGIN_API
YaComponentPluginImpl::canProcessSampleSize(int32 symbolicSampleSize) {
YaPluginMonolithImpl::canProcessSampleSize(int32 symbolicSampleSize) {
return bridge.send_message(YaAudioProcessor::CanProcessSampleSize{
.instance_id = arguments.instance_id,
.symbolic_sample_size = symbolicSampleSize});
}
uint32 PLUGIN_API YaComponentPluginImpl::getLatencySamples() {
uint32 PLUGIN_API YaPluginMonolithImpl::getLatencySamples() {
return bridge.send_message(YaAudioProcessor::GetLatencySamples{
.instance_id = arguments.instance_id});
}
tresult PLUGIN_API
YaComponentPluginImpl::setupProcessing(Steinberg::Vst::ProcessSetup& setup) {
YaPluginMonolithImpl::setupProcessing(Steinberg::Vst::ProcessSetup& setup) {
return bridge.send_message(YaAudioProcessor::SetupProcessing{
.instance_id = arguments.instance_id, .setup = setup});
}
tresult PLUGIN_API YaComponentPluginImpl::setProcessing(TBool state) {
tresult PLUGIN_API YaPluginMonolithImpl::setProcessing(TBool state) {
return bridge.send_message(YaAudioProcessor::SetProcessing{
.instance_id = arguments.instance_id, .state = state});
}
tresult PLUGIN_API
YaComponentPluginImpl::process(Steinberg::Vst::ProcessData& data) {
YaPluginMonolithImpl::process(Steinberg::Vst::ProcessData& data) {
ProcessResponse response = bridge.send_message(YaAudioProcessor::Process{
.instance_id = arguments.instance_id, .data = data});
@@ -106,29 +107,29 @@ YaComponentPluginImpl::process(Steinberg::Vst::ProcessData& data) {
return response.result;
}
uint32 PLUGIN_API YaComponentPluginImpl::getTailSamples() {
uint32 PLUGIN_API YaPluginMonolithImpl::getTailSamples() {
return bridge.send_message(
YaAudioProcessor::GetTailSamples{.instance_id = arguments.instance_id});
}
tresult PLUGIN_API
YaComponentPluginImpl::setIoMode(Steinberg::Vst::IoMode mode) {
YaPluginMonolithImpl::setIoMode(Steinberg::Vst::IoMode mode) {
return bridge.send_message(YaComponent::SetIoMode{
.instance_id = arguments.instance_id, .mode = mode});
}
int32 PLUGIN_API
YaComponentPluginImpl::getBusCount(Steinberg::Vst::MediaType type,
Steinberg::Vst::BusDirection dir) {
YaPluginMonolithImpl::getBusCount(Steinberg::Vst::MediaType type,
Steinberg::Vst::BusDirection dir) {
return bridge.send_message(YaComponent::GetBusCount{
.instance_id = arguments.instance_id, .type = type, .dir = dir});
}
tresult PLUGIN_API
YaComponentPluginImpl::getBusInfo(Steinberg::Vst::MediaType type,
Steinberg::Vst::BusDirection dir,
int32 index,
Steinberg::Vst::BusInfo& bus /*out*/) {
YaPluginMonolithImpl::getBusInfo(Steinberg::Vst::MediaType type,
Steinberg::Vst::BusDirection dir,
int32 index,
Steinberg::Vst::BusInfo& bus /*out*/) {
const GetBusInfoResponse response = bridge.send_message(
YaComponent::GetBusInfo{.instance_id = arguments.instance_id,
.type = type,
@@ -140,7 +141,7 @@ YaComponentPluginImpl::getBusInfo(Steinberg::Vst::MediaType type,
return response.result;
}
tresult PLUGIN_API YaComponentPluginImpl::getRoutingInfo(
tresult PLUGIN_API YaPluginMonolithImpl::getRoutingInfo(
Steinberg::Vst::RoutingInfo& inInfo,
Steinberg::Vst::RoutingInfo& outInfo /*out*/) {
const GetRoutingInfoResponse response = bridge.send_message(
@@ -154,10 +155,10 @@ tresult PLUGIN_API YaComponentPluginImpl::getRoutingInfo(
}
tresult PLUGIN_API
YaComponentPluginImpl::activateBus(Steinberg::Vst::MediaType type,
Steinberg::Vst::BusDirection dir,
int32 index,
TBool state) {
YaPluginMonolithImpl::activateBus(Steinberg::Vst::MediaType type,
Steinberg::Vst::BusDirection dir,
int32 index,
TBool state) {
return bridge.send_message(
YaComponent::ActivateBus{.instance_id = arguments.instance_id,
.type = type,
@@ -166,17 +167,17 @@ YaComponentPluginImpl::activateBus(Steinberg::Vst::MediaType type,
.state = state});
}
tresult PLUGIN_API YaComponentPluginImpl::setActive(TBool state) {
tresult PLUGIN_API YaPluginMonolithImpl::setActive(TBool state) {
return bridge.send_message(YaComponent::SetActive{
.instance_id = arguments.instance_id, .state = state});
}
tresult PLUGIN_API YaComponentPluginImpl::setState(Steinberg::IBStream* state) {
tresult PLUGIN_API YaPluginMonolithImpl::setState(Steinberg::IBStream* state) {
return bridge.send_message(YaComponent::SetState{
.instance_id = arguments.instance_id, .state = state});
}
tresult PLUGIN_API YaComponentPluginImpl::getState(Steinberg::IBStream* state) {
tresult PLUGIN_API YaPluginMonolithImpl::getState(Steinberg::IBStream* state) {
const GetStateResponse response = bridge.send_message(
YaComponent::GetState{.instance_id = arguments.instance_id});
@@ -185,7 +186,7 @@ tresult PLUGIN_API YaComponentPluginImpl::getState(Steinberg::IBStream* state) {
return response.result;
}
tresult PLUGIN_API YaComponentPluginImpl::initialize(FUnknown* context) {
tresult PLUGIN_API YaPluginMonolithImpl::initialize(FUnknown* context) {
// This `context` will likely be an `IHostApplication`. If it is, we will
// store it here, and we'll proxy through all calls to it made from the Wine
// side. Otherwise we'll still call `IPluginBase::initialize()` but with a
@@ -209,7 +210,7 @@ tresult PLUGIN_API YaComponentPluginImpl::initialize(FUnknown* context) {
std::move(host_application_context_args)});
}
tresult PLUGIN_API YaComponentPluginImpl::terminate() {
tresult PLUGIN_API YaPluginMonolithImpl::terminate() {
return bridge.send_message(
YaPluginBase::Terminate{.instance_id = arguments.instance_id});
}
+4 -4
View File
@@ -20,17 +20,17 @@
#include "../vst3.h"
class YaComponentPluginImpl : public YaComponent {
class YaPluginMonolithImpl : public YaPluginMonolith {
public:
YaComponentPluginImpl(Vst3PluginBridge& bridge,
YaComponent::ConstructArgs&& args);
YaPluginMonolithImpl(Vst3PluginBridge& bridge,
YaPluginMonolith::ConstructArgs&& args);
/**
* When the reference count reaches zero and this destructor is called,
* we'll send a request to the Wine plugin host to destroy the corresponding
* object.
*/
~YaComponentPluginImpl();
~YaPluginMonolithImpl();
/**
* We'll override the query interface to log queries for interfaces we do
@@ -38,13 +38,13 @@ YaPluginFactoryPluginImpl::createInstance(Steinberg::FIDString cid,
ArrayUID cid_array;
std::copy(cid, cid + sizeof(Steinberg::TUID), cid_array.begin());
if (Steinberg::FIDStringsEqual(_iid, Steinberg::Vst::IComponent::iid)) {
std::variant<YaComponent::ConstructArgs, UniversalTResult> result =
bridge.send_message(YaComponent::Construct{.cid = cid_array});
std::variant<YaPluginMonolith::ConstructArgs, UniversalTResult> result =
bridge.send_message(YaPluginMonolith::Construct{.cid = cid_array});
return std::visit(
overload{
[&](YaComponent::ConstructArgs&& args) -> tresult {
[&](YaPluginMonolith::ConstructArgs&& args) -> tresult {
*obj = static_cast<Steinberg::Vst::IComponent*>(
new YaComponentPluginImpl(bridge, std::move(args)));
new YaPluginMonolithImpl(bridge, std::move(args)));
return Steinberg::kResultOk;
},
[&](const UniversalTResult& code) -> tresult { return code; }},
@@ -18,6 +18,7 @@
#include "../vst3.h"
// TODO Rename to YaPluginFactoryImpl
class YaPluginFactoryPluginImpl : public YaPluginFactory {
public:
YaPluginFactoryPluginImpl(Vst3PluginBridge& bridge,
+2 -2
View File
@@ -115,10 +115,10 @@ Steinberg::IPluginFactory* Vst3PluginBridge::get_plugin_factory() {
}
void Vst3PluginBridge::register_component(size_t instance_id,
YaComponentPluginImpl& component) {
YaPluginMonolithImpl& component) {
std::lock_guard lock(component_instances_mutex);
component_instances.emplace(instance_id,
std::ref<YaComponentPluginImpl>(component));
std::ref<YaPluginMonolithImpl>(component));
}
void Vst3PluginBridge::unregister_component(size_t instance_id) {
+5 -3
View File
@@ -24,7 +24,7 @@
#include "common.h"
// Forward declaration
class YaComponentPluginImpl;
class YaPluginMonolithImpl;
/**
* This handles the communication between the native host and a VST3 plugin
@@ -83,9 +83,11 @@ class Vst3PluginBridge : PluginBridge<Vst3Sockets<std::jthread>> {
* context.
*
* @see component_instances
*
* TODO: REname to `register_instance` or `register_object`
*/
void register_component(size_t instance_id,
YaComponentPluginImpl& component);
YaPluginMonolithImpl& component);
/**
* Remove a previously registered `YaComponentPluginImpl` from the list of
@@ -149,7 +151,7 @@ class Vst3PluginBridge : PluginBridge<Vst3Sockets<std::jthread>> {
* `register_component()` in the constractor, and an instance is then
* removed through a call to `unregister_component()` in the destructor.
*/
std::map<size_t, std::reference_wrapper<YaComponentPluginImpl>>
std::map<size_t, std::reference_wrapper<YaPluginMonolithImpl>>
component_instances;
std::mutex component_instances_mutex;
};