Add an IConnectionPoint proxy implementation

We still have to pass this proxy to the plugin. That's next.
This commit is contained in:
Robbert van der Helm
2020-12-25 13:46:03 +01:00
parent 0fce9c9eed
commit fbad4a65ab
6 changed files with 139 additions and 8 deletions
+1
View File
@@ -158,6 +158,7 @@ if with_vst3
'src/common/serialization/vst3/plugin-factory.cpp', 'src/common/serialization/vst3/plugin-factory.cpp',
'src/common/serialization/vst3/process-data.cpp', 'src/common/serialization/vst3/process-data.cpp',
'src/wine-host/bridges/vst3-impls/component-handler-proxy.cpp', 'src/wine-host/bridges/vst3-impls/component-handler-proxy.cpp',
'src/wine-host/bridges/vst3-impls/connection-point-proxy.cpp',
'src/wine-host/bridges/vst3-impls/host-context-proxy.cpp', 'src/wine-host/bridges/vst3-impls/host-context-proxy.cpp',
'src/wine-host/bridges/vst3-impls/plug-frame-proxy.cpp', 'src/wine-host/bridges/vst3-impls/plug-frame-proxy.cpp',
'src/wine-host/bridges/vst3.cpp', 'src/wine-host/bridges/vst3.cpp',
+6
View File
@@ -24,6 +24,7 @@
#include "../utils.h" #include "../utils.h"
#include "common.h" #include "common.h"
#include "vst3/component-handler-proxy.h" #include "vst3/component-handler-proxy.h"
#include "vst3/connection-point-proxy.h"
#include "vst3/host-context-proxy.h" #include "vst3/host-context-proxy.h"
#include "vst3/plug-frame-proxy.h" #include "vst3/plug-frame-proxy.h"
#include "vst3/plug-view-proxy.h" #include "vst3/plug-view-proxy.h"
@@ -143,6 +144,11 @@ using CallbackRequest = std::variant<WantsConfiguration,
YaComponentHandler::PerformEdit, YaComponentHandler::PerformEdit,
YaComponentHandler::EndEdit, YaComponentHandler::EndEdit,
YaComponentHandler::RestartComponent, YaComponentHandler::RestartComponent,
// Used when the host uses proxy objects,
// and we have to route
// `IConnectionPoint::notify` calls through
// there
YaConnectionPoint::Notify,
YaHostApplication::GetName, YaHostApplication::GetName,
YaPlugFrame::ResizeView>; YaPlugFrame::ResizeView>;
+16 -8
View File
@@ -124,6 +124,22 @@ class Vst3PluginProxyImpl : public Vst3PluginProxy {
tresult PLUGIN_API initialize(FUnknown* context) override; tresult PLUGIN_API initialize(FUnknown* context) override;
tresult PLUGIN_API terminate() override; tresult PLUGIN_API terminate() override;
/**
* The component handler the host passed to us during
* `IEditController::setComponentHandler()`. When the plugin makes a
* callback on a component handler proxy object, we'll pass the call through
* to this object.
*/
Steinberg::IPtr<Steinberg::Vst::IComponentHandler> component_handler;
/**
* If the host doesn't connect two objects directly in
* `IConnectionPoint::connect` but instead connects them through a proxy,
* we'll store that proxy here. This way we can then route messages sent by
* the plugin through this proxy. So far this is only needed for Ardour.
*/
Steinberg::IPtr<Steinberg::Vst::IConnectionPoint> connection_point_proxy;
/** /**
* An unmanaged, raw pointer to the `IPlugView` instance returned in our * An unmanaged, raw pointer to the `IPlugView` instance returned in our
* implementation of `IEditController::createView()`. We need this to handle * implementation of `IEditController::createView()`. We need this to handle
@@ -136,14 +152,6 @@ class Vst3PluginProxyImpl : public Vst3PluginProxy {
*/ */
Vst3PlugViewProxyImpl* last_created_plug_view = nullptr; Vst3PlugViewProxyImpl* last_created_plug_view = nullptr;
/**
* The component handler the host passed to us during
* `IEditController::setComponentHandler()`. When the plugin makes a
* callback on a component handler proxy object, we'll pass the call through
* to this object.
*/
Steinberg::IPtr<Steinberg::Vst::IComponentHandler> component_handler;
// The following pointers are cast from `host_context` if `setHostContext()` // The following pointers are cast from `host_context` if `setHostContext()`
// has been called // has been called
+6
View File
@@ -106,6 +106,12 @@ Vst3PluginBridge::Vst3PluginBridge()
.get() .get()
.component_handler->restartComponent(request.flags); .component_handler->restartComponent(request.flags);
}, },
[&](YaConnectionPoint::Notify& request)
-> YaConnectionPoint::Notify::Response {
return plugin_proxies.at(request.instance_id)
.get()
.connection_point_proxy->notify(&request.message);
},
[&](const YaHostApplication::GetName& request) [&](const YaHostApplication::GetName& request)
-> YaHostApplication::GetName::Response { -> YaHostApplication::GetName::Response {
tresult result; tresult result;
@@ -0,0 +1,69 @@
// 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 "connection-point-proxy.h"
#include <iostream>
Vst3ConnectionPointProxyImpl::Vst3ConnectionPointProxyImpl(
Vst3Bridge& bridge,
Vst3ConnectionPointProxy::ConstructArgs&& args)
: Vst3ConnectionPointProxy(std::move(args)), bridge(bridge) {}
tresult PLUGIN_API
Vst3ConnectionPointProxyImpl::queryInterface(const Steinberg::TUID _iid,
void** obj) {
// TODO: Successful queries should also be logged
const tresult result = Vst3ConnectionPointProxy::queryInterface(_iid, obj);
if (result != Steinberg::kResultOk) {
std::cerr << "TODO: Implement unknown interface logging on Wine side "
"for Vst3ConnectionPointProxyImpl::queryInterface"
<< std::endl;
}
return result;
}
tresult PLUGIN_API
Vst3ConnectionPointProxyImpl::connect(IConnectionPoint* /*other*/) {
std::cerr << "WARNING: The plugin called IConnectionPoint::connect(), this "
"should not happen"
<< std::endl;
return Steinberg::kNotImplemented;
}
tresult PLUGIN_API
Vst3ConnectionPointProxyImpl::disconnect(IConnectionPoint* /*other*/) {
std::cerr << "WARNING: The plugin called IConnectionPoint::disconnect(), "
"this should not happen"
<< std::endl;
return Steinberg::kNotImplemented;
}
tresult PLUGIN_API
Vst3ConnectionPointProxyImpl::notify(Steinberg::Vst::IMessage* message) {
// As explained in `YaMessage` and `Vst3PluginProxyImpl::notify`, we can
// only support our own `IMessage implementation here`
if (auto message_impl = dynamic_cast<YaMessage*>(message)) {
return bridge.send_message(YaConnectionPoint::Notify{
.instance_id = owner_instance_id(), .message = *message_impl});
} else {
std::cerr << "WARNING: Unknown message type passed to "
"'IConnectionPoint::notify()', ignoring"
<< std::endl;
return Steinberg::kNotImplemented;
}
}
@@ -0,0 +1,41 @@
// 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 "../vst3.h"
class Vst3ConnectionPointProxyImpl : public Vst3ConnectionPointProxy {
public:
Vst3ConnectionPointProxyImpl(
Vst3Bridge& bridge,
Vst3ConnectionPointProxy::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;
// From `IConnectionPoint`
tresult PLUGIN_API connect(IConnectionPoint* other) override;
tresult PLUGIN_API disconnect(IConnectionPoint* other) override;
tresult PLUGIN_API notify(Steinberg::Vst::IMessage* message) override;
private:
Vst3Bridge& bridge;
};