diff options
-rw-r--r-- | src/client/ClientStore.cpp | 2 | ||||
-rw-r--r-- | src/client/PatchModel.cpp | 42 | ||||
-rw-r--r-- | src/client/PatchModel.hpp | 9 | ||||
-rw-r--r-- | src/common/interface/Patch.hpp | 4 | ||||
-rw-r--r-- | src/engine/InputPort.cpp | 6 | ||||
-rw-r--r-- | src/engine/MessageContext.cpp | 2 | ||||
-rw-r--r-- | src/engine/ObjectSender.cpp | 2 | ||||
-rw-r--r-- | src/engine/PatchImpl.cpp | 51 | ||||
-rw-r--r-- | src/engine/PatchImpl.hpp | 5 | ||||
-rw-r--r-- | src/engine/events/Connect.cpp | 8 | ||||
-rw-r--r-- | src/engine/events/Connect.hpp | 1 | ||||
-rw-r--r-- | src/engine/events/Disconnect.cpp | 57 | ||||
-rw-r--r-- | src/engine/events/Disconnect.hpp | 2 | ||||
-rw-r--r-- | src/engine/events/DisconnectAll.cpp | 4 | ||||
-rw-r--r-- | src/gui/PatchCanvas.cpp | 4 | ||||
-rw-r--r-- | src/serialisation/Serialiser.cpp | 2 | ||||
-rw-r--r-- | src/shared/Builder.cpp | 2 |
17 files changed, 112 insertions, 91 deletions
diff --git a/src/client/ClientStore.cpp b/src/client/ClientStore.cpp index 8a6e008b..2b7bb7f7 100644 --- a/src/client/ClientStore.cpp +++ b/src/client/ClientStore.cpp @@ -478,7 +478,7 @@ ClientStore::disconnect(const Path& src_port_path, const Path& dst_port_path) SharedPtr<PatchModel> patch = connection_patch(src_port_path, dst_port_path); if (patch) - patch->remove_connection(src_port_path, dst_port_path); + patch->remove_connection(src_port.get(), dst_port.get()); else LOG(error) << "Disconnection in non-existent patch: " << src_port_path << " -> " << dst_port_path << endl; diff --git a/src/client/PatchModel.cpp b/src/client/PatchModel.cpp index bf4168d6..94557bd0 100644 --- a/src/client/PatchModel.cpp +++ b/src/client/PatchModel.cpp @@ -59,7 +59,7 @@ PatchModel::remove_child(SharedPtr<ObjectModel> o) Connections::iterator next = j; ++next; - SharedPtr<ConnectionModel> cm = PtrCast<ConnectionModel>(*j); + SharedPtr<ConnectionModel> cm = PtrCast<ConnectionModel>(j->second); assert(cm); if (cm->src_port_path().parent() == o->path() @@ -68,7 +68,6 @@ PatchModel::remove_child(SharedPtr<ObjectModel> o) || cm->dst_port_path() == o->path()) { signal_removed_connection.emit(cm); _connections->erase(j); // cuts our reference - assert(!get_connection(cm->src_port_path(), cm->dst_port_path())); // no duplicates } j = next; } @@ -98,13 +97,13 @@ PatchModel::clear() SharedPtr<ConnectionModel> -PatchModel::get_connection(const Path& src_port_path, const Path& dst_port_path) const +PatchModel::get_connection(const Shared::Port* src_port, const Shared::Port* dst_port) { - for (Connections::const_iterator i = _connections->begin(); i != _connections->end(); ++i) - if ((*i)->src_port_path() == src_port_path && (*i)->dst_port_path() == dst_port_path) - return PtrCast<ConnectionModel>(*i); - - return SharedPtr<ConnectionModel>(); + Connections::iterator i = _connections->find(make_pair(src_port, dst_port)); + if (i != _connections->end()) + return PtrCast<ConnectionModel>(i->second); + else + return SharedPtr<ConnectionModel>(); } @@ -130,34 +129,31 @@ PatchModel::add_connection(SharedPtr<ConnectionModel> cm) assert(cm->dst_port()->parent().get() == this || cm->dst_port()->parent()->parent().get() == this); - SharedPtr<ConnectionModel> existing = get_connection(cm->src_port_path(), cm->dst_port_path()); + SharedPtr<ConnectionModel> existing = get_connection( + cm->src_port().get(), cm->dst_port().get()); if (existing) { assert(cm->src_port() == existing->src_port()); assert(cm->dst_port() == existing->dst_port()); } else { - _connections->push_back(new Connections::Node(cm)); + _connections->insert(make_pair(make_pair(cm->src_port().get(), cm->dst_port().get()), cm)); signal_new_connection.emit(cm); } } void -PatchModel::remove_connection(const Path& src_port_path, const Path& dst_port_path) +PatchModel::remove_connection(const Shared::Port* src_port, const Shared::Port* dst_port) { - for (Connections::iterator i = _connections->begin(); i != _connections->end(); ++i) { - SharedPtr<ConnectionModel> cm = PtrCast<ConnectionModel>(*i); - assert(cm); - if (cm->src_port_path() == src_port_path && cm->dst_port_path() == dst_port_path) { - signal_removed_connection.emit(cm); - delete _connections->erase(i); // cuts our reference - assert(!get_connection(src_port_path, dst_port_path)); // no duplicates - return; - } + Connections::iterator i = _connections->find(make_pair(src_port, dst_port)); + if (i != _connections->end()) { + SharedPtr<ConnectionModel> c = PtrCast<ConnectionModel>(i->second); + signal_removed_connection.emit(c); + _connections->erase(i); + } else { + warn << "[PatchModel::remove_connection] Failed to find connection " << + src_port->path() << " -> " << dst_port->path() << endl; } - - warn << "[PatchModel::remove_connection] Failed to find connection " << - src_port_path << " -> " << dst_port_path << endl; } diff --git a/src/client/PatchModel.hpp b/src/client/PatchModel.hpp index 1590aa10..e3baa3eb 100644 --- a/src/client/PatchModel.hpp +++ b/src/client/PatchModel.hpp @@ -27,6 +27,9 @@ #include "ConnectionModel.hpp" namespace Ingen { + +namespace Shared { class Port; } + namespace Client { class ClientStore; @@ -43,8 +46,8 @@ public: const Connections& connections() const { return *_connections.get(); } - SharedPtr<ConnectionModel> get_connection(const Raul::Path& src_port_path, - const Raul::Path& dst_port_path) const; + SharedPtr<ConnectionModel> get_connection(const Shared::Port* src_port, + const Shared::Port* dst_port); //uint32_t poly() const { return _poly; } bool enabled() const; @@ -85,7 +88,7 @@ private: bool remove_child(SharedPtr<ObjectModel> c); void add_connection(SharedPtr<ConnectionModel> cm); - void remove_connection(const Raul::Path& src_port_path, const Raul::Path& dst_port_path); + void remove_connection(const Shared::Port* src_port, const Shared::Port* dst_port); SharedPtr<Connections> _connections; bool _editable; diff --git a/src/common/interface/Patch.hpp b/src/common/interface/Patch.hpp index 0817d7c2..f46c1a6d 100644 --- a/src/common/interface/Patch.hpp +++ b/src/common/interface/Patch.hpp @@ -18,6 +18,7 @@ #ifndef INGEN_INTERFACE_PATCH_HPP #define INGEN_INTERFACE_PATCH_HPP +#include <map> #include "raul/SharedPtr.hpp" #include "raul/List.hpp" #include "interface/Node.hpp" @@ -35,7 +36,8 @@ class Connection; class Patch : virtual public Node { public: - typedef Raul::List< SharedPtr<Connection> > Connections; + typedef std::pair<const Port*, const Port*> ConnectionsKey; + typedef std::map< ConnectionsKey, SharedPtr<Connection> > Connections; virtual const Connections& connections() const = 0; diff --git a/src/engine/InputPort.cpp b/src/engine/InputPort.cpp index fa45117d..f9ddbfe2 100644 --- a/src/engine/InputPort.cpp +++ b/src/engine/InputPort.cpp @@ -81,7 +81,7 @@ InputPort::set_buffer_size(Context& context, BufferFactory& bufs, size_t size) PortImpl::set_buffer_size(context, bufs, size); for (Connections::iterator c = _connections.begin(); c != _connections.end(); ++c) - ((ConnectionImpl*)c->get())->update_buffer_size(context, bufs); + (*c)->update_buffer_size(context, bufs); } @@ -156,8 +156,10 @@ InputPort::remove_connection(ProcessContext& context, const OutputPort* src_port Connections::iterator next = i; ++next; - if ((*i)->src_port() == src_port) + if ((*i)->src_port() == src_port) { connection = _connections.erase(i); + break; + } i = next; } diff --git a/src/engine/MessageContext.cpp b/src/engine/MessageContext.cpp index eec5acaa..ec0fedbf 100644 --- a/src/engine/MessageContext.cpp +++ b/src/engine/MessageContext.cpp @@ -118,7 +118,7 @@ MessageContext::execute(const Request& req) lv2_contexts_port_is_valid(valid_ports, i)) { PatchImpl::Connections& wires = patch->connections(); for (PatchImpl::Connections::iterator c = wires.begin(); c != wires.end(); ++c) { - ConnectionImpl* ci = dynamic_cast<ConnectionImpl*>(c->get()); + ConnectionImpl* ci = (ConnectionImpl*)c->second.get(); if (ci->src_port() == p && ci->dst_port()->context() == Context::MESSAGE) { _queue.insert(Request(req.time, ci->dst_port())); } diff --git a/src/engine/ObjectSender.cpp b/src/engine/ObjectSender.cpp index 7cfa5f85..adb35f13 100644 --- a/src/engine/ObjectSender.cpp +++ b/src/engine/ObjectSender.cpp @@ -83,7 +83,7 @@ ObjectSender::send_patch(ClientInterface* client, const PatchImpl* patch, bool r // Send connections for (PatchImpl::Connections::const_iterator j = patch->connections().begin(); j != patch->connections().end(); ++j) - client->connect((*j)->src_port_path(), (*j)->dst_port_path()); + client->connect(j->second->src_port_path(), j->second->dst_port_path()); } if (bundle) diff --git a/src/engine/PatchImpl.cpp b/src/engine/PatchImpl.cpp index 7ee82803..309ac3f8 100644 --- a/src/engine/PatchImpl.cpp +++ b/src/engine/PatchImpl.cpp @@ -112,7 +112,7 @@ PatchImpl::prepare_internal_poly(BufferFactory& bufs, uint32_t poly) (*i)->prepare_poly(bufs, poly); for (Connections::iterator i = _connections.begin(); i != _connections.end(); ++i) - ((ConnectionImpl*)i->get())->prepare_poly(bufs, poly); + ((ConnectionImpl*)i->second.get())->prepare_poly(bufs, poly); return true; } @@ -129,7 +129,7 @@ PatchImpl::apply_internal_poly(ProcessContext& context, BufferFactory& bufs, Rau (*i)->apply_poly(maid, poly); for (Connections::iterator i = _connections.begin(); i != _connections.end(); ++i) - ((ConnectionImpl*)i->get())->apply_poly(maid, poly); + ((ConnectionImpl*)i->second.get())->apply_poly(maid, poly); for (List<NodeImpl*>::iterator i = _nodes.begin(); i != _nodes.end(); ++i) { for (uint32_t j = 0; j < (*i)->num_ports(); ++j) { @@ -301,42 +301,39 @@ PatchImpl::remove_node(const Raul::Symbol& symbol) } +void +PatchImpl::add_connection(SharedPtr<ConnectionImpl> c) +{ + ThreadManager::assert_thread(THREAD_PRE_PROCESS); + _connections.insert(make_pair(make_pair(c->src_port(), c->dst_port()), c)); +} + + /** Remove a connection. * Preprocessing thread only. */ -PatchImpl::Connections::Node* +SharedPtr<ConnectionImpl> PatchImpl::remove_connection(const PortImpl* src_port, const PortImpl* dst_port) { ThreadManager::assert_thread(THREAD_PRE_PROCESS); - bool found = false; - Connections::Node* connection = NULL; - for (Connections::iterator i = _connections.begin(); i != _connections.end(); ++i) { - ConnectionImpl* const c = (ConnectionImpl*)i->get(); - if (c->src_port() == src_port && c->dst_port() == dst_port) { - connection = _connections.erase(i); - found = true; - break; - } - } - - if ( ! found) + Connections::iterator i = _connections.find(make_pair(src_port, dst_port)); + if (i != _connections.end()) { + SharedPtr<ConnectionImpl> c = PtrCast<ConnectionImpl>(i->second); + _connections.erase(i); + return c; + } else { error << "[PatchImpl::remove_connection] Connection not found" << endl; - - return connection; + return SharedPtr<ConnectionImpl>(); + } } bool PatchImpl::has_connection(const PortImpl* src_port, const PortImpl* dst_port) const { - // FIXME: Doesn't scale - for (Connections::const_iterator i = _connections.begin(); i != _connections.end(); ++i) { - ConnectionImpl* const c = (ConnectionImpl*)i->get(); - if (c->src_port() == src_port && c->dst_port() == dst_port) - return true; - } - - return false; + ThreadManager::assert_thread(THREAD_PRE_PROCESS); + Connections::const_iterator i = _connections.find(make_pair(src_port, dst_port)); + return (i != _connections.end()); } @@ -479,10 +476,10 @@ PatchImpl::compile() const // Add any queued connections that must be run after a cycle for (Connections::const_iterator i = _connections.begin(); i != _connections.end(); ++i) { - ConnectionImpl* const c = (ConnectionImpl*)i->get(); + SharedPtr<ConnectionImpl> c = PtrCast<ConnectionImpl>(i->second); if (c->src_port()->context() == Context::AUDIO && c->dst_port()->context() == Context::MESSAGE) { - compiled_patch->queued_connections.push_back(c); + compiled_patch->queued_connections.push_back(c.get()); } } diff --git a/src/engine/PatchImpl.hpp b/src/engine/PatchImpl.hpp index ff2f0631..9bc2614d 100644 --- a/src/engine/PatchImpl.hpp +++ b/src/engine/PatchImpl.hpp @@ -102,8 +102,9 @@ public: Raul::List<PortImpl*>::Node* remove_port(const std::string& name); void clear_ports(); - void add_connection(Connections::Node* c) { _connections.push_back(c); } - Connections::Node* remove_connection(const PortImpl* src_port, const PortImpl* dst_port); + void add_connection(SharedPtr<ConnectionImpl> c); + + SharedPtr<ConnectionImpl> remove_connection(const PortImpl* src_port, const PortImpl* dst_port); bool has_connection(const PortImpl* src_port, const PortImpl* dst_port) const; diff --git a/src/engine/events/Connect.cpp b/src/engine/events/Connect.cpp index fac11965..b4389438 100644 --- a/src/engine/events/Connect.cpp +++ b/src/engine/events/Connect.cpp @@ -52,7 +52,6 @@ Connect::Connect(Engine& engine, SharedPtr<Request> request, SampleCount timesta , _src_output_port(NULL) , _dst_input_port(NULL) , _compiled_patch(NULL) - , _patch_listnode(NULL) , _port_listnode(NULL) , _buffers(NULL) { @@ -149,8 +148,9 @@ Connect::pre_process() return; } - _connection = SharedPtr<ConnectionImpl>(new ConnectionImpl(*_engine.buffer_factory(), _src_port, _dst_port)); - _patch_listnode = new PatchImpl::Connections::Node(_connection); + _connection = SharedPtr<ConnectionImpl>( + new ConnectionImpl(*_engine.buffer_factory(), _src_port, _dst_port)); + _port_listnode = new InputPort::Connections::Node(_connection); // Need to be careful about patch port connections here and adding a node's @@ -160,7 +160,7 @@ Connect::pre_process() src_node->dependants()->push_back(new Raul::List<NodeImpl*>::Node(dst_node)); } - _patch->add_connection(_patch_listnode); + _patch->add_connection(_connection); _dst_input_port->increment_num_connections(); switch (_dst_input_port->num_connections()) { diff --git a/src/engine/events/Connect.hpp b/src/engine/events/Connect.hpp index 90fba0d9..322a5dbf 100644 --- a/src/engine/events/Connect.hpp +++ b/src/engine/events/Connect.hpp @@ -78,7 +78,6 @@ private: CompiledPatch* _compiled_patch; ///< New process order for Patch SharedPtr<ConnectionImpl> _connection; - PatchImpl::Connections::Node* _patch_listnode; InputPort::Connections::Node* _port_listnode; Raul::Array<BufferFactory::Ref>* _buffers; diff --git a/src/engine/events/Disconnect.cpp b/src/engine/events/Disconnect.cpp index 653933b7..250dc234 100644 --- a/src/engine/events/Disconnect.cpp +++ b/src/engine/events/Disconnect.cpp @@ -51,7 +51,6 @@ Disconnect::Disconnect( , _patch(NULL) , _src_port(NULL) , _dst_port(NULL) - , _patch_connection(NULL) , _compiled_patch(NULL) , _buffers(NULL) , _internal(false) @@ -62,12 +61,12 @@ Disconnect::Disconnect( Disconnect::Disconnect( - Engine& engine, - SharedPtr<Request> request, - SampleCount timestamp, - PortImpl* const src_port, - PortImpl* const dst_port, - bool reconnect_dst_port) + Engine& engine, + SharedPtr<Request> request, + SampleCount timestamp, + PortImpl* const src_port, + PortImpl* const dst_port, + bool reconnect_dst_port) : QueuedEvent(engine, request, timestamp) , _src_port_path(src_port->path()) , _dst_port_path(dst_port->path()) @@ -157,7 +156,7 @@ Disconnect::pre_process() break; } - _patch_connection = _patch->remove_connection(_src_port, _dst_port); + _connection = _patch->remove_connection(_src_port, _dst_port); _dst_input_port->decrement_num_connections(); if (_dst_input_port->num_connections() == 0) { @@ -180,9 +179,9 @@ Disconnect::execute(ProcessContext& context) QueuedEvent::execute(context); if (_error == NO_ERROR) { - InputPort::Connections::Node* const port_connection + InputPort::Connections::Node* const port_connections_node = _dst_input_port->remove_connection(context, _src_output_port); - port_connection->elem()->recycle_buffer(); + port_connections_node->elem()->recycle_buffer(); if (_reconnect_dst_port) { if (_buffers) _engine.maid()->push(_dst_input_port->set_buffers(_buffers)); @@ -204,13 +203,11 @@ Disconnect::execute(ProcessContext& context) _dst_input_port->recycle_buffers(); } - if (port_connection != NULL) { - assert(_patch_connection); - assert(port_connection->elem() == _patch_connection->elem()); + if (port_connections_node) { + assert(_connection); + assert(port_connections_node->elem() == _connection); - // Destroy list node, which will drop reference to connection itself - _engine.maid()->push(port_connection); - _engine.maid()->push(_patch_connection); + _engine.maid()->push(port_connections_node); if (!_internal) { _engine.maid()->push(_patch->compiled_patch()); @@ -231,8 +228,32 @@ Disconnect::post_process() _request->respond_ok(); _engine.broadcaster()->disconnect(_src_port->path(), _dst_port->path()); } else { - string msg = "Unable to disconnect "; - msg.append(_src_port_path.str() + " -> " + _dst_port_path.str()); + string msg("Unable to disconnect "); + msg.append(_src_port_path.str() + " => " + _dst_port_path.str()); + msg.append(" ("); + switch (_error) { + case PARENT_PATCH_DIFFERENT: + msg.append("Ports exist in different patches"); + break; + case PORT_NOT_FOUND: + msg.append("Port not found"); + break; + case TYPE_MISMATCH: + msg.append("Ports have incompatible types"); + break; + case NOT_CONNECTED: + msg.append("Ports are not connected"); + break; + case PARENTS_NOT_FOUND: + msg.append("Parent node not found"); + break; + case CONNECTION_NOT_FOUND: + msg.append("Connection not found"); + break; + default: + break; + } + msg.append(")"); if (_request) _request->respond_error(msg); } diff --git a/src/engine/events/Disconnect.hpp b/src/engine/events/Disconnect.hpp index 3a8758ec..d0376001 100644 --- a/src/engine/events/Disconnect.hpp +++ b/src/engine/events/Disconnect.hpp @@ -86,7 +86,7 @@ private: OutputPort* _src_output_port; InputPort* _dst_input_port; - PatchImpl::Connections::Node* _patch_connection; + SharedPtr<ConnectionImpl> _connection; CompiledPatch* _compiled_patch; ///< New process order for Patch Raul::Array<BufferFactory::Ref>* _buffers; diff --git a/src/engine/events/DisconnectAll.cpp b/src/engine/events/DisconnectAll.cpp index 38ed7102..7b10b3f4 100644 --- a/src/engine/events/DisconnectAll.cpp +++ b/src/engine/events/DisconnectAll.cpp @@ -112,7 +112,7 @@ DisconnectAll::pre_process() if (_node) { for (PatchImpl::Connections::const_iterator i = _parent->connections().begin(); i != _parent->connections().end(); ++i) { - ConnectionImpl* c = (ConnectionImpl*)i->get(); + ConnectionImpl* c = (ConnectionImpl*)i->second.get(); const bool reconnect_input = !_deleting || (c->dst_port()->parent_node() != _node); if ((c->src_port()->parent_node() == _node || c->dst_port()->parent_node() == _node) && !c->pending_disconnection()) { @@ -126,7 +126,7 @@ DisconnectAll::pre_process() } else { // _port for (PatchImpl::Connections::const_iterator i = _parent->connections().begin(); i != _parent->connections().end(); ++i) { - ConnectionImpl* c = (ConnectionImpl*)i->get(); + ConnectionImpl* c = (ConnectionImpl*)i->second.get(); const bool reconnect_input = !_deleting || (c->dst_port()->parent_node() != _node); if ((c->src_port() == _port || c->dst_port() == _port) && !c->pending_disconnection()) { Disconnect* ev = new Disconnect(_engine, diff --git a/src/gui/PatchCanvas.cpp b/src/gui/PatchCanvas.cpp index 0762718b..83e921b3 100644 --- a/src/gui/PatchCanvas.cpp +++ b/src/gui/PatchCanvas.cpp @@ -272,7 +272,7 @@ PatchCanvas::build() // Create connections for (PatchModel::Connections::const_iterator i = _patch->connections().begin(); i != _patch->connections().end(); ++i) { - connection(PtrCast<ConnectionModel>(*i)); + connection(PtrCast<ConnectionModel>(i->second)); } } @@ -708,7 +708,7 @@ PatchCanvas::paste() assert(root); for (Patch::Connections::const_iterator i = root->connections().begin(); i != root->connections().end(); ++i) { - App::instance().engine()->connect((*i)->src_port_path(), (*i)->dst_port_path()); + App::instance().engine()->connect(i->second->src_port_path(), i->second->dst_port_path()); } } diff --git a/src/serialisation/Serialiser.cpp b/src/serialisation/Serialiser.cpp index 35d304f8..1469afaf 100644 --- a/src/serialisation/Serialiser.cpp +++ b/src/serialisation/Serialiser.cpp @@ -367,7 +367,7 @@ Serialiser::serialise_patch(SharedPtr<Shared::Patch> patch, const Redland::Node& for (Shared::Patch::Connections::const_iterator c = patch->connections().begin(); c != patch->connections().end(); ++c) { - serialise_connection(patch, *c); + serialise_connection(patch, c->second); } } diff --git a/src/shared/Builder.cpp b/src/shared/Builder.cpp index 820a26b3..0cc4e980 100644 --- a/src/shared/Builder.cpp +++ b/src/shared/Builder.cpp @@ -85,7 +85,7 @@ Builder::connect(SharedPtr<const GraphObject> object) if (patch) { for (Patch::Connections::const_iterator i = patch->connections().begin(); i != patch->connections().end(); ++i) { - _interface.connect((*i)->src_port_path(), (*i)->dst_port_path()); + _interface.connect(i->second->src_port_path(), i->second->dst_port_path()); } return; } |