mirror of
https://github.com/robbert-vdh/yabridge.git
synced 2026-05-09 20:29:10 +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:
@@ -16,8 +16,6 @@ This branch is still very far removed from being in a usable state. Below is an
|
|||||||
incomplete list of things that still have to be done before this can be used:
|
incomplete list of things that still have to be done before this can be used:
|
||||||
|
|
||||||
- Interfaces left to implement:
|
- Interfaces left to implement:
|
||||||
- `IConnectionPoint::notify()`, and support for indirectly connecting objects
|
|
||||||
through connction proxies
|
|
||||||
- `IEditController2`
|
- `IEditController2`
|
||||||
- All other mandatory interfaces
|
- All other mandatory interfaces
|
||||||
- All other optional interfaces
|
- All other optional interfaces
|
||||||
|
|||||||
@@ -94,8 +94,17 @@ bool Vst3Logger::log_request(bool is_host_vst,
|
|||||||
const YaConnectionPoint::Connect& request) {
|
const YaConnectionPoint::Connect& request) {
|
||||||
return log_request_base(is_host_vst, [&](auto& message) {
|
return log_request_base(is_host_vst, [&](auto& message) {
|
||||||
message << request.instance_id
|
message << request.instance_id
|
||||||
<< ": IConnectionPoint::connect(other = <IConnectionPoint* #"
|
<< ": IConnectionPoint::connect(other = ";
|
||||||
<< request.other_instance_id << ">)";
|
std::visit(
|
||||||
|
overload{[&](const native_size_t& other_instance_id) {
|
||||||
|
message << "<IConnectionPoint* #" << other_instance_id
|
||||||
|
<< ">";
|
||||||
|
},
|
||||||
|
[&](const Vst3ConnectionPointProxy::ConstructArgs&) {
|
||||||
|
message << "<IConnectionPoint* proxy>";
|
||||||
|
}},
|
||||||
|
request.other);
|
||||||
|
message << ")";
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -103,8 +112,14 @@ bool Vst3Logger::log_request(bool is_host_vst,
|
|||||||
const YaConnectionPoint::Disconnect& request) {
|
const YaConnectionPoint::Disconnect& request) {
|
||||||
return log_request_base(is_host_vst, [&](auto& message) {
|
return log_request_base(is_host_vst, [&](auto& message) {
|
||||||
message << request.instance_id
|
message << request.instance_id
|
||||||
<< ": IConnectionPoint::disconnect(other = <IConnectionPoint* #"
|
<< ": IConnectionPoint::disconnect(other = ";
|
||||||
<< request.other_instance_id << ">)";
|
if (request.other_instance_id) {
|
||||||
|
message << "<IConnectionPoint* #" << *request.other_instance_id
|
||||||
|
<< ">";
|
||||||
|
} else {
|
||||||
|
message << "<IConnectionPoint* proxy>";
|
||||||
|
}
|
||||||
|
message << ")";
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -16,13 +16,6 @@
|
|||||||
|
|
||||||
#include "connection-point-proxy.h"
|
#include "connection-point-proxy.h"
|
||||||
|
|
||||||
Vst3ConnectionPointProxy::ConstructArgs::ConstructArgs() {}
|
|
||||||
|
|
||||||
Vst3ConnectionPointProxy::ConstructArgs::ConstructArgs(
|
|
||||||
Steinberg::IPtr<Steinberg::FUnknown> object,
|
|
||||||
size_t owner_instance_id)
|
|
||||||
: owner_instance_id(owner_instance_id), connection_point_args(object) {}
|
|
||||||
|
|
||||||
Vst3ConnectionPointProxy::Vst3ConnectionPointProxy(const ConstructArgs&& args)
|
Vst3ConnectionPointProxy::Vst3ConnectionPointProxy(const ConstructArgs&& args)
|
||||||
: YaConnectionPoint(std::move(args.connection_point_args)),
|
: YaConnectionPoint(std::move(args.connection_point_args)),
|
||||||
arguments(std::move(args)){FUNKNOWN_CTOR}
|
arguments(std::move(args)){FUNKNOWN_CTOR}
|
||||||
|
|||||||
@@ -38,40 +38,10 @@
|
|||||||
*/
|
*/
|
||||||
class Vst3ConnectionPointProxy : public YaConnectionPoint {
|
class Vst3ConnectionPointProxy : public YaConnectionPoint {
|
||||||
public:
|
public:
|
||||||
/**
|
// We had to define this in `YaConnectionPoint` to work around circular
|
||||||
* These are the arguments for constructing a
|
// includes
|
||||||
* `Vst3ConnectionPointProxyImpl`.
|
using ConstructArgs =
|
||||||
*/
|
YaConnectionPoint::Vst3ConnectionPointProxyConstructArgs;
|
||||||
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.
|
|
||||||
*
|
|
||||||
* This is not necessary in this case since the object has to support
|
|
||||||
* `IConnectionPoint`, but let's stay consistent with the overall style
|
|
||||||
* here.
|
|
||||||
*/
|
|
||||||
ConstructArgs(Steinberg::IPtr<FUnknown> object,
|
|
||||||
size_t owner_instance_id);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* The unique instance identifier of the proxy object instance this
|
|
||||||
* connection proxy has been passed to and thus belongs to. This way we
|
|
||||||
* can refer to the correct 'actual' `IConnectionPoint` instance when
|
|
||||||
* the plugin calls `notify()` on this proxy object.
|
|
||||||
*/
|
|
||||||
native_size_t owner_instance_id;
|
|
||||||
|
|
||||||
YaConnectionPoint::ConstructArgs connection_point_args;
|
|
||||||
|
|
||||||
template <typename S>
|
|
||||||
void serialize(S& s) {
|
|
||||||
s.value8b(owner_instance_id);
|
|
||||||
s.object(connection_point_args);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Instantiate this instance with arguments read from an actual
|
* Instantiate this instance with arguments read from an actual
|
||||||
|
|||||||
@@ -23,5 +23,14 @@ YaConnectionPoint::ConstructArgs::ConstructArgs(
|
|||||||
: supported(
|
: supported(
|
||||||
Steinberg::FUnknownPtr<Steinberg::Vst::IConnectionPoint>(object)) {}
|
Steinberg::FUnknownPtr<Steinberg::Vst::IConnectionPoint>(object)) {}
|
||||||
|
|
||||||
|
YaConnectionPoint::Vst3ConnectionPointProxyConstructArgs::
|
||||||
|
Vst3ConnectionPointProxyConstructArgs() {}
|
||||||
|
|
||||||
|
YaConnectionPoint::Vst3ConnectionPointProxyConstructArgs::
|
||||||
|
Vst3ConnectionPointProxyConstructArgs(
|
||||||
|
Steinberg::IPtr<Steinberg::FUnknown> object,
|
||||||
|
size_t owner_instance_id)
|
||||||
|
: owner_instance_id(owner_instance_id), connection_point_args(object) {}
|
||||||
|
|
||||||
YaConnectionPoint::YaConnectionPoint(const ConstructArgs&& args)
|
YaConnectionPoint::YaConnectionPoint(const ConstructArgs&& args)
|
||||||
: arguments(std::move(args)) {}
|
: arguments(std::move(args)) {}
|
||||||
|
|||||||
@@ -16,7 +16,10 @@
|
|||||||
|
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
|
#include <variant>
|
||||||
|
|
||||||
#include <bitsery/ext/std_optional.h>
|
#include <bitsery/ext/std_optional.h>
|
||||||
|
#include <bitsery/ext/std_variant.h>
|
||||||
#include <pluginterfaces/vst/ivstmessage.h>
|
#include <pluginterfaces/vst/ivstmessage.h>
|
||||||
|
|
||||||
#include "../../common.h"
|
#include "../../common.h"
|
||||||
@@ -32,8 +35,6 @@
|
|||||||
* monolithic proxy class we can easily directly connect different objects by
|
* monolithic proxy class we can easily directly connect different objects by
|
||||||
* checking if they're a `Vst3PluginProxy` and then fetching that object's
|
* checking if they're a `Vst3PluginProxy` and then fetching that object's
|
||||||
* instance ID (if the host doesn't place a proxy object here).
|
* instance ID (if the host doesn't place a proxy object here).
|
||||||
*
|
|
||||||
* TODO: Make sure we somehow handle proxies created by the host here.
|
|
||||||
*/
|
*/
|
||||||
class YaConnectionPoint : public Steinberg::Vst::IConnectionPoint {
|
class YaConnectionPoint : public Steinberg::Vst::IConnectionPoint {
|
||||||
public:
|
public:
|
||||||
@@ -60,6 +61,45 @@ class YaConnectionPoint : public Steinberg::Vst::IConnectionPoint {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
protected:
|
||||||
|
/**
|
||||||
|
* These are the arguments for constructing a
|
||||||
|
* `Vst3ConnectionPointProxyImpl`.
|
||||||
|
*
|
||||||
|
* It's defined here to work around circular includes.
|
||||||
|
*/
|
||||||
|
struct Vst3ConnectionPointProxyConstructArgs {
|
||||||
|
Vst3ConnectionPointProxyConstructArgs();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Read from an existing object. We will try to mimic this object, so
|
||||||
|
* we'll support any interfaces this object also supports.
|
||||||
|
*
|
||||||
|
* This is not necessary in this case since the object has to support
|
||||||
|
* `IConnectionPoint`, but let's stay consistent with the overall style
|
||||||
|
* here.
|
||||||
|
*/
|
||||||
|
Vst3ConnectionPointProxyConstructArgs(Steinberg::IPtr<FUnknown> object,
|
||||||
|
size_t owner_instance_id);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The unique instance identifier of the proxy object instance this
|
||||||
|
* connection proxy has been passed to and thus belongs to. This way we
|
||||||
|
* can refer to the correct 'actual' `IConnectionPoint` instance when
|
||||||
|
* the plugin calls `notify()` on this proxy object.
|
||||||
|
*/
|
||||||
|
native_size_t owner_instance_id;
|
||||||
|
|
||||||
|
ConstructArgs connection_point_args;
|
||||||
|
|
||||||
|
template <typename S>
|
||||||
|
void serialize(S& s) {
|
||||||
|
s.value8b(owner_instance_id);
|
||||||
|
s.object(connection_point_args);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
public:
|
||||||
/**
|
/**
|
||||||
* Instantiate this instance with arguments read from another interface
|
* Instantiate this instance with arguments read from another interface
|
||||||
* implementation.
|
* implementation.
|
||||||
@@ -69,10 +109,10 @@ class YaConnectionPoint : public Steinberg::Vst::IConnectionPoint {
|
|||||||
inline bool supported() const { return arguments.supported; }
|
inline bool supported() const { return arguments.supported; }
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Message to pass through a call to
|
* Message to pass through a call to `IConnectionPoint::connect(other)` to
|
||||||
* `IConnectionPoint::connect(other_instance_id)` to the Wine plugin host.
|
* the Wine plugin host. If the host directly connects two objects, then
|
||||||
* At the moment this is only implemented for directly connecting objects
|
* we'll connect them directly as well. Otherwise all messages have to be
|
||||||
* created by the plugin without any proxies in between them.
|
* routed through the host.
|
||||||
*/
|
*/
|
||||||
struct Connect {
|
struct Connect {
|
||||||
using Response = UniversalTResult;
|
using Response = UniversalTResult;
|
||||||
@@ -82,24 +122,32 @@ class YaConnectionPoint : public Steinberg::Vst::IConnectionPoint {
|
|||||||
/**
|
/**
|
||||||
* The other object this object should be connected to. When connecting
|
* The other object this object should be connected to. When connecting
|
||||||
* two `Vst3PluginProxy` objects, we can directly connect the underlying
|
* two `Vst3PluginProxy` objects, we can directly connect the underlying
|
||||||
* objects on the Wine side.
|
* objects on the Wine side using their instance IDs. Otherwise we'll
|
||||||
|
* create a proxy object for the connection proxy provided by the host
|
||||||
|
* that the plugin can use to send messages to.
|
||||||
*/
|
*/
|
||||||
native_size_t other_instance_id;
|
std::variant<native_size_t, Vst3ConnectionPointProxyConstructArgs>
|
||||||
|
other;
|
||||||
|
|
||||||
template <typename S>
|
template <typename S>
|
||||||
void serialize(S& s) {
|
void serialize(S& s) {
|
||||||
s.value8b(instance_id);
|
s.value8b(instance_id);
|
||||||
s.value8b(other_instance_id);
|
s.ext(other,
|
||||||
|
bitsery::ext::StdVariant{
|
||||||
|
[](S& s, native_size_t& other_instance_id) {
|
||||||
|
s.value8b(other_instance_id);
|
||||||
|
},
|
||||||
|
[](S& s, Vst3ConnectionPointProxyConstructArgs& args) {
|
||||||
|
s.object(args);
|
||||||
|
}});
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
virtual tresult PLUGIN_API connect(IConnectionPoint* other) override = 0;
|
virtual tresult PLUGIN_API connect(IConnectionPoint* other) override = 0;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Message to pass through a call to
|
* Message to pass through a call to `IConnectionPoint::disconnect(other)`
|
||||||
* `IConnectionPoint::disconnect(other_instance_id)` to the Wine plugin
|
* to the Wine plugin host.
|
||||||
* host. At the moment this is only implemented for directly connecting
|
|
||||||
* objects created by the plugin without any proxies in between them.
|
|
||||||
*/
|
*/
|
||||||
struct Disconnect {
|
struct Disconnect {
|
||||||
using Response = UniversalTResult;
|
using Response = UniversalTResult;
|
||||||
@@ -107,15 +155,19 @@ class YaConnectionPoint : public Steinberg::Vst::IConnectionPoint {
|
|||||||
native_size_t instance_id;
|
native_size_t instance_id;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The other object backed by a `Vst3PluginProxy` this object was
|
* If we connected two objects directly, then this is the instance ID of
|
||||||
* connected to and should be disconnected from. When connecting.
|
* that object. Otherwise we'll just destroy the smart pointer pointing
|
||||||
|
* to our `IConnectionPoint` proxy object.
|
||||||
*/
|
*/
|
||||||
native_size_t other_instance_id;
|
std::optional<native_size_t> other_instance_id;
|
||||||
|
|
||||||
template <typename S>
|
template <typename S>
|
||||||
void serialize(S& s) {
|
void serialize(S& s) {
|
||||||
s.value8b(instance_id);
|
s.value8b(instance_id);
|
||||||
s.value8b(other_instance_id);
|
s.ext(other_instance_id, bitsery::ext::StdOptional{},
|
||||||
|
[](S& s, native_size_t& instance_id) {
|
||||||
|
s.value8b(instance_id);
|
||||||
|
});
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -214,17 +214,19 @@ tresult PLUGIN_API Vst3PluginProxyImpl::getState(Steinberg::IBStream* state) {
|
|||||||
tresult PLUGIN_API Vst3PluginProxyImpl::connect(IConnectionPoint* other) {
|
tresult PLUGIN_API Vst3PluginProxyImpl::connect(IConnectionPoint* other) {
|
||||||
// When the host is trying to connect two plugin proxy objects, we can just
|
// When the host is trying to connect two plugin proxy objects, we can just
|
||||||
// identify the other object by its instance IDs and then connect the
|
// identify the other object by its instance IDs and then connect the
|
||||||
// objects in the Wine plugin host directly
|
// objects in the Wine plugin host directly. Otherwise we'll have to set up
|
||||||
|
// a proxy for the host's connection proxy so the messages can be routed
|
||||||
|
// through that.
|
||||||
if (auto other_proxy = dynamic_cast<Vst3PluginProxy*>(other)) {
|
if (auto other_proxy = dynamic_cast<Vst3PluginProxy*>(other)) {
|
||||||
return bridge.send_message(YaConnectionPoint::Connect{
|
return bridge.send_message(YaConnectionPoint::Connect{
|
||||||
.instance_id = instance_id(),
|
.instance_id = instance_id(), .other = other_proxy->instance_id()});
|
||||||
.other_instance_id = other_proxy->instance_id()});
|
|
||||||
} else {
|
} else {
|
||||||
// TODO: Add support for `ConnectionProxy` and similar objects
|
connection_point_proxy = other;
|
||||||
bridge.logger.log(
|
|
||||||
"WARNING: The host passed a proxy proxy object to "
|
return bridge.send_message(YaConnectionPoint::Connect{
|
||||||
"'IConnectionPoint::connect()'. This is currently not supported.");
|
.instance_id = instance_id(),
|
||||||
return Steinberg::kNotImplemented;
|
.other =
|
||||||
|
Vst3ConnectionPointProxy::ConstructArgs(other, instance_id())});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -235,12 +237,12 @@ tresult PLUGIN_API Vst3PluginProxyImpl::disconnect(IConnectionPoint* other) {
|
|||||||
.instance_id = instance_id(),
|
.instance_id = instance_id(),
|
||||||
.other_instance_id = other_proxy->instance_id()});
|
.other_instance_id = other_proxy->instance_id()});
|
||||||
} else {
|
} else {
|
||||||
// TODO: Add support for `ConnectionProxy` and similar objects
|
const tresult result = bridge.send_message(
|
||||||
bridge.logger.log(
|
YaConnectionPoint::Disconnect{.instance_id = instance_id(),
|
||||||
"WARNING: The host passed a proxy proxy object to "
|
.other_instance_id = std::nullopt});
|
||||||
"'IConnectionPoint::disconnect()'. This is currently not "
|
connection_point_proxy.reset();
|
||||||
"supported.");
|
|
||||||
return Steinberg::kNotImplemented;
|
return result;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -21,6 +21,7 @@
|
|||||||
#include <public.sdk/source/vst/hosting/module_win32.cpp>
|
#include <public.sdk/source/vst/hosting/module_win32.cpp>
|
||||||
|
|
||||||
#include "vst3-impls/component-handler-proxy.h"
|
#include "vst3-impls/component-handler-proxy.h"
|
||||||
|
#include "vst3-impls/connection-point-proxy.h"
|
||||||
#include "vst3-impls/host-context-proxy.h"
|
#include "vst3-impls/host-context-proxy.h"
|
||||||
#include "vst3-impls/plug-frame-proxy.h"
|
#include "vst3-impls/plug-frame-proxy.h"
|
||||||
|
|
||||||
@@ -168,24 +169,55 @@ void Vst3Bridge::run() {
|
|||||||
return Vst3PluginProxy::GetStateResponse{
|
return Vst3PluginProxy::GetStateResponse{
|
||||||
.result = result, .updated_state = std::move(stream)};
|
.result = result, .updated_state = std::move(stream)};
|
||||||
},
|
},
|
||||||
[&](const YaConnectionPoint::Connect& request)
|
[&](YaConnectionPoint::Connect& request)
|
||||||
-> YaConnectionPoint::Connect::Response {
|
-> YaConnectionPoint::Connect::Response {
|
||||||
// We can directly connect the underlying objects
|
// If the host directly connected the underlying objects then we
|
||||||
// TODO: Add support for connecting objects through a proxy
|
// can directly connect them as well. Otherwise we'll have to go
|
||||||
// object provided by the host
|
// through a connection proxy (to proxy the host's connection
|
||||||
return object_instances[request.instance_id]
|
// proxy).
|
||||||
.connection_point->connect(
|
return std::visit(
|
||||||
object_instances[request.other_instance_id]
|
overload{
|
||||||
.connection_point);
|
[&](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)
|
[&](const YaConnectionPoint::Disconnect& request)
|
||||||
-> YaConnectionPoint::Disconnect::Response {
|
-> YaConnectionPoint::Disconnect::Response {
|
||||||
// TODO: Add support for connecting objects through a proxy
|
// If the objects were connected directly we can also disconnect
|
||||||
// object provided by the host
|
// them directly. Otherwise we'll disconnect them from our proxy
|
||||||
return object_instances[request.instance_id]
|
// object and then destroy that proxy object.
|
||||||
.connection_point->disconnect(
|
if (request.other_instance_id) {
|
||||||
object_instances[request.other_instance_id]
|
return object_instances[request.instance_id]
|
||||||
.connection_point);
|
.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& request)
|
||||||
-> YaConnectionPoint::Notify::Response {
|
-> YaConnectionPoint::Notify::Response {
|
||||||
|
|||||||
@@ -26,9 +26,6 @@
|
|||||||
#include "../editor.h"
|
#include "../editor.h"
|
||||||
#include "common.h"
|
#include "common.h"
|
||||||
|
|
||||||
// Forward declarations
|
|
||||||
class Vst3PlugFrameProxyImpl;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A holder for plugin object instance created from the factory. This stores all
|
* 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
|
* relevant interface smart pointers to that object so we can handle control
|
||||||
@@ -57,6 +54,18 @@ struct InstanceInterfaces {
|
|||||||
*/
|
*/
|
||||||
Steinberg::IPtr<Vst3HostContextProxy> host_context_proxy;
|
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
|
* After a call to `IEditController::setComponentHandler()`, we'll create a
|
||||||
* proxy of that component handler just like we did for the plugin object.
|
* proxy of that component handler just like we did for the plugin object.
|
||||||
|
|||||||
Reference in New Issue
Block a user