mirror of
https://github.com/robbert-vdh/yabridge.git
synced 2026-05-10 04:30:12 +02:00
Allow indirect IConnectionPoint connections
This is needed to support Ardour. These extra hops and serialization steps will probably hurt performance, but outside of some huge hacks (to connect the components directly anyways) there's not much else we can do.
This commit is contained in:
@@ -21,6 +21,7 @@
|
||||
#include <public.sdk/source/vst/hosting/module_win32.cpp>
|
||||
|
||||
#include "vst3-impls/component-handler-proxy.h"
|
||||
#include "vst3-impls/connection-point-proxy.h"
|
||||
#include "vst3-impls/host-context-proxy.h"
|
||||
#include "vst3-impls/plug-frame-proxy.h"
|
||||
|
||||
@@ -168,24 +169,55 @@ void Vst3Bridge::run() {
|
||||
return Vst3PluginProxy::GetStateResponse{
|
||||
.result = result, .updated_state = std::move(stream)};
|
||||
},
|
||||
[&](const YaConnectionPoint::Connect& request)
|
||||
[&](YaConnectionPoint::Connect& request)
|
||||
-> YaConnectionPoint::Connect::Response {
|
||||
// We can directly connect the underlying objects
|
||||
// TODO: Add support for connecting objects through a proxy
|
||||
// object provided by the host
|
||||
return object_instances[request.instance_id]
|
||||
.connection_point->connect(
|
||||
object_instances[request.other_instance_id]
|
||||
.connection_point);
|
||||
// If the host directly connected the underlying objects then we
|
||||
// can directly connect them as well. Otherwise we'll have to go
|
||||
// through a connection proxy (to proxy the host's connection
|
||||
// proxy).
|
||||
return std::visit(
|
||||
overload{
|
||||
[&](const native_size_t& other_instance_id) -> tresult {
|
||||
return object_instances[request.instance_id]
|
||||
.connection_point->connect(
|
||||
object_instances[other_instance_id]
|
||||
.connection_point);
|
||||
},
|
||||
[&](Vst3ConnectionPointProxy::ConstructArgs& args)
|
||||
-> tresult {
|
||||
object_instances[request.instance_id]
|
||||
.connection_point_proxy = Steinberg::owned(
|
||||
new Vst3ConnectionPointProxyImpl(
|
||||
*this, std::move(args)));
|
||||
|
||||
return object_instances[request.instance_id]
|
||||
.connection_point->connect(
|
||||
object_instances[request.instance_id]
|
||||
.connection_point_proxy);
|
||||
}},
|
||||
request.other);
|
||||
},
|
||||
[&](const YaConnectionPoint::Disconnect& request)
|
||||
-> YaConnectionPoint::Disconnect::Response {
|
||||
// TODO: Add support for connecting objects through a proxy
|
||||
// object provided by the host
|
||||
return object_instances[request.instance_id]
|
||||
.connection_point->disconnect(
|
||||
object_instances[request.other_instance_id]
|
||||
.connection_point);
|
||||
// If the objects were connected directly we can also disconnect
|
||||
// them directly. Otherwise we'll disconnect them from our proxy
|
||||
// object and then destroy that proxy object.
|
||||
if (request.other_instance_id) {
|
||||
return object_instances[request.instance_id]
|
||||
.connection_point->disconnect(
|
||||
object_instances[*request.other_instance_id]
|
||||
.connection_point);
|
||||
} else {
|
||||
const tresult result =
|
||||
object_instances[request.instance_id]
|
||||
.connection_point->disconnect(
|
||||
object_instances[*request.other_instance_id]
|
||||
.connection_point_proxy);
|
||||
object_instances[*request.other_instance_id]
|
||||
.connection_point_proxy.reset();
|
||||
|
||||
return result;
|
||||
}
|
||||
},
|
||||
[&](YaConnectionPoint::Notify& request)
|
||||
-> YaConnectionPoint::Notify::Response {
|
||||
|
||||
@@ -26,9 +26,6 @@
|
||||
#include "../editor.h"
|
||||
#include "common.h"
|
||||
|
||||
// Forward declarations
|
||||
class Vst3PlugFrameProxyImpl;
|
||||
|
||||
/**
|
||||
* A holder for plugin object instance created from the factory. This stores all
|
||||
* relevant interface smart pointers to that object so we can handle control
|
||||
@@ -57,6 +54,18 @@ struct InstanceInterfaces {
|
||||
*/
|
||||
Steinberg::IPtr<Vst3HostContextProxy> host_context_proxy;
|
||||
|
||||
/**
|
||||
* If the host connects two objects indirectly using a connection proxy (as
|
||||
* allowed by the VST3 specification), then we also can't connect the
|
||||
* objects directly on the Wine side. In that case we'll have to create this
|
||||
* proxy object, pass it to the plugin, and if the plugin then calls
|
||||
* `IConnectionPoint::notify()` on it we'll pass that call through to the
|
||||
* `IConnectionPoint` instance passed to us by the host (which will then in
|
||||
* turn call `IConnectionPoint::notify()` on our plugin proxy object).
|
||||
* Proxies for days.
|
||||
*/
|
||||
Steinberg::IPtr<Vst3ConnectionPointProxy> connection_point_proxy;
|
||||
|
||||
/**
|
||||
* After a call to `IEditController::setComponentHandler()`, we'll create a
|
||||
* proxy of that component handler just like we did for the plugin object.
|
||||
|
||||
Reference in New Issue
Block a user