VST3: Use a proxy for connecting and passing messages #8481
This separates channels in each direction component <> controller, preventing recursions.
This commit is contained in:
parent
0cfee47867
commit
b79520d316
@ -198,6 +198,28 @@ protected:
|
||||
boost::shared_ptr<HostAttributeList> _attribute_list;
|
||||
};
|
||||
|
||||
class LIBARDOUR_API ConnectionProxy : public Vst::IConnectionPoint, public RefObject
|
||||
{
|
||||
public:
|
||||
ConnectionProxy (IConnectionPoint* src);
|
||||
~ConnectionProxy () SMTG_OVERRIDE;
|
||||
|
||||
QUERY_INTERFACE_IMPL (Vst::IConnectionPoint);
|
||||
uint32 PLUGIN_API addRef () SMTG_OVERRIDE { return RefObject::addRef (); }
|
||||
uint32 PLUGIN_API release () SMTG_OVERRIDE { return RefObject::release (); }
|
||||
|
||||
/* IConnectionPoint API */
|
||||
tresult PLUGIN_API connect (Vst::IConnectionPoint*) SMTG_OVERRIDE;
|
||||
tresult PLUGIN_API disconnect (Vst::IConnectionPoint*) SMTG_OVERRIDE;
|
||||
tresult PLUGIN_API notify (Vst::IMessage*) SMTG_OVERRIDE;
|
||||
|
||||
bool disconnect ();
|
||||
|
||||
protected:
|
||||
IConnectionPoint* _src;
|
||||
IConnectionPoint* _dst;
|
||||
};
|
||||
|
||||
class LIBARDOUR_API PlugInterfaceSupport : public Vst::IPlugInterfaceSupport
|
||||
{
|
||||
public:
|
||||
|
@ -54,7 +54,6 @@ namespace Steinberg {
|
||||
class LIBARDOUR_API VST3PI
|
||||
: public Vst::IComponentHandler
|
||||
, public Vst::IComponentHandler2
|
||||
, public Vst::IConnectionPoint
|
||||
, public Vst::IUnitHandler
|
||||
, public IPlugFrame
|
||||
, public Presonus::IContextInfoProvider3
|
||||
@ -75,11 +74,6 @@ public:
|
||||
tresult PLUGIN_API startGroupEdit () SMTG_OVERRIDE;
|
||||
tresult PLUGIN_API finishGroupEdit () SMTG_OVERRIDE;
|
||||
|
||||
/* IConnectionPoint API */
|
||||
tresult PLUGIN_API connect (Vst::IConnectionPoint* other) SMTG_OVERRIDE;
|
||||
tresult PLUGIN_API disconnect (Vst::IConnectionPoint* other) SMTG_OVERRIDE;
|
||||
tresult PLUGIN_API notify (Vst::IMessage* message) SMTG_OVERRIDE;
|
||||
|
||||
/* IPlugFrame */
|
||||
tresult PLUGIN_API resizeView (IPlugView* view, ViewRect* newSize) SMTG_OVERRIDE;
|
||||
|
||||
@ -217,7 +211,8 @@ private:
|
||||
|
||||
boost::shared_ptr<ARDOUR::VST3PluginModule> _module;
|
||||
|
||||
std::vector <Vst::IConnectionPoint*> _connections;
|
||||
boost::shared_ptr<ConnectionProxy> _component_cproxy;
|
||||
boost::shared_ptr<ConnectionProxy> _controller_cproxy;
|
||||
|
||||
FUID _fuid;
|
||||
Vst::IComponent* _component;
|
||||
|
@ -299,6 +299,90 @@ HostMessage::getAttributes ()
|
||||
|
||||
/* ****************************************************************************/
|
||||
|
||||
ConnectionProxy::ConnectionProxy (Vst::IConnectionPoint* src)
|
||||
: _src (src)
|
||||
, _dst (0)
|
||||
{
|
||||
if (_src) {
|
||||
_src->addRef ();
|
||||
}
|
||||
}
|
||||
|
||||
ConnectionProxy::~ConnectionProxy ()
|
||||
{
|
||||
if (_src) {
|
||||
_src->release ();
|
||||
}
|
||||
if (_dst) {
|
||||
_dst->release ();
|
||||
}
|
||||
}
|
||||
|
||||
tresult
|
||||
ConnectionProxy::connect (Vst::IConnectionPoint* dst)
|
||||
{
|
||||
if (!dst) {
|
||||
return kInvalidArgument;
|
||||
}
|
||||
if (_dst) {
|
||||
return kResultFalse;
|
||||
}
|
||||
|
||||
_dst = dst;
|
||||
_dst->addRef ();
|
||||
|
||||
tresult res = _src->connect (this);
|
||||
|
||||
if (res != kResultTrue) {
|
||||
_dst->release ();
|
||||
_dst = 0;
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
||||
tresult
|
||||
ConnectionProxy::disconnect (Vst::IConnectionPoint* dst)
|
||||
{
|
||||
if (!dst) {
|
||||
return kInvalidArgument;
|
||||
}
|
||||
|
||||
if (dst != _dst) {
|
||||
return kInvalidArgument;
|
||||
}
|
||||
|
||||
if (_src) {
|
||||
_src->disconnect (this);
|
||||
}
|
||||
|
||||
_dst->release ();
|
||||
_dst = 0;
|
||||
return kResultTrue;
|
||||
}
|
||||
|
||||
|
||||
tresult
|
||||
ConnectionProxy::notify (Vst::IMessage* message)
|
||||
{
|
||||
if (!_dst) {
|
||||
return kResultFalse;
|
||||
}
|
||||
#if 0
|
||||
if (strcmp ("ArdourGUI", pthread_name ())) {
|
||||
return kResultFalse;
|
||||
}
|
||||
#endif
|
||||
return _dst->notify (message);
|
||||
}
|
||||
|
||||
bool
|
||||
ConnectionProxy::disconnect ()
|
||||
{
|
||||
return kResultTrue == disconnect (_dst);
|
||||
}
|
||||
|
||||
/* ****************************************************************************/
|
||||
|
||||
PlugInterfaceSupport::PlugInterfaceSupport ()
|
||||
{
|
||||
using namespace Vst;
|
||||
|
@ -1232,14 +1232,18 @@ VST3PI::connect_components ()
|
||||
return true;
|
||||
}
|
||||
|
||||
tresult res = componentCP->connect (this);
|
||||
_component_cproxy = boost::shared_ptr<ConnectionProxy> (new ConnectionProxy (componentCP));
|
||||
_controller_cproxy = boost::shared_ptr<ConnectionProxy> (new ConnectionProxy (controllerCP));
|
||||
|
||||
tresult res = _component_cproxy->connect (controllerCP);
|
||||
if (!(res == kResultOk || res == kNotImplemented)) {
|
||||
return false;
|
||||
DEBUG_TRACE (DEBUG::VST3Config, "VST3PI::connect_components Cannot connect controller to component\n");
|
||||
//return false;
|
||||
}
|
||||
|
||||
res = controllerCP->connect (this);
|
||||
res = _controller_cproxy->connect (componentCP);
|
||||
if (!(res == kResultOk || res == kNotImplemented)) {
|
||||
DEBUG_TRACE (DEBUG::VST3Config, "VST3PI::connect_components Cannot connect controller, ignored.\n");
|
||||
DEBUG_TRACE (DEBUG::VST3Config, "VST3PI::connect_components Cannot connect component to controller\n");
|
||||
}
|
||||
|
||||
return true;
|
||||
@ -1248,60 +1252,17 @@ VST3PI::connect_components ()
|
||||
bool
|
||||
VST3PI::disconnect_components ()
|
||||
{
|
||||
FUnknownPtr<Vst::IConnectionPoint> componentCP (_component);
|
||||
FUnknownPtr<Vst::IConnectionPoint> controllerCP (_controller);
|
||||
if (!componentCP || !controllerCP) {
|
||||
if (!_component_cproxy || !_controller_cproxy) {
|
||||
return false;
|
||||
}
|
||||
|
||||
bool res = kResultTrue == componentCP->disconnect (this);
|
||||
res &= kResultTrue == controllerCP->disconnect (this);
|
||||
return res;
|
||||
}
|
||||
bool rv = _component_cproxy->disconnect ();
|
||||
rv &= _controller_cproxy->disconnect ();
|
||||
|
||||
tresult
|
||||
VST3PI::connect (Vst::IConnectionPoint* other)
|
||||
{
|
||||
if (!other) {
|
||||
return kInvalidArgument;
|
||||
}
|
||||
_connections.push_back (other);
|
||||
return kResultTrue;
|
||||
}
|
||||
_component_cproxy.reset ();
|
||||
_controller_cproxy.reset ();
|
||||
|
||||
tresult
|
||||
VST3PI::disconnect (Vst::IConnectionPoint* other)
|
||||
{
|
||||
std::vector <Vst::IConnectionPoint*>::iterator i = std::find (_connections.begin(), _connections.end(), other);
|
||||
if (i != _connections.end()) {
|
||||
_connections.erase (i);
|
||||
return kResultTrue;
|
||||
}
|
||||
return kInvalidArgument;
|
||||
}
|
||||
|
||||
tresult
|
||||
VST3PI::notify (Vst::IMessage* msg)
|
||||
{
|
||||
DEBUG_TRACE (DEBUG::VST3Callbacks, "VST3PI::notify.\n");
|
||||
for (std::vector <Vst::IConnectionPoint*>::const_iterator i = _connections.begin(); i != _connections.end(); ++i) {
|
||||
/* TODO delegate to GUI thread if available
|
||||
* see ./libs/pbd/pbd/event_loop.h ir->call_slot ()
|
||||
* and HostMessage()
|
||||
*/
|
||||
(*i)->notify (msg);
|
||||
}
|
||||
|
||||
FUnknownPtr<Vst::IConnectionPoint> componentCP (_component);
|
||||
FUnknownPtr<Vst::IConnectionPoint> controllerCP (_controller);
|
||||
if (componentCP) {
|
||||
componentCP->notify (msg);
|
||||
}
|
||||
if (controllerCP) {
|
||||
controllerCP->notify (msg);
|
||||
}
|
||||
|
||||
return kResultTrue;
|
||||
return rv;
|
||||
}
|
||||
|
||||
tresult
|
||||
@ -1311,7 +1272,6 @@ VST3PI::queryInterface (const TUID _iid, void** obj)
|
||||
QUERY_INTERFACE (_iid, obj, Vst::IComponentHandler::iid, Vst::IComponentHandler)
|
||||
QUERY_INTERFACE (_iid, obj, Vst::IComponentHandler2::iid, Vst::IComponentHandler2)
|
||||
|
||||
QUERY_INTERFACE (_iid, obj, Vst::IConnectionPoint::iid, Vst::IConnectionPoint)
|
||||
QUERY_INTERFACE (_iid, obj, Vst::IUnitHandler::iid, Vst::IUnitHandler)
|
||||
|
||||
QUERY_INTERFACE (_iid, obj, Presonus::IContextInfoProvider::iid, Presonus::IContextInfoProvider)
|
||||
|
Loading…
Reference in New Issue
Block a user