summaryrefslogtreecommitdiffstats
path: root/src/engine/events/Disconnect.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/engine/events/Disconnect.cpp')
-rw-r--r--src/engine/events/Disconnect.cpp183
1 files changed, 97 insertions, 86 deletions
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);
}
}