summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDavid Robillard <d@drobilla.net>2011-04-20 03:30:03 +0000
committerDavid Robillard <d@drobilla.net>2011-04-20 03:30:03 +0000
commit1119a2c71a5f6b4e23ac0a19784705002ca9cefd (patch)
tree14f1a7f2b270185defc9e99ddf03e108b6767c8b
parent7042795c8138f03124539f0efc892fe45eb2979f (diff)
downloadingen-1119a2c71a5f6b4e23ac0a19784705002ca9cefd.tar.gz
ingen-1119a2c71a5f6b4e23ac0a19784705002ca9cefd.tar.bz2
ingen-1119a2c71a5f6b4e23ac0a19784705002ca9cefd.zip
Move disconnect_all to CommonInterface and implement in clients.
Factor out process thread implementation of Disconnect into Disconnect::Impl. Implement DisconnectAll in terms of DisconnectImpl rather than abusing Disconnect. Dramatically reduce notification communication overhead of DisconnectAll. git-svn-id: http://svn.drobilla.net/lad/trunk/ingen@3179 a436a847-0d15-0410-975c-d299462d15a1
-rw-r--r--include/ingen/CommonInterface.hpp3
-rw-r--r--include/ingen/EngineInterface.hpp5
-rw-r--r--src/client/ClientStore.cpp24
-rw-r--r--src/client/ClientStore.hpp3
-rw-r--r--src/client/SigClientInterface.hpp4
-rw-r--r--src/client/ThreadedSigClientInterface.hpp5
-rw-r--r--src/engine/ClientBroadcaster.hpp5
-rw-r--r--src/engine/HTTPClientSender.cpp7
-rw-r--r--src/engine/HTTPClientSender.hpp3
-rw-r--r--src/engine/OSCClientSender.cpp15
-rw-r--r--src/engine/OSCClientSender.hpp3
-rw-r--r--src/engine/events/Disconnect.cpp183
-rw-r--r--src/engine/events/Disconnect.hpp43
-rw-r--r--src/engine/events/DisconnectAll.cpp28
-rw-r--r--src/engine/events/DisconnectAll.hpp17
-rw-r--r--src/shared/ClashAvoider.cpp8
-rw-r--r--src/shared/ClashAvoider.hpp3
17 files changed, 228 insertions, 131 deletions
diff --git a/include/ingen/CommonInterface.hpp b/include/ingen/CommonInterface.hpp
index c42a3eea..f67f1d13 100644
--- a/include/ingen/CommonInterface.hpp
+++ b/include/ingen/CommonInterface.hpp
@@ -60,6 +60,9 @@ public:
virtual void disconnect(const Raul::Path& src_port_path,
const Raul::Path& dst_port_path) = 0;
+ virtual void disconnect_all(const Raul::Path& parent_patch_path,
+ const Raul::Path& path) = 0;
+
virtual void set_property(const Raul::URI& subject,
const Raul::URI& predicate,
const Raul::Atom& value) = 0;
diff --git a/include/ingen/EngineInterface.hpp b/include/ingen/EngineInterface.hpp
index 357ca46b..301a675b 100644
--- a/include/ingen/EngineInterface.hpp
+++ b/include/ingen/EngineInterface.hpp
@@ -46,11 +46,6 @@ public:
virtual void register_client(ClientInterface* client) = 0;
virtual void unregister_client(const Raul::URI& uri) = 0;
- // Object commands
-
- virtual void disconnect_all(const Raul::Path& parent_patch_path,
- const Raul::Path& path) = 0;
-
// Requests
virtual void ping() = 0;
diff --git a/src/client/ClientStore.cpp b/src/client/ClientStore.cpp
index 690a2666..be7d4186 100644
--- a/src/client/ClientStore.cpp
+++ b/src/client/ClientStore.cpp
@@ -63,6 +63,7 @@ ClientStore::ClientStore(SharedPtr<Shared::LV2URIMap> uris,
CONNECT(delta, delta);
CONNECT(connection, connect);
CONNECT(disconnection, disconnect);
+ CONNECT(disconnect_all, disconnect_all);
CONNECT(property_change, set_property);
CONNECT(activity, activity);
}
@@ -475,6 +476,29 @@ ClientStore::disconnect(const Path& src_path,
patch->remove_connection(src_port.get(), dst_port.get());
}
+void
+ClientStore::disconnect_all(const Raul::Path& parent_patch_path,
+ const Raul::Path& path)
+{
+ SharedPtr<PatchModel> patch = PtrCast<PatchModel>(object(parent_patch_path));
+ SharedPtr<ObjectModel> object = this->object(path);
+
+ if (!patch || !object)
+ return;
+
+ const PatchModel::Connections connections = patch->connections();
+ for (PatchModel::Connections::const_iterator i = connections.begin();
+ i != connections.end(); ++i) {
+ SharedPtr<ConnectionModel> c = PtrCast<ConnectionModel>(i->second);
+ if (c->src_port()->parent() == object
+ || c->dst_port()->parent() == object) {
+ c->src_port()->disconnected_from(c->dst_port());
+ c->dst_port()->disconnected_from(c->src_port());
+ patch->remove_connection(c->src_port().get(), c->dst_port().get());
+ }
+ }
+}
+
} // namespace Client
} // namespace Ingen
diff --git a/src/client/ClientStore.hpp b/src/client/ClientStore.hpp
index dc02a455..c5dc023a 100644
--- a/src/client/ClientStore.hpp
+++ b/src/client/ClientStore.hpp
@@ -97,6 +97,9 @@ public:
void disconnect(const Raul::Path& src_port_path,
const Raul::Path& dst_port_path);
+ void disconnect_all(const Raul::Path& parent_patch_path,
+ const Raul::Path& path);
+
void del(const Raul::URI& uri);
sigc::signal< void, SharedPtr<ObjectModel> > signal_new_object;
diff --git a/src/client/SigClientInterface.hpp b/src/client/SigClientInterface.hpp
index 17cd8556..7d968524 100644
--- a/src/client/SigClientInterface.hpp
+++ b/src/client/SigClientInterface.hpp
@@ -58,6 +58,7 @@ public:
sigc::signal<void, Raul::URI> signal_object_deleted;
sigc::signal<void, Raul::Path, Raul::Path> signal_connection;
sigc::signal<void, Raul::Path, Raul::Path> signal_disconnection;
+ sigc::signal<void, Raul::Path, Raul::Path> signal_disconnect_all;
sigc::signal<void, Raul::URI, Raul::URI, Raul::Atom> signal_variable_change;
sigc::signal<void, Raul::URI, Raul::URI, Raul::Atom> signal_property_change;
sigc::signal<void, Raul::Path, Raul::Atom> signal_port_value;
@@ -109,6 +110,9 @@ protected:
void disconnect(const Raul::Path& src_port_path, const Raul::Path& dst_port_path)
{ EMIT(disconnection, src_port_path, dst_port_path); }
+ void disconnect_all(const Raul::Path& parent_patch_path, const Raul::Path& path)
+ { EMIT(disconnect_all, parent_patch_path, path); }
+
void set_property(const Raul::URI& subject, const Raul::URI& key, const Raul::Atom& value)
{ EMIT(property_change, subject, key, value); }
diff --git a/src/client/ThreadedSigClientInterface.hpp b/src/client/ThreadedSigClientInterface.hpp
index 00bd2767..d9f89503 100644
--- a/src/client/ThreadedSigClientInterface.hpp
+++ b/src/client/ThreadedSigClientInterface.hpp
@@ -57,6 +57,7 @@ public:
, object_deleted_slot(signal_object_deleted.make_slot())
, object_moved_slot(signal_object_moved.make_slot())
, disconnection_slot(signal_disconnection.make_slot())
+ , disconnect_all_slot(signal_disconnect_all.make_slot())
, variable_change_slot(signal_variable_change.make_slot())
, property_change_slot(signal_property_change.make_slot())
, port_value_slot(signal_port_value.make_slot())
@@ -103,6 +104,9 @@ public:
void disconnect(const Raul::Path& src_port_path, const Raul::Path& dst_port_path)
{ push_sig(sigc::bind(disconnection_slot, src_port_path, dst_port_path)); }
+ void disconnect_all(const Raul::Path& parent_patch_path, const Raul::Path& path)
+ { push_sig(sigc::bind(disconnect_all_slot, parent_patch_path, path)); }
+
void set_property(const Raul::URI& subject, const Raul::URI& key, const Raul::Atom& value)
{ push_sig(sigc::bind(property_change_slot, subject, key, value)); }
@@ -135,6 +139,7 @@ private:
sigc::slot<void, Raul::URI> object_deleted_slot;
sigc::slot<void, Raul::Path, Raul::Path> object_moved_slot;
sigc::slot<void, Raul::Path, Raul::Path> disconnection_slot;
+ sigc::slot<void, Raul::Path, Raul::Path> disconnect_all_slot;
sigc::slot<void, Raul::URI, Raul::URI, Raul::Atom> variable_change_slot;
sigc::slot<void, Raul::URI, Raul::URI, Raul::Atom> property_change_slot;
sigc::slot<void, Raul::Path, Raul::Atom> port_value_slot;
diff --git a/src/engine/ClientBroadcaster.hpp b/src/engine/ClientBroadcaster.hpp
index ec0e7492..6c371a50 100644
--- a/src/engine/ClientBroadcaster.hpp
+++ b/src/engine/ClientBroadcaster.hpp
@@ -98,6 +98,11 @@ public:
BROADCAST(disconnect, src_port_path, dst_port_path);
}
+ void disconnect_all(const Raul::Path& parent_patch_path,
+ const Raul::Path& path) {
+ BROADCAST(disconnect_all, parent_patch_path, path);
+ }
+
void set_property(const Raul::URI& subject,
const Raul::URI& predicate,
const Raul::Atom& value) {
diff --git a/src/engine/HTTPClientSender.cpp b/src/engine/HTTPClientSender.cpp
index 83d09b97..8a03e2bd 100644
--- a/src/engine/HTTPClientSender.cpp
+++ b/src/engine/HTTPClientSender.cpp
@@ -98,7 +98,12 @@ HTTPClientSender::connect(const Path& src_path, const Path& dst_path)
void
HTTPClientSender::disconnect(const Path& src_path, const Path& dst_path)
{
- //send("/ingen/disconnection", "ss", src_path.c_str(), dst_path.c_str(), LO_ARGS_END);
+}
+
+void
+HTTPClientSender::disconnect_all(const Raul::Path& parent_patch_path,
+ const Raul::Path& path)
+{
}
void
diff --git a/src/engine/HTTPClientSender.hpp b/src/engine/HTTPClientSender.hpp
index 1b741071..501343a9 100644
--- a/src/engine/HTTPClientSender.hpp
+++ b/src/engine/HTTPClientSender.hpp
@@ -85,6 +85,9 @@ public:
virtual void disconnect(const Raul::Path& src_port_path,
const Raul::Path& dst_port_path);
+ virtual void disconnect_all(const Raul::Path& parent_patch_path,
+ const Raul::Path& path);
+
virtual void set_property(const Raul::URI& subject_path,
const Raul::URI& predicate,
const Raul::Atom& value);
diff --git a/src/engine/OSCClientSender.cpp b/src/engine/OSCClientSender.cpp
index 0d3c5cf6..88b979bf 100644
--- a/src/engine/OSCClientSender.cpp
+++ b/src/engine/OSCClientSender.cpp
@@ -192,6 +192,21 @@ OSCClientSender::disconnect(const Path& src_port_path,
}
/** @page client_osc_namespace
+ * <h2>/disconnect_all</h2>
+ * @arg @p parent-patch-path :: String
+ * @arg @p path :: String
+ *
+ * @par
+ * Notification all connections to an object have been disconnected.
+ */
+void
+OSCClientSender::disconnect_all(const Raul::Path& parent_patch_path,
+ const Raul::Path& path)
+{
+ send("/disconnect_all", "ss", parent_patch_path.c_str(), path.c_str(), LO_ARGS_END);
+}
+
+/** @page client_osc_namespace
* <h2>/set_property</h2>
* @arg @p path :: String
* @arg @p key :: URI String
diff --git a/src/engine/OSCClientSender.hpp b/src/engine/OSCClientSender.hpp
index 7352ebc2..a3031258 100644
--- a/src/engine/OSCClientSender.hpp
+++ b/src/engine/OSCClientSender.hpp
@@ -88,6 +88,9 @@ public:
virtual void disconnect(const Raul::Path& src_port_path,
const Raul::Path& dst_port_path);
+ virtual void disconnect_all(const Raul::Path& parent_patch_path,
+ const Raul::Path& path);
+
virtual void set_property(const Raul::URI& subject,
const Raul::URI& predicate,
const Raul::Atom& value);
diff --git a/src/engine/events/Disconnect.cpp b/src/engine/events/Disconnect.cpp
index 33a65ed8..aa59b618 100644
--- a/src/engine/events/Disconnect.cpp
+++ b/src/engine/events/Disconnect.cpp
@@ -31,6 +31,7 @@
#include "PortImpl.hpp"
#include "ProcessContext.hpp"
#include "Request.hpp"
+#include "ThreadManager.hpp"
using namespace std;
using namespace Raul;
@@ -52,59 +53,82 @@ Disconnect::Disconnect(
, _src_port(NULL)
, _dst_port(NULL)
, _compiled_patch(NULL)
- , _buffers(NULL)
- , _internal(false)
- , _reconnect_dst_port(true)
{
}
-Disconnect::Disconnect(
- 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())
- , _patch(src_port->parent_node()->parent_patch())
- , _src_port(src_port)
- , _dst_port(dst_port)
- , _compiled_patch(NULL)
+Disconnect::Impl::Impl(Engine& e,
+ PatchImpl* patch,
+ OutputPort* s,
+ InputPort* d)
+ : _engine(e)
+ , _src_output_port(s)
+ , _dst_input_port(d)
+ , _patch(patch)
+ , _connection(patch->remove_connection(_src_output_port, _dst_input_port))
, _buffers(NULL)
- , _internal(true)
- , _reconnect_dst_port(reconnect_dst_port)
{
+ ThreadManager::assert_thread(THREAD_PRE_PROCESS);
+
+ NodeImpl* const src_node = _src_output_port->parent_node();
+ NodeImpl* const dst_node = _dst_input_port->parent_node();
+
+ for (Raul::List<NodeImpl*>::iterator i = dst_node->providers()->begin();
+ i != dst_node->providers()->end(); ++i) {
+ if ((*i) == src_node) {
+ delete dst_node->providers()->erase(i);
+ break;
+ }
+ }
+
+ for (Raul::List<NodeImpl*>::iterator i = src_node->dependants()->begin();
+ i != src_node->dependants()->end(); ++i) {
+ if ((*i) == dst_node) {
+ delete src_node->dependants()->erase(i);
+ break;
+ }
+ }
+
+ _dst_input_port->decrement_num_connections();
+
+ if (_dst_input_port->num_connections() == 0) {
+ _buffers = new Raul::Array<BufferFactory::Ref>(_dst_input_port->poly());
+ _dst_input_port->get_buffers(*_engine.buffer_factory(),
+ _buffers, _dst_input_port->poly());
+
+ const bool is_control = _dst_input_port->is_a(PortType::CONTROL);
+ const float value = is_control ? _dst_input_port->value().get_float() : 0;
+ for (uint32_t i = 0; i < _buffers->size(); ++i) {
+ if (is_control) {
+ PtrCast<AudioBuffer>(_buffers->at(i))->set_value(value, 0, 0);
+ } else {
+ _buffers->at(i)->clear();
+ }
+ }
+ }
+
+ _connection->pending_disconnection(true);
}
void
Disconnect::pre_process()
{
- if (!_internal) {
- if (_src_port_path.parent().parent() != _dst_port_path.parent().parent()
- && _src_port_path.parent() != _dst_port_path.parent().parent()
- && _src_port_path.parent().parent() != _dst_port_path.parent()) {
- _error = PARENT_PATCH_DIFFERENT;
- QueuedEvent::pre_process();
- return;
- }
-
- _src_port = _engine.engine_store()->find_port(_src_port_path);
- _dst_port = _engine.engine_store()->find_port(_dst_port_path);
+ if (_src_port_path.parent().parent() != _dst_port_path.parent().parent()
+ && _src_port_path.parent() != _dst_port_path.parent().parent()
+ && _src_port_path.parent().parent() != _dst_port_path.parent()) {
+ _error = PARENT_PATCH_DIFFERENT;
+ QueuedEvent::pre_process();
+ return;
}
+ _src_port = _engine.engine_store()->find_port(_src_port_path);
+ _dst_port = _engine.engine_store()->find_port(_dst_port_path);
+
if (_src_port == NULL || _dst_port == NULL) {
_error = PORT_NOT_FOUND;
QueuedEvent::pre_process();
return;
}
- _dst_input_port = dynamic_cast<InputPort*>(_dst_port);
- _src_output_port = dynamic_cast<OutputPort*>(_src_port);
- assert(_src_output_port);
- assert(_dst_input_port);
-
NodeImpl* const src_node = _src_port->parent_node();
NodeImpl* const dst_node = _dst_port->parent_node();
@@ -128,7 +152,7 @@ Disconnect::pre_process()
assert(_patch);
- if (!_patch->has_connection(_src_output_port, _dst_input_port)) {
+ if (!_patch->has_connection(_src_port, _dst_port)) {
_error = NOT_CONNECTED;
QueuedEvent::pre_process();
return;
@@ -140,41 +164,46 @@ Disconnect::pre_process()
return;
}
- for (Raul::List<NodeImpl*>::iterator i = dst_node->providers()->begin(); i != dst_node->providers()->end(); ++i)
- if ((*i) == src_node) {
- delete dst_node->providers()->erase(i);
- break;
- }
+ _impl = SharedPtr<Impl>(
+ new Impl(_engine,
+ _patch,
+ dynamic_cast<OutputPort*>(_src_port),
+ dynamic_cast<InputPort*>(_dst_port)));
- for (Raul::List<NodeImpl*>::iterator i = src_node->dependants()->begin(); i != src_node->dependants()->end(); ++i)
- if ((*i) == dst_node) {
- delete src_node->dependants()->erase(i);
- break;
- }
+ if (_patch->enabled())
+ _compiled_patch = _patch->compile();
- _connection = _patch->remove_connection(_src_port, _dst_port);
- _dst_input_port->decrement_num_connections();
+ QueuedEvent::pre_process();
+}
- if (_dst_input_port->num_connections() == 0) {
- _buffers = new Raul::Array<BufferFactory::Ref>(_dst_input_port->poly());
- _dst_input_port->get_buffers(*_engine.buffer_factory(),
- _buffers, _dst_input_port->poly());
+bool
+Disconnect::Impl::execute(ProcessContext& context, bool set_dst_buffers)
+{
+ ThreadManager::assert_thread(THREAD_PROCESS);
- const bool is_control = _dst_input_port->is_a(PortType::CONTROL);
- const float value = is_control ? _dst_input_port->value().get_float() : 0;
- for (uint32_t i = 0; i < _buffers->size(); ++i) {
- if (is_control) {
- PtrCast<AudioBuffer>(_buffers->at(i))->set_value(value, 0, 0);
- } else {
- _buffers->at(i)->clear();
- }
+ InputPort::Connections::Node* const port_connections_node
+ = _dst_input_port->remove_connection(context, _src_output_port);
+ if (!port_connections_node) {
+ return false;
+ }
+
+ if (set_dst_buffers) {
+ if (_buffers) {
+ _engine.maid()->push(_dst_input_port->set_buffers(_buffers));
+ } else {
+ _dst_input_port->setup_buffers(*_engine.buffer_factory(),
+ _dst_input_port->poly());
}
+ _dst_input_port->connect_buffers();
+ } else {
+ _dst_input_port->recycle_buffers();
}
- if (!_internal && _patch->enabled())
- _compiled_patch = _patch->compile();
+ assert(_connection);
+ assert(port_connections_node->elem() == _connection);
- QueuedEvent::pre_process();
+ _engine.maid()->push(port_connections_node);
+ return true;
}
void
@@ -183,31 +212,13 @@ Disconnect::execute(ProcessContext& context)
QueuedEvent::execute(context);
if (_error == NO_ERROR) {
- InputPort::Connections::Node* const port_connections_node
- = _dst_input_port->remove_connection(context, _src_output_port);
- if (_reconnect_dst_port) {
- if (_buffers)
- _engine.maid()->push(_dst_input_port->set_buffers(_buffers));
- else
- _dst_input_port->setup_buffers(*_engine.buffer_factory(), _dst_input_port->poly());
- _dst_input_port->connect_buffers();
- } else {
- _dst_input_port->recycle_buffers();
- }
-
- if (port_connections_node) {
- assert(_connection);
- assert(port_connections_node->elem() == _connection);
-
- _engine.maid()->push(port_connections_node);
-
- if (!_internal) {
- _engine.maid()->push(_patch->compiled_patch());
- _patch->compiled_patch(_compiled_patch);
- }
- } else {
+ if (!_impl->execute(context, true)) {
_error = CONNECTION_NOT_FOUND;
+ return;
}
+
+ _engine.maid()->push(_patch->compiled_patch());
+ _patch->compiled_patch(_compiled_patch);
}
}
diff --git a/src/engine/events/Disconnect.hpp b/src/engine/events/Disconnect.hpp
index 9c741293..0c177d0a 100644
--- a/src/engine/events/Disconnect.hpp
+++ b/src/engine/events/Disconnect.hpp
@@ -53,20 +53,31 @@ public:
const Raul::Path& src_port_path,
const Raul::Path& dst_port_path);
- Disconnect(
- Engine& engine,
- SharedPtr<Request> request,
- SampleCount timestamp,
- PortImpl* const src_port,
- PortImpl* const dst_port,
- bool reconnect_dst_port);
-
void pre_process();
void execute(ProcessContext& context);
void post_process();
-private:
+ class Impl {
+ public:
+ Impl(Engine& e,
+ PatchImpl* patch,
+ OutputPort* s,
+ InputPort* d);
+ bool execute(ProcessContext& context, bool set_dst_buffers);
+
+ InputPort* dst_port() { return _dst_input_port; }
+
+ private:
+ Engine& _engine;
+ OutputPort* _src_output_port;
+ InputPort* _dst_input_port;
+ PatchImpl* _patch;
+ SharedPtr<ConnectionImpl> _connection;
+ Raul::Array<BufferFactory::Ref>* _buffers;
+ };
+
+private:
enum ErrorType {
NO_ERROR,
PARENT_PATCH_DIFFERENT,
@@ -80,19 +91,13 @@ private:
Raul::Path _src_port_path;
Raul::Path _dst_port_path;
- PatchImpl* _patch;
- PortImpl* _src_port;
- PortImpl* _dst_port;
- OutputPort* _src_output_port;
- InputPort* _dst_input_port;
+ PatchImpl* _patch;
+ PortImpl* _src_port;
+ PortImpl* _dst_port;
- SharedPtr<ConnectionImpl> _connection;
CompiledPatch* _compiled_patch; ///< New process order for Patch
- Raul::Array<BufferFactory::Ref>* _buffers;
-
- bool _internal;
- bool _reconnect_dst_port;
+ SharedPtr<Impl> _impl;
};
} // namespace Events
diff --git a/src/engine/events/DisconnectAll.cpp b/src/engine/events/DisconnectAll.cpp
index c49cd9d7..a79969d3 100644
--- a/src/engine/events/DisconnectAll.cpp
+++ b/src/engine/events/DisconnectAll.cpp
@@ -69,19 +69,21 @@ DisconnectAll::DisconnectAll(Engine& engine, PatchImpl* parent, GraphObjectImpl*
DisconnectAll::~DisconnectAll()
{
- for (Raul::List<Disconnect*>::iterator i = _disconnect_events.begin(); i != _disconnect_events.end(); ++i)
+ for (Raul::List<Disconnect::Impl*>::iterator i = _disconnect_events.begin();
+ i != _disconnect_events.end(); ++i)
delete (*i);
}
void
DisconnectAll::remove_connection(ConnectionImpl* c)
{
- const bool reconnect_input = !_deleting || (c->dst_port()->parent_node() != _node);
- Disconnect* ev = new Disconnect(_engine, SharedPtr<Request>(), _time,
- c->src_port(), c->dst_port(), reconnect_input);
- ev->pre_process();
- _disconnect_events.push_back(new Raul::List<Disconnect*>::Node(ev));
- c->pending_disconnection(true);
+
+ _disconnect_events.push_back(
+ new Raul::List<Disconnect::Impl*>::Node(
+ new Disconnect::Impl(_engine,
+ _parent,
+ dynamic_cast<OutputPort*>(c->src_port()),
+ dynamic_cast<InputPort*>(c->dst_port()))));
}
void
@@ -151,9 +153,11 @@ DisconnectAll::execute(ProcessContext& context)
QueuedEvent::execute(context);
if (_error == NO_ERROR) {
- for (Raul::List<Disconnect*>::iterator i = _disconnect_events.begin();
- i != _disconnect_events.end(); ++i)
- (*i)->execute(context);
+ for (Raul::List<Disconnect::Impl*>::iterator i = _disconnect_events.begin();
+ i != _disconnect_events.end(); ++i) {
+ (*i)->execute(context,
+ !_deleting || ((*i)->dst_port()->parent_node() != _node));
+ }
}
_engine.maid()->push(_parent->compiled_patch());
@@ -166,9 +170,7 @@ DisconnectAll::post_process()
if (_error == NO_ERROR) {
if (_request)
_request->respond_ok();
- for (Raul::List<Disconnect*>::iterator i = _disconnect_events.begin();
- i != _disconnect_events.end(); ++i)
- (*i)->post_process();
+ _engine.broadcaster()->disconnect_all(_parent_path, _path);
} else {
if (_request) {
boost::format fmt("Unable to disconnect %1% (%2%)");
diff --git a/src/engine/events/DisconnectAll.hpp b/src/engine/events/DisconnectAll.hpp
index ee8fbade..65c9599f 100644
--- a/src/engine/events/DisconnectAll.hpp
+++ b/src/engine/events/DisconnectAll.hpp
@@ -20,6 +20,8 @@
#include "raul/List.hpp"
#include "raul/Path.hpp"
+
+#include "Disconnect.hpp"
#include "QueuedEvent.hpp"
namespace Ingen {
@@ -69,16 +71,17 @@ private:
void remove_connection(ConnectionImpl* c);
- Raul::Path _parent_path;
- Raul::Path _path;
- PatchImpl* _parent;
- NodeImpl* _node;
- PortImpl* _port;
- Raul::List<Disconnect*> _disconnect_events;
+ Raul::Path _parent_path;
+ Raul::Path _path;
+ PatchImpl* _parent;
+ NodeImpl* _node;
+ PortImpl* _port;
+
+ Raul::List<Disconnect::Impl*> _disconnect_events;
CompiledPatch* _compiled_patch; ///< New process order for Patch
- bool _deleting;
+ bool _deleting;
};
} // namespace Engine
diff --git a/src/shared/ClashAvoider.cpp b/src/shared/ClashAvoider.cpp
index 10a26934..0e44ef85 100644
--- a/src/shared/ClashAvoider.cpp
+++ b/src/shared/ClashAvoider.cpp
@@ -178,6 +178,14 @@ ClashAvoider::disconnect(const Raul::Path& src_port_path,
_target.disconnect(map_path(src_port_path), map_path(dst_port_path));
}
+
+void
+ClashAvoider::disconnect_all(const Raul::Path& parent_patch_path,
+ const Raul::Path& path)
+{
+ _target.disconnect_all(map_path(parent_patch_path), map_path(path));
+}
+
void
ClashAvoider::set_property(const Raul::URI& subject,
const Raul::URI& predicate,
diff --git a/src/shared/ClashAvoider.hpp b/src/shared/ClashAvoider.hpp
index 3cd5c8ba..4322957c 100644
--- a/src/shared/ClashAvoider.hpp
+++ b/src/shared/ClashAvoider.hpp
@@ -64,6 +64,9 @@ public:
virtual void disconnect(const Raul::Path& src_port_path,
const Raul::Path& dst_port_path);
+ virtual void disconnect_all(const Raul::Path& parent_patch_path,
+ const Raul::Path& path);
+
virtual void set_property(const Raul::URI& subject_path,
const Raul::URI& predicate,
const Raul::Atom& value);