diff options
author | David Robillard <d@drobilla.net> | 2008-06-10 17:41:26 +0000 |
---|---|---|
committer | David Robillard <d@drobilla.net> | 2008-06-10 17:41:26 +0000 |
commit | 6ed65a4a3b14d204a24ab63fa907f8e9adce01dc (patch) | |
tree | 52ec9bafe242c976b70f8422f1a33f9e78d9ab16 | |
parent | 43dc73756cf97b4e4bc2ebdec59f3cb15f99750b (diff) | |
download | ingen-6ed65a4a3b14d204a24ab63fa907f8e9adce01dc.tar.gz ingen-6ed65a4a3b14d204a24ab63fa907f8e9adce01dc.tar.bz2 ingen-6ed65a4a3b14d204a24ab63fa907f8e9adce01dc.zip |
Fix 'disconnect' operation for all objects (inc. patch ports).
Fixes ticket #147.
git-svn-id: http://svn.drobilla.net/lad/ingen@1265 a436a847-0d15-0410-975c-d299462d15a1
26 files changed, 280 insertions, 429 deletions
diff --git a/src/common/interface/EngineInterface.hpp b/src/common/interface/EngineInterface.hpp index 32706724..c8fd08a9 100644 --- a/src/common/interface/EngineInterface.hpp +++ b/src/common/interface/EngineInterface.hpp @@ -97,7 +97,8 @@ public: virtual void disconnect(const string& src_port_path, const string& dst_port_path) = 0; - virtual void disconnect_all(const string& path) = 0; + virtual void disconnect_all(const string& parent_patch_path, + const string& path) = 0; virtual void set_port_value(const string& port_path, const string& type_uri, diff --git a/src/libs/client/OSCEngineSender.cpp b/src/libs/client/OSCEngineSender.cpp index 345f4be3..20070ff9 100644 --- a/src/libs/client/OSCEngineSender.cpp +++ b/src/libs/client/OSCEngineSender.cpp @@ -340,11 +340,13 @@ OSCEngineSender::disconnect(const string& src_port_path, void -OSCEngineSender::disconnect_all(const string& node_path) +OSCEngineSender::disconnect_all(const string& parent_patch_path, + const string& node_path) { assert(_engine_addr); - lo_send(_engine_addr, "/ingen/disconnect_all", "is", + lo_send(_engine_addr, "/ingen/disconnect_all", "iss", next_id(), + parent_patch_path.c_str(), node_path.c_str()); } diff --git a/src/libs/client/OSCEngineSender.hpp b/src/libs/client/OSCEngineSender.hpp index eb6dd2ee..6bd088ec 100644 --- a/src/libs/client/OSCEngineSender.hpp +++ b/src/libs/client/OSCEngineSender.hpp @@ -109,7 +109,8 @@ public: void disconnect(const string& src_port_path, const string& dst_port_path); - void disconnect_all(const string& node_path); + void disconnect_all(const string& parent_patch_path, + const string& node_path); void set_port_value(const string& port_path, const string& type_uri, diff --git a/src/libs/engine/Makefile.am b/src/libs/engine/Makefile.am index b53b28e1..9ddfe88a 100644 --- a/src/libs/engine/Makefile.am +++ b/src/libs/engine/Makefile.am @@ -135,10 +135,8 @@ libingen_engine_la_SOURCES = \ events/DeactivateEvent.hpp \ events/DestroyEvent.cpp \ events/DestroyEvent.hpp \ - events/DisconnectNodeEvent.cpp \ - events/DisconnectNodeEvent.hpp \ - events/DisconnectPortEvent.cpp \ - events/DisconnectPortEvent.hpp \ + events/DisconnectAllEvent.cpp \ + events/DisconnectAllEvent.hpp \ events/DisconnectionEvent.cpp \ events/DisconnectionEvent.hpp \ events/EnablePatchEvent.cpp \ diff --git a/src/libs/engine/OSCEngineReceiver.cpp b/src/libs/engine/OSCEngineReceiver.cpp index 20971e5a..c5ea7dae 100644 --- a/src/libs/engine/OSCEngineReceiver.cpp +++ b/src/libs/engine/OSCEngineReceiver.cpp @@ -101,7 +101,7 @@ OSCEngineReceiver::OSCEngineReceiver(Engine& engine, size_t queue_size, uint16_t lo_server_add_method(_server, "/ingen/rename", "iss", rename_cb, this); lo_server_add_method(_server, "/ingen/connect", "iss", connect_cb, this); lo_server_add_method(_server, "/ingen/disconnect", "iss", disconnect_cb, this); - lo_server_add_method(_server, "/ingen/disconnect_all", "is", disconnect_all_cb, this); + lo_server_add_method(_server, "/ingen/disconnect_all", "iss", disconnect_all_cb, this); lo_server_add_method(_server, "/ingen/set_port_value", NULL, set_port_value_cb, this); lo_server_add_method(_server, "/ingen/set_port_value_immediate", NULL, set_port_value_immediate_cb, this); lo_server_add_method(_server, "/ingen/enable_port_broadcasting", NULL, enable_port_broadcasting_cb, this); @@ -594,16 +594,18 @@ OSCEngineReceiver::_disconnect_cb(const char* path, const char* types, lo_arg** /** \page engine_osc_namespace - * <p> \b /ingen/disconnect_all - Disconnect all connections to/from a node. + * <p> \b /ingen/disconnect_all - Disconnect all connections to/from a node/port. * \arg \b response-id (integer) - * \arg \b node-path (string) - Full path of node. </p> \n \n + * \arg \b patch-path (string) - The (parent) patch in which to disconnect object. </p> \n \n + * \arg \b node-path (string) - Full path of object. </p> \n \n */ int OSCEngineReceiver::_disconnect_all_cb(const char* path, const char* types, lo_arg** argv, int argc, lo_message msg) { - const char* node_path = &argv[1]->s; + const char* patch_path = &argv[1]->s; + const char* object_path = &argv[2]->s; - disconnect_all(node_path); + disconnect_all(patch_path, object_path); return 0; } diff --git a/src/libs/engine/QueuedEngineInterface.cpp b/src/libs/engine/QueuedEngineInterface.cpp index a2603665..feb08c9c 100644 --- a/src/libs/engine/QueuedEngineInterface.cpp +++ b/src/libs/engine/QueuedEngineInterface.cpp @@ -227,9 +227,10 @@ QueuedEngineInterface::disconnect(const string& src_port_path, void -QueuedEngineInterface::disconnect_all(const string& node_path) +QueuedEngineInterface::disconnect_all(const string& patch_path, + const string& node_path) { - push_queued(new DisconnectNodeEvent(_engine, _responder, now(), node_path)); + push_queued(new DisconnectAllEvent(_engine, _responder, now(), patch_path, node_path)); } diff --git a/src/libs/engine/QueuedEngineInterface.hpp b/src/libs/engine/QueuedEngineInterface.hpp index ea4be595..54b3b5fd 100644 --- a/src/libs/engine/QueuedEngineInterface.hpp +++ b/src/libs/engine/QueuedEngineInterface.hpp @@ -116,7 +116,8 @@ public: virtual void disconnect(const string& src_port_path, const string& dst_port_path); - virtual void disconnect_all(const string& node_path); + virtual void disconnect_all(const string& patch_path, + const string& node_path); virtual void set_port_value(const string& port_path, const string& type_uri, diff --git a/src/libs/engine/events.hpp b/src/libs/engine/events.hpp index 54b23cce..a2ea50a5 100644 --- a/src/libs/engine/events.hpp +++ b/src/libs/engine/events.hpp @@ -28,7 +28,7 @@ #include "CreatePortEvent.hpp" #include "DeactivateEvent.hpp" #include "DestroyEvent.hpp" -#include "DisconnectNodeEvent.hpp" +#include "DisconnectAllEvent.hpp" #include "DisconnectionEvent.hpp" #include "EnablePatchEvent.hpp" #include "EnablePortBroadcastingEvent.hpp" diff --git a/src/libs/engine/events/DestroyEvent.cpp b/src/libs/engine/events/DestroyEvent.cpp index eef7ea0e..bc28501e 100644 --- a/src/libs/engine/events/DestroyEvent.cpp +++ b/src/libs/engine/events/DestroyEvent.cpp @@ -25,8 +25,7 @@ #include "PluginImpl.hpp" #include "AudioDriver.hpp" #include "MidiDriver.hpp" -#include "DisconnectNodeEvent.hpp" -#include "DisconnectPortEvent.hpp" +#include "DisconnectAllEvent.hpp" #include "ClientBroadcaster.hpp" #include "ObjectStore.hpp" #include "QueuedEventSource.hpp" @@ -44,8 +43,7 @@ DestroyEvent::DestroyEvent(Engine& engine, SharedPtr<Responder> responder, Frame , _patch_port_listnode(NULL) , _ports_array(NULL) , _compiled_patch(NULL) - , _disconnect_node_event(NULL) - , _disconnect_port_event(NULL) + , _disconnect_event(NULL) { assert(_source); } @@ -53,8 +51,7 @@ DestroyEvent::DestroyEvent(Engine& engine, SharedPtr<Responder> responder, Frame DestroyEvent::~DestroyEvent() { - delete _disconnect_node_event; - delete _disconnect_port_event; + delete _disconnect_event; } @@ -80,8 +77,8 @@ DestroyEvent::pre_process() if (_patch_node_listnode) { assert(_patch_node_listnode->elem() == _node.get()); - _disconnect_node_event = new DisconnectNodeEvent(_engine, _node.get()); - _disconnect_node_event->pre_process(); + _disconnect_event = new DisconnectAllEvent(_engine, _node->parent_patch(), _node.get()); + _disconnect_event->pre_process(); if (_node->parent_patch()->enabled()) { // FIXME: is this called multiple times? @@ -101,10 +98,8 @@ DestroyEvent::pre_process() if (_patch_port_listnode) { assert(_patch_port_listnode->elem() == _port.get()); - //_port->remove_from_store(); - - _disconnect_port_event = new DisconnectPortEvent(_engine, _port->parent_patch(), _port.get()); - _disconnect_port_event->pre_process(); + _disconnect_event = new DisconnectAllEvent(_engine, _port->parent_patch(), _port.get()); + _disconnect_event->pre_process(); if (_port->parent_patch()->enabled()) { // FIXME: is this called multiple times? @@ -128,8 +123,8 @@ DestroyEvent::execute(ProcessContext& context) if (_patch_node_listnode) { assert(_node); - if (_disconnect_node_event) - _disconnect_node_event->execute(context); + if (_disconnect_event) + _disconnect_event->execute(context); if (_node->parent_patch()->compiled_patch()) _engine.maid()->push(_node->parent_patch()->compiled_patch()); @@ -138,8 +133,8 @@ DestroyEvent::execute(ProcessContext& context) } else if (_patch_port_listnode) { assert(_port); - if (_disconnect_port_event) - _disconnect_port_event->execute(context); + if (_disconnect_event) + _disconnect_event->execute(context); if (_port->parent_patch()->compiled_patch()) _engine.maid()->push(_port->parent_patch()->compiled_patch()); @@ -183,8 +178,8 @@ DestroyEvent::post_process() _node->deactivate(); _responder->respond_ok(); _engine.broadcaster()->bundle_begin(); - if (_disconnect_node_event) - _disconnect_node_event->post_process(); + if (_disconnect_event) + _disconnect_event->post_process(); _engine.broadcaster()->send_destroyed(_path); _engine.broadcaster()->bundle_end(); _engine.maid()->push(_patch_node_listnode); @@ -192,8 +187,8 @@ DestroyEvent::post_process() assert(_port); _responder->respond_ok(); _engine.broadcaster()->bundle_begin(); - if (_disconnect_port_event) - _disconnect_port_event->post_process(); + if (_disconnect_event) + _disconnect_event->post_process(); _engine.broadcaster()->send_destroyed(_path); _engine.broadcaster()->bundle_end(); _engine.maid()->push(_patch_port_listnode); diff --git a/src/libs/engine/events/DestroyEvent.hpp b/src/libs/engine/events/DestroyEvent.hpp index 134290b1..5d87f27c 100644 --- a/src/libs/engine/events/DestroyEvent.hpp +++ b/src/libs/engine/events/DestroyEvent.hpp @@ -38,8 +38,7 @@ class GraphObjectImpl; class NodeImpl; class PortImpl; class DriverPort; -class DisconnectNodeEvent; -class DisconnectPortEvent; +class DisconnectAllEvent; class CompiledPatch; @@ -67,8 +66,7 @@ private: Raul::List<PortImpl*>::Node* _patch_port_listnode; Raul::Array<PortImpl*>* _ports_array; ///< New (external) ports for Patch CompiledPatch* _compiled_patch; ///< Patch's new process order - DisconnectNodeEvent* _disconnect_node_event; - DisconnectPortEvent* _disconnect_port_event; + DisconnectAllEvent* _disconnect_event; SharedPtr< Table<Path, SharedPtr<Shared::GraphObject> > > _removed_table; }; diff --git a/src/libs/engine/events/DisconnectAllEvent.cpp b/src/libs/engine/events/DisconnectAllEvent.cpp new file mode 100644 index 00000000..a536fffc --- /dev/null +++ b/src/libs/engine/events/DisconnectAllEvent.cpp @@ -0,0 +1,183 @@ +/* This file is part of Ingen. + * Copyright (C) 2007 Dave Robillard <http://drobilla.net> + * + * Ingen 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 2 of the License, or (at your option) any later + * version. + * + * Ingen 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 details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include <boost/format.hpp> +#include <raul/Array.hpp> +#include <raul/List.hpp> +#include <raul/Maid.hpp> +#include <raul/Path.hpp> +#include "ClientBroadcaster.hpp" +#include "ConnectionImpl.hpp" +#include "DisconnectAllEvent.hpp" +#include "DisconnectionEvent.hpp" +#include "Engine.hpp" +#include "InputPort.hpp" +#include "NodeImpl.hpp" +#include "ObjectStore.hpp" +#include "OutputPort.hpp" +#include "PatchImpl.hpp" +#include "PortImpl.hpp" +#include "Responder.hpp" +#include "util.hpp" + +namespace Ingen { + + +DisconnectAllEvent::DisconnectAllEvent(Engine& engine, SharedPtr<Responder> responder, SampleCount timestamp, const string& parent_path, const string& node_path) + : QueuedEvent(engine, responder, timestamp) + , _parent_path(parent_path) + , _path(node_path) + , _parent(NULL) + , _node(NULL) + , _port(NULL) + , _lookup(true) + , _error(NO_ERROR) +{ +} + + +/** Internal version for use by other events. + */ +DisconnectAllEvent::DisconnectAllEvent(Engine& engine, PatchImpl* parent, GraphObjectImpl* object) + : QueuedEvent(engine) + , _parent_path(parent->path()) + , _path(object->path()) + , _parent(parent) + , _node(dynamic_cast<NodeImpl*>(object)) + , _port(dynamic_cast<PortImpl*>(object)) + , _lookup(false) + , _error(NO_ERROR) +{ +} + + +DisconnectAllEvent::~DisconnectAllEvent() +{ + for (Raul::List<DisconnectionEvent*>::iterator i = _disconnection_events.begin(); i != _disconnection_events.end(); ++i) + delete (*i); +} + + +void +DisconnectAllEvent::pre_process() +{ + if (_lookup) { + _parent = _engine.object_store()->find_patch(_parent_path); + + if (_parent == NULL) { + _error = PARENT_NOT_FOUND; + QueuedEvent::pre_process(); + return; + } + + GraphObjectImpl* object = _engine.object_store()->find_object(_path); + + if (object == NULL) { + _error = OBJECT_NOT_FOUND; + QueuedEvent::pre_process(); + return; + } + + if (object->parent_patch() != _parent && object->parent()->parent_patch() != _parent) { + _error = INVALID_PARENT_PATH; + QueuedEvent::pre_process(); + return; + } + + // Only one of these will succeed + _node = dynamic_cast<NodeImpl*>(object); + _port = dynamic_cast<PortImpl*>(object); + + assert((_node || _port) && !(_node && _port)); + } + + if (_node) { + for (PatchImpl::Connections::const_iterator i = _parent->connections().begin(); + i != _parent->connections().end(); ++i) { + ConnectionImpl* c = (ConnectionImpl*)i->get(); + if ((c->src_port()->parent_node() == _node || c->dst_port()->parent_node() == _node) + && !c->pending_disconnection()) { + DisconnectionEvent* ev = new DisconnectionEvent(_engine, + SharedPtr<Responder>(new Responder()), _time, c->src_port(), c->dst_port()); + ev->pre_process(); + _disconnection_events.push_back(new Raul::List<DisconnectionEvent*>::Node(ev)); + c->pending_disconnection(true); + } + } + } else { // _port + for (PatchImpl::Connections::const_iterator i = _parent->connections().begin(); + i != _parent->connections().end(); ++i) { + ConnectionImpl* c = (ConnectionImpl*)i->get(); + if ((c->src_port() == _port || c->dst_port() == _port) && !c->pending_disconnection()) { + DisconnectionEvent* ev = new DisconnectionEvent(_engine, + SharedPtr<Responder>(new Responder()), _time, c->src_port(), c->dst_port()); + ev->pre_process(); + _disconnection_events.push_back(new Raul::List<DisconnectionEvent*>::Node(ev)); + c->pending_disconnection(true); + } + } + } + + QueuedEvent::pre_process(); +} + + +void +DisconnectAllEvent::execute(ProcessContext& context) +{ + QueuedEvent::execute(context); + + if (_error == NO_ERROR) { + for (Raul::List<DisconnectionEvent*>::iterator i = _disconnection_events.begin(); i != _disconnection_events.end(); ++i) + (*i)->execute(context); + } +} + + +void +DisconnectAllEvent::post_process() +{ + if (_error == NO_ERROR) { + if (_responder) + _responder->respond_ok(); + for (Raul::List<DisconnectionEvent*>::iterator i = _disconnection_events.begin(); + i != _disconnection_events.end(); ++i) + (*i)->post_process(); + } else { + if (_responder) { + boost::format fmt("Unable to disconnect %1% (%2%)"); + fmt % _path; + switch (_error) { + case INVALID_PARENT_PATH: + fmt % string("Invalid parent path: ").append(_parent_path); + break; + case PARENT_NOT_FOUND: + fmt % string("Unable to find parent: ").append(_parent_path); + break; + case OBJECT_NOT_FOUND: + fmt % string("Unable to find object"); + default: + break; + } + _responder->respond_error(fmt.str()); + } + } +} + + +} // namespace Ingen + diff --git a/src/libs/engine/events/DisconnectNodeEvent.hpp b/src/libs/engine/events/DisconnectAllEvent.hpp index 6d38c768..6b75e6df 100644 --- a/src/libs/engine/events/DisconnectNodeEvent.hpp +++ b/src/libs/engine/events/DisconnectAllEvent.hpp @@ -40,26 +40,36 @@ class OutputPort; * * \ingroup engine */ -class DisconnectNodeEvent : public QueuedEvent +class DisconnectAllEvent : public QueuedEvent { public: - DisconnectNodeEvent(Engine& engine, SharedPtr<Responder> responder, SampleCount timestamp, const string& node_path); - DisconnectNodeEvent(Engine& engine, NodeImpl* node); - ~DisconnectNodeEvent(); + DisconnectAllEvent(Engine& engine, SharedPtr<Responder> responder, SampleCount timestamp, const string& parent_path, const string& node_path); + DisconnectAllEvent(Engine& engine, PatchImpl* parent, GraphObjectImpl* object); + ~DisconnectAllEvent(); void pre_process(); void execute(ProcessContext& context); void post_process(); private: - Raul::Path _node_path; - PatchImpl* _patch; + enum ErrorType { + NO_ERROR, + INVALID_PARENT_PATH, + PARENT_NOT_FOUND, + OBJECT_NOT_FOUND, + }; + + Raul::Path _parent_path; + Raul::Path _path; + PatchImpl* _parent; NodeImpl* _node; + PortImpl* _port; Raul::List<DisconnectionEvent*> _disconnection_events; - bool _succeeded; bool _lookup; bool _disconnect_parent; + + ErrorType _error; }; diff --git a/src/libs/engine/events/DisconnectNodeEvent.cpp b/src/libs/engine/events/DisconnectNodeEvent.cpp deleted file mode 100644 index 4fa92af0..00000000 --- a/src/libs/engine/events/DisconnectNodeEvent.cpp +++ /dev/null @@ -1,135 +0,0 @@ -/* This file is part of Ingen. - * Copyright (C) 2007 Dave Robillard <http://drobilla.net> - * - * Ingen 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 2 of the License, or (at your option) any later - * version. - * - * Ingen 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 details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#include <raul/Array.hpp> -#include <raul/List.hpp> -#include <raul/Maid.hpp> -#include <raul/Path.hpp> -#include "ClientBroadcaster.hpp" -#include "ConnectionImpl.hpp" -#include "DisconnectNodeEvent.hpp" -#include "DisconnectionEvent.hpp" -#include "Engine.hpp" -#include "InputPort.hpp" -#include "NodeImpl.hpp" -#include "ObjectStore.hpp" -#include "OutputPort.hpp" -#include "PatchImpl.hpp" -#include "PortImpl.hpp" -#include "Responder.hpp" -#include "util.hpp" - -namespace Ingen { - - -DisconnectNodeEvent::DisconnectNodeEvent(Engine& engine, SharedPtr<Responder> responder, SampleCount timestamp, const string& node_path) -: QueuedEvent(engine, responder, timestamp), - _node_path(node_path), - _patch(NULL), - _node(NULL), - _succeeded(true), - _lookup(true) -{ -} - - -/** Internal version, disconnects parent port as well (in the case of InputNode, etc). - */ -DisconnectNodeEvent::DisconnectNodeEvent(Engine& engine, NodeImpl* node) -: QueuedEvent(engine), - _node_path(node->path()), - _patch(node->parent_patch()), - _node(node), - _succeeded(true), - _lookup(false) -{ -} - - -DisconnectNodeEvent::~DisconnectNodeEvent() -{ - for (Raul::List<DisconnectionEvent*>::iterator i = _disconnection_events.begin(); i != _disconnection_events.end(); ++i) - delete (*i); -} - - -void -DisconnectNodeEvent::pre_process() -{ - if (_lookup) { - _patch = _engine.object_store()->find_patch(_node_path.parent()); - - if (_patch == NULL) { - _succeeded = false; - QueuedEvent::pre_process(); - return; - } - - _node = _engine.object_store()->find_node(_node_path); - - if (_node == NULL) { - _succeeded = false; - QueuedEvent::pre_process(); - return; - } - } - - for (PatchImpl::Connections::const_iterator i = _patch->connections().begin(); i != _patch->connections().end(); ++i) { - ConnectionImpl* c = (ConnectionImpl*)i->get(); - if ((c->src_port()->parent_node() == _node || c->dst_port()->parent_node() == _node) && !c->pending_disconnection()) { - DisconnectionEvent* ev = new DisconnectionEvent(_engine, SharedPtr<Responder>(new Responder()), _time, - c->src_port(), c->dst_port()); - ev->pre_process(); - _disconnection_events.push_back(new Raul::List<DisconnectionEvent*>::Node(ev)); - c->pending_disconnection(true); - } - } - - _succeeded = true; - QueuedEvent::pre_process(); -} - - -void -DisconnectNodeEvent::execute(ProcessContext& context) -{ - QueuedEvent::execute(context); - - if (_succeeded) { - for (Raul::List<DisconnectionEvent*>::iterator i = _disconnection_events.begin(); i != _disconnection_events.end(); ++i) - (*i)->execute(context); - } -} - - -void -DisconnectNodeEvent::post_process() -{ - if (_succeeded) { - if (_responder) - _responder->respond_ok(); - for (Raul::List<DisconnectionEvent*>::iterator i = _disconnection_events.begin(); i != _disconnection_events.end(); ++i) - (*i)->post_process(); - } else { - if (_responder) - _responder->respond_error("Unable to disconnect all ports."); - } -} - - -} // namespace Ingen - diff --git a/src/libs/engine/events/DisconnectPortEvent.cpp b/src/libs/engine/events/DisconnectPortEvent.cpp deleted file mode 100644 index 617d86a2..00000000 --- a/src/libs/engine/events/DisconnectPortEvent.cpp +++ /dev/null @@ -1,151 +0,0 @@ -/* This file is part of Ingen. - * Copyright (C) 2007 Dave Robillard <http://drobilla.net> - * - * Ingen 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 2 of the License, or (at your option) any later - * version. - * - * Ingen 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 details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#include <iostream> -#include <raul/Maid.hpp> -#include <raul/List.hpp> -#include <raul/Path.hpp> -#include <raul/Array.hpp> -#include "Responder.hpp" -#include "Engine.hpp" -#include "NodeImpl.hpp" -#include "ConnectionImpl.hpp" -#include "DisconnectionEvent.hpp" -#include "PortImpl.hpp" -#include "InputPort.hpp" -#include "OutputPort.hpp" -#include "PatchImpl.hpp" -#include "ClientBroadcaster.hpp" -#include "util.hpp" -#include "ObjectStore.hpp" -#include "DisconnectPortEvent.hpp" - -using std::cerr; using std::endl; - -namespace Ingen { - - -DisconnectPortEvent::DisconnectPortEvent(Engine& engine, SharedPtr<Responder> responder, SampleCount timestamp, const string& port_path) -: QueuedEvent(engine, responder, timestamp), - _port_path(port_path), - _patch(NULL), - _port(NULL), - _process_order(NULL), - _succeeded(true), - _lookup(true) -{ -} - - -DisconnectPortEvent::DisconnectPortEvent(Engine& engine, PatchImpl* patch, Port* port) -: QueuedEvent(engine), - _port_path(port->path()), - _patch(patch), - _port(port), - _process_order(NULL), - _succeeded(true), - _lookup(false) -{ - //cerr << "DisconnectPortEvent(Engine& engine, )\n"; -} - - -DisconnectPortEvent::~DisconnectPortEvent() -{ - for (Raul::List<DisconnectionEvent*>::iterator i = _disconnection_events.begin(); i != _disconnection_events.end(); ++i) - delete (*i); -} - - -void -DisconnectPortEvent::pre_process() -{ - // cerr << "Preparing disconnection event...\n"; - - if (_lookup) { - - /* FIXME: Double lookup */ - - _patch = _engine.object_store()->find_patch(_port_path.parent().parent()); - - if (_patch == NULL) { - _succeeded = false; - QueuedEvent::pre_process(); - return; - } - - _port = _engine.object_store()->find_port(_port_path); - - if (_port == NULL) { - _succeeded = false; - QueuedEvent::pre_process(); - return; - } - } - - if (_patch == NULL) { - _succeeded = false; - QueuedEvent::pre_process(); - return; - } - - for (PatchImpl::Connections::const_iterator i = _patch->connections().begin(); - i != _patch->connections().end(); ++i) { - ConnectionImpl* c = (ConnectionImpl*)i->get(); - if ((c->src_port() == _port || c->dst_port() == _port) && !c->pending_disconnection()) { - DisconnectionEvent* ev = new DisconnectionEvent(_engine, SharedPtr<Responder>(new Responder()), _time, - c->src_port(), c->dst_port()); - ev->pre_process(); - _disconnection_events.push_back(new Raul::List<DisconnectionEvent*>::Node(ev)); - c->pending_disconnection(true); - } - } - - _succeeded = true; - QueuedEvent::pre_process(); -} - - -void -DisconnectPortEvent::execute(ProcessContext& context) -{ - QueuedEvent::execute(context); - - if (_succeeded) { - for (Raul::List<DisconnectionEvent*>::iterator i = _disconnection_events.begin(); i != _disconnection_events.end(); ++i) - (*i)->execute(context); - } -} - - -void -DisconnectPortEvent::post_process() -{ - if (_succeeded) { - if (_responder) - _responder->respond_ok(); - for (Raul::List<DisconnectionEvent*>::iterator i = _disconnection_events.begin(); i != _disconnection_events.end(); ++i) - (*i)->post_process(); - } else { - if (_responder) - _responder->respond_error("Unable to disconnect port."); - } -} - - -} // namespace Ingen - diff --git a/src/libs/engine/events/DisconnectPortEvent.hpp b/src/libs/engine/events/DisconnectPortEvent.hpp deleted file mode 100644 index de75ddf2..00000000 --- a/src/libs/engine/events/DisconnectPortEvent.hpp +++ /dev/null @@ -1,71 +0,0 @@ -/* This file is part of Ingen. - * Copyright (C) 2007 Dave Robillard <http://drobilla.net> - * - * Ingen 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 2 of the License, or (at your option) any later - * version. - * - * Ingen 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 details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#ifndef DISCONNECTPORTEVENT_H -#define DISCONNECTPORTEVENT_H - -#include <string> -#include <raul/Path.hpp> -#include "QueuedEvent.hpp" -#include <raul/List.hpp> - -namespace Raul { template <typename T> class Array; } - -namespace Ingen { - - -class PatchImpl; -class NodeImpl; -class Connection; -class PortImpl; -class DisconnectionEvent; - -using std::string; - - -/** An event to disconnect all connections to a Port. - * - * \ingroup engine - */ -class DisconnectPortEvent : public QueuedEvent -{ -public: - DisconnectPortEvent(Engine& engine, SharedPtr<Responder> responder, SampleCount timestamp, const string& port_path); - DisconnectPortEvent(Engine& engine, PatchImpl* patch, Port* port); - ~DisconnectPortEvent(); - - void pre_process(); - void execute(ProcessContext& context); - void post_process(); - -private: - Path _port_path; - PatchImpl* _patch; - Port* _port; - Raul::List<DisconnectionEvent*> _disconnection_events; - - Raul::Array<NodeImpl*>* _process_order; // Patch's new process order - - bool _succeeded; - bool _lookup; -}; - - -} // namespace Ingen - - -#endif // DISCONNECTPORTEVENT_H diff --git a/src/libs/engine/events/Makefile.am b/src/libs/engine/events/Makefile.am index f437be2c..18b02d8c 100644 --- a/src/libs/engine/events/Makefile.am +++ b/src/libs/engine/events/Makefile.am @@ -17,10 +17,8 @@ EXTRA_DIST = \ DeactivateEvent.hpp \ DestroyEvent.cpp \ DestroyEvent.hpp \ - DisconnectNodeEvent.cpp \ - DisconnectNodeEvent.hpp \ - DisconnectPortEvent.cpp \ - DisconnectPortEvent.hpp \ + DisconnectAllEvent.cpp \ + DisconnectAllEvent.hpp \ DisconnectionEvent.cpp \ DisconnectionEvent.hpp \ EnablePatchEvent.cpp \ diff --git a/src/libs/engine/events/RenameEvent.hpp b/src/libs/engine/events/RenameEvent.hpp index fae3a060..dbfc6d53 100644 --- a/src/libs/engine/events/RenameEvent.hpp +++ b/src/libs/engine/events/RenameEvent.hpp @@ -30,12 +30,7 @@ template<typename T> class ListNode; namespace Ingen { -class GraphObjectImpl; class PatchImpl; -class NodeImpl; -class Plugin; -class DisconnectNodeEvent; -class DisconnectPortEvent; /** An event to change the name of an GraphObjectImpl. diff --git a/src/libs/gui/NodeMenu.cpp b/src/libs/gui/NodeMenu.cpp index cbb4c0df..6051ec7c 100644 --- a/src/libs/gui/NodeMenu.cpp +++ b/src/libs/gui/NodeMenu.cpp @@ -125,6 +125,13 @@ NodeMenu::on_menu_learn() App::instance().engine()->midi_learn(_object->path()); } + +void +NodeMenu::on_menu_disconnect() +{ + App::instance().engine()->disconnect_all(_object->parent()->path(), _object->path()); +} + bool NodeMenu::has_control_inputs() diff --git a/src/libs/gui/NodeMenu.hpp b/src/libs/gui/NodeMenu.hpp index 05457b8f..2a10e473 100644 --- a/src/libs/gui/NodeMenu.hpp +++ b/src/libs/gui/NodeMenu.hpp @@ -55,6 +55,7 @@ protected: virtual void enable_controls_menuitem(); virtual void disable_controls_menuitem(); + void on_menu_disconnect(); void on_menu_clone(); void on_menu_learn(); void on_menu_embed_gui(); diff --git a/src/libs/gui/ObjectMenu.cpp b/src/libs/gui/ObjectMenu.cpp index 73d01389..3a208d51 100644 --- a/src/libs/gui/ObjectMenu.cpp +++ b/src/libs/gui/ObjectMenu.cpp @@ -92,13 +92,6 @@ ObjectMenu::polyphonic_changed(bool polyphonic) void -ObjectMenu::on_menu_disconnect() -{ - App::instance().engine()->disconnect_all(_object->path()); -} - - -void ObjectMenu::on_menu_destroy() { App::instance().engine()->destroy(_object->path()); diff --git a/src/libs/gui/ObjectMenu.hpp b/src/libs/gui/ObjectMenu.hpp index ab9eb30e..712322e3 100644 --- a/src/libs/gui/ObjectMenu.hpp +++ b/src/libs/gui/ObjectMenu.hpp @@ -46,10 +46,10 @@ public: protected: - void on_menu_polyphonic(); - void on_menu_disconnect(); - void on_menu_destroy(); - void on_menu_properties(); + virtual void on_menu_disconnect() = 0; + void on_menu_polyphonic(); + void on_menu_destroy(); + void on_menu_properties(); void polyphonic_changed(bool polyphonic); diff --git a/src/libs/gui/PatchPortModule.cpp b/src/libs/gui/PatchPortModule.cpp index de0ed445..a6192210 100644 --- a/src/libs/gui/PatchPortModule.cpp +++ b/src/libs/gui/PatchPortModule.cpp @@ -90,7 +90,7 @@ PatchPortModule::create_menu() { Glib::RefPtr<Gnome::Glade::Xml> xml = GladeFactory::new_glade_reference(); xml->get_widget_derived("object_menu", _menu); - _menu->init(_port); + _menu->init(_port, true); set_menu(_menu); } diff --git a/src/libs/gui/Port.cpp b/src/libs/gui/Port.cpp index df0b779c..36a010bb 100644 --- a/src/libs/gui/Port.cpp +++ b/src/libs/gui/Port.cpp @@ -42,6 +42,7 @@ Port::Port(boost::shared_ptr<FlowCanvas::Module> module, SharedPtr<PortModel> pm flip ? (!pm->is_input()) : pm->is_input(), App::instance().configuration()->get_port_color(pm.get())) , _port_model(pm) + , _flipped(flip) { assert(module); assert(_port_model); @@ -78,7 +79,7 @@ Port::create_menu() PortMenu* menu = NULL; Glib::RefPtr<Gnome::Glade::Xml> xml = GladeFactory::new_glade_reference(); xml->get_widget_derived("object_menu", menu); - menu->init(_port_model); + menu->init(_port_model, _flipped); set_menu(menu); } diff --git a/src/libs/gui/Port.hpp b/src/libs/gui/Port.hpp index e14110e7..ae9b0c48 100644 --- a/src/libs/gui/Port.hpp +++ b/src/libs/gui/Port.hpp @@ -57,6 +57,7 @@ private: void renamed(); SharedPtr<PortModel> _port_model; + bool _flipped; }; diff --git a/src/libs/gui/PortMenu.cpp b/src/libs/gui/PortMenu.cpp index 8bb002c9..45b216b6 100644 --- a/src/libs/gui/PortMenu.cpp +++ b/src/libs/gui/PortMenu.cpp @@ -30,14 +30,16 @@ namespace GUI { PortMenu::PortMenu(BaseObjectType* cobject, const Glib::RefPtr<Gnome::Glade::Xml>& xml) : ObjectMenu(cobject, xml) + , _patch_port(NULL) { } void -PortMenu::init(SharedPtr<PortModel> port) +PortMenu::init(SharedPtr<PortModel> port, bool patch_port) { ObjectMenu::init(port); + _patch_port = patch_port; if ( ! PtrCast<PatchModel>(port->parent()) ) { _polyphonic_menuitem->set_sensitive(false); @@ -48,6 +50,19 @@ PortMenu::init(SharedPtr<PortModel> port) _enable_signal = true; } + +void +PortMenu::on_menu_disconnect() +{ + if (_patch_port) { + App::instance().engine()->disconnect_all( + _object->parent()->path(), _object->path()); + } else { + App::instance().engine()->disconnect_all( + _object->parent()->path().parent(), _object->path()); + } +} + } // namespace GUI } // namespace Ingen diff --git a/src/libs/gui/PortMenu.hpp b/src/libs/gui/PortMenu.hpp index 06e8ac7d..520c5809 100644 --- a/src/libs/gui/PortMenu.hpp +++ b/src/libs/gui/PortMenu.hpp @@ -40,7 +40,12 @@ class PortMenu : public ObjectMenu public: PortMenu(BaseObjectType* cobject, const Glib::RefPtr<Gnome::Glade::Xml>& xml); - void init(SharedPtr<PortModel> port); + void init(SharedPtr<PortModel> port, bool patch_port = false); + +private: + void on_menu_disconnect(); + + bool _patch_port; }; |