summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDavid Robillard <d@drobilla.net>2012-08-15 05:24:41 +0000
committerDavid Robillard <d@drobilla.net>2012-08-15 05:24:41 +0000
commit5dd1d9b720993fc7813fe12fca0844f95033ff1b (patch)
tree344151dd656894340d217a8fe33f8dba53fe160f
parent0a9297ed2a1622d252a389d8babc0656fedbe7fd (diff)
downloadingen-5dd1d9b720993fc7813fe12fca0844f95033ff1b.tar.gz
ingen-5dd1d9b720993fc7813fe12fca0844f95033ff1b.tar.bz2
ingen-5dd1d9b720993fc7813fe12fca0844f95033ff1b.zip
Use intrusive lists to store nodes and ports in their parent patch to avoid tedious allocated list node juggling.
git-svn-id: http://svn.drobilla.net/lad/trunk/ingen@4700 a436a847-0d15-0410-975c-d299462d15a1
-rw-r--r--src/server/DuplexPort.cpp7
-rw-r--r--src/server/DuplexPort.hpp17
-rw-r--r--src/server/NodeImpl.cpp11
-rw-r--r--src/server/NodeImpl.hpp9
-rw-r--r--src/server/PatchImpl.cpp124
-rw-r--r--src/server/PatchImpl.hpp43
-rw-r--r--src/server/events/CreateNode.cpp4
-rw-r--r--src/server/events/CreatePatch.cpp2
-rw-r--r--src/server/events/CreatePort.cpp4
-rw-r--r--src/server/events/CreatePort.hpp5
-rw-r--r--src/server/events/Delete.cpp107
-rw-r--r--src/server/events/Delete.hpp19
-rw-r--r--src/server/events/Get.cpp8
13 files changed, 166 insertions, 194 deletions
diff --git a/src/server/DuplexPort.cpp b/src/server/DuplexPort.cpp
index 349eb779..f4bf6915 100644
--- a/src/server/DuplexPort.cpp
+++ b/src/server/DuplexPort.cpp
@@ -48,6 +48,13 @@ DuplexPort::DuplexPort(BufferFactory& bufs,
bufs.forge().make(polyphonic));
}
+DuplexPort::~DuplexPort()
+{
+ if (is_linked()) {
+ parent_patch()->remove_port(*this);
+ }
+}
+
bool
DuplexPort::get_buffers(BufferFactory& bufs,
Raul::Array<BufferRef>* buffers,
diff --git a/src/server/DuplexPort.hpp b/src/server/DuplexPort.hpp
index 042f3681..90146e40 100644
--- a/src/server/DuplexPort.hpp
+++ b/src/server/DuplexPort.hpp
@@ -17,7 +17,7 @@
#ifndef INGEN_ENGINE_DUPLEXPORT_HPP
#define INGEN_ENGINE_DUPLEXPORT_HPP
-#include <string>
+#include <boost/intrusive/slist.hpp>
#include "BufferRef.hpp"
#include "InputPort.hpp"
@@ -28,15 +28,18 @@ namespace Server {
class NodeImpl;
-/** A duplex port (which is both an InputPort and an OutputPort)
+/** A duplex Port (both an InputPort and an OutputPort on a Patch)
*
- * This is used for Patch ports, since they need to appear as both an input
- * and an output port based on context. Eg. a patch output appears as an
- * input inside the patch, so nodes inside the patch can feed it data.
+ * This is used for Patch ports, since they need to appear as both an input and
+ * an output port based on context. There are no actual duplex ports in Ingen,
+ * a Port is either an Input or Output. This class only exists to allow Patch
+ * outputs to appear as inputs to Nodes inside that patch, and vice versa.
*
* \ingroup engine
*/
-class DuplexPort : public InputPort, public OutputPort
+class DuplexPort : public InputPort
+ , public OutputPort
+ , public boost::intrusive::slist_base_hook<> // In PatchImpl
{
public:
DuplexPort(BufferFactory& bufs,
@@ -51,7 +54,7 @@ public:
size_t buffer_size,
bool is_output);
- virtual ~DuplexPort() {}
+ virtual ~DuplexPort();
uint32_t max_tail_poly(Context& context) const;
diff --git a/src/server/NodeImpl.cpp b/src/server/NodeImpl.cpp
index f3277a2d..f1f6c362 100644
--- a/src/server/NodeImpl.cpp
+++ b/src/server/NodeImpl.cpp
@@ -53,8 +53,13 @@ NodeImpl::NodeImpl(PluginImpl* plugin,
NodeImpl::~NodeImpl()
{
- if (_activated)
+ if (_activated) {
deactivate();
+ }
+
+ if (is_linked()) {
+ parent_patch()->remove_node(*this);
+ }
delete _ports;
}
@@ -75,9 +80,8 @@ void
NodeImpl::activate(BufferFactory& bufs)
{
ThreadManager::assert_thread(THREAD_PRE_PROCESS);
- assert(!_activated);
- _activated = true;
+ _activated = true;
for (uint32_t p = 0; p < num_ports(); ++p) {
PortImpl* const port = _ports->at(p);
port->setup_buffers(bufs, port->poly(), false);
@@ -89,7 +93,6 @@ NodeImpl::activate(BufferFactory& bufs)
void
NodeImpl::deactivate()
{
- assert(_activated);
_activated = false;
for (uint32_t i = 0; i < _polyphony; ++i) {
for (uint32_t j = 0; j < num_ports(); ++j) {
diff --git a/src/server/NodeImpl.hpp b/src/server/NodeImpl.hpp
index 4649cdaa..86741156 100644
--- a/src/server/NodeImpl.hpp
+++ b/src/server/NodeImpl.hpp
@@ -18,7 +18,8 @@
#define INGEN_ENGINE_NODEIMPL_HPP
#include <list>
-#include <string>
+
+#include <boost/intrusive/slist.hpp>
#include "raul/Array.hpp"
#include "raul/AtomicInt.hpp"
@@ -30,7 +31,6 @@
#include "types.hpp"
namespace Raul {
-template <typename T> class List;
class Maid;
}
@@ -56,6 +56,7 @@ class ProcessContext;
* \ingroup engine
*/
class NodeImpl : public GraphObjectImpl
+ , public boost::intrusive::slist_base_hook<> // In PatchImpl
{
public:
NodeImpl(PluginImpl* plugin,
@@ -153,8 +154,8 @@ public:
virtual uint32_t polyphony() const { return _polyphony; }
/** Used by the process order finding algorithm (ie during connections) */
- bool traversed() const { return _traversed; }
- void traversed(bool b) { _traversed = b; }
+ bool traversed() const { return _traversed; }
+ void traversed(bool b) { _traversed = b; }
protected:
PluginImpl* _plugin;
diff --git a/src/server/PatchImpl.cpp b/src/server/PatchImpl.cpp
index acf0c46d..da27657a 100644
--- a/src/server/PatchImpl.cpp
+++ b/src/server/PatchImpl.cpp
@@ -68,8 +68,9 @@ PatchImpl::activate(BufferFactory& bufs)
{
NodeImpl::activate(bufs);
- for (Nodes::iterator i = _nodes.begin(); i != _nodes.end(); ++i)
- (*i)->activate(bufs);
+ for (Nodes::iterator i = _nodes.begin(); i != _nodes.end(); ++i) {
+ i->activate(bufs);
+ }
assert(_activated);
}
@@ -81,12 +82,11 @@ PatchImpl::deactivate()
NodeImpl::deactivate();
for (Nodes::iterator i = _nodes.begin(); i != _nodes.end(); ++i) {
- if ((*i)->activated())
- (*i)->deactivate();
- assert(!(*i)->activated());
+ if (i->activated()) {
+ i->deactivate();
+ }
}
}
- assert(!_activated);
}
void
@@ -94,7 +94,7 @@ PatchImpl::disable(ProcessContext& context)
{
_process = false;
for (Ports::iterator i = _outputs.begin(); i != _outputs.end(); ++i) {
- (*i)->clear_buffers();
+ i->clear_buffers();
}
}
@@ -105,8 +105,9 @@ PatchImpl::prepare_internal_poly(BufferFactory& bufs, uint32_t poly)
// TODO: Subpatch dynamic polyphony (i.e. changing port polyphony)
- for (Nodes::iterator i = _nodes.begin(); i != _nodes.end(); ++i)
- (*i)->prepare_poly(bufs, poly);
+ for (Nodes::iterator i = _nodes.begin(); i != _nodes.end(); ++i) {
+ i->prepare_poly(bufs, poly);
+ }
_poly_pre = poly;
return true;
@@ -120,12 +121,13 @@ PatchImpl::apply_internal_poly(ProcessContext& context,
{
// TODO: Subpatch dynamic polyphony (i.e. changing port polyphony)
- for (Nodes::iterator i = _nodes.begin(); i != _nodes.end(); ++i)
- (*i)->apply_poly(context, maid, poly);
+ for (Nodes::iterator i = _nodes.begin(); i != _nodes.end(); ++i) {
+ i->apply_poly(context, maid, poly);
+ }
for (Nodes::iterator i = _nodes.begin(); i != _nodes.end(); ++i) {
- for (uint32_t j = 0; j < (*i)->num_ports(); ++j) {
- PortImpl* const port = (*i)->port_impl(j);
+ for (uint32_t j = 0; j < i->num_ports(); ++j) {
+ PortImpl* const port = i->port_impl(j);
if (port->is_input() && dynamic_cast<InputPort*>(port)->direct_connect())
port->setup_buffers(bufs, port->poly(), true);
port->connect_buffers();
@@ -134,7 +136,7 @@ PatchImpl::apply_internal_poly(ProcessContext& context,
const bool polyphonic = parent_patch() && (poly == parent_patch()->internal_poly_process());
for (Ports::iterator i = _outputs.begin(); i != _outputs.end(); ++i)
- (*i)->setup_buffers(bufs, polyphonic ? poly : 1, true);
+ i->setup_buffers(bufs, polyphonic ? poly : 1, true);
_poly_process = poly;
return true;
@@ -180,28 +182,19 @@ PatchImpl::set_buffer_size(Context& context,
* Preprocessing thread only.
*/
void
-PatchImpl::add_node(Nodes::Node* ln)
+PatchImpl::add_node(NodeImpl& node)
{
ThreadManager::assert_thread(THREAD_PRE_PROCESS);
- assert(ln != NULL);
- assert(ln->elem() != NULL);
- assert(ln->elem()->parent_patch() == this);
-
- _nodes.push_back(ln);
+ _nodes.push_front(node);
}
/** Remove a node.
* Preprocessing thread only.
*/
-PatchImpl::Nodes::Node*
-PatchImpl::remove_node(const Raul::Symbol& symbol)
+void
+PatchImpl::remove_node(NodeImpl& node)
{
- ThreadManager::assert_thread(THREAD_PRE_PROCESS);
- for (Nodes::iterator i = _nodes.begin(); i != _nodes.end(); ++i)
- if ((*i)->symbol() == symbol)
- return _nodes.erase(i);
-
- return NULL;
+ _nodes.erase(_nodes.iterator_to(node));
}
void
@@ -246,7 +239,7 @@ PatchImpl::num_ports_non_rt() const
/** Create a port. Not realtime safe.
*/
-PortImpl*
+DuplexPort*
PatchImpl::create_port(BufferFactory& bufs,
const Raul::Symbol& symbol,
PortType type,
@@ -275,36 +268,16 @@ PatchImpl::create_port(BufferFactory& bufs,
*
* Realtime safe. Preprocessing thread only.
*/
-PatchImpl::Ports::Node*
-PatchImpl::remove_port(const Raul::Symbol& symbol)
+void
+PatchImpl::remove_port(DuplexPort& port)
{
ThreadManager::assert_thread(THREAD_PRE_PROCESS);
- bool found = false;
- Ports::Node* ret = NULL;
- for (Ports::iterator i = _inputs.begin(); i != _inputs.end(); ++i) {
- if ((*i)->symbol() == symbol) {
- ret = _inputs.erase(i);
- found = true;
- break;
- }
- }
-
- if (!found) {
- for (Ports::iterator i = _outputs.begin(); i != _outputs.end(); ++i) {
- if ((*i)->symbol() == symbol) {
- ret = _outputs.erase(i);
- found = true;
- break;
- }
- }
- }
-
- if (!found) {
- Raul::error << "[PatchImpl::remove_port] Port not found!" << endl;
+ if (port.is_input()) {
+ _inputs.erase(_inputs.iterator_to(port));
+ } else {
+ _outputs.erase(_outputs.iterator_to(port));
}
-
- return ret;
}
/** Remove all ports from ports list used in pre-processing thread.
@@ -324,7 +297,7 @@ PatchImpl::clear_ports()
}
Raul::Array<PortImpl*>*
-PatchImpl::build_ports_array() const
+PatchImpl::build_ports_array()
{
ThreadManager::assert_thread(THREAD_PRE_PROCESS);
@@ -333,11 +306,11 @@ PatchImpl::build_ports_array() const
size_t i = 0;
- for (Ports::const_iterator p = _inputs.begin(); p != _inputs.end(); ++p, ++i)
- result->at(i) = *p;
+ for (Ports::iterator p = _inputs.begin(); p != _inputs.end(); ++p, ++i)
+ result->at(i) = &*p;
- for (Ports::const_iterator p = _outputs.begin(); p != _outputs.end(); ++p, ++i)
- result->at(i) = *p;
+ for (Ports::iterator p = _outputs.begin(); p != _outputs.end(); ++p, ++i)
+ result->at(i) = &*p;
assert(i == n);
@@ -372,30 +345,35 @@ compile_recursive(NodeImpl* n, CompiledPatch* output)
* Not realtime safe.
*/
CompiledPatch*
-PatchImpl::compile() const
+PatchImpl::compile()
{
ThreadManager::assert_thread(THREAD_PRE_PROCESS);
- CompiledPatch* const compiled_patch = new CompiledPatch();//_nodes.size());
+ CompiledPatch* const compiled_patch = new CompiledPatch();
- for (Nodes::const_iterator i = _nodes.begin(); i != _nodes.end(); ++i)
- (*i)->traversed(false);
+ for (Nodes::iterator i = _nodes.begin(); i != _nodes.end(); ++i) {
+ i->traversed(false);
+ }
- for (Nodes::const_iterator i = _nodes.begin(); i != _nodes.end(); ++i) {
- NodeImpl* const node = (*i);
+ for (Nodes::iterator i = _nodes.begin(); i != _nodes.end(); ++i) {
// Either a sink or connected to our output ports:
- if (!node->traversed() && node->dependants().empty())
- compile_recursive(node, compiled_patch);
+ if (!i->traversed() && i->dependants().empty()) {
+ compile_recursive(&*i, compiled_patch);
+ }
}
// Traverse any nodes we didn't hit yet
- for (Nodes::const_iterator i = _nodes.begin(); i != _nodes.end(); ++i) {
- NodeImpl* const node = (*i);
- if ( ! node->traversed())
- compile_recursive(node, compiled_patch);
+ for (Nodes::iterator i = _nodes.begin(); i != _nodes.end(); ++i) {
+ if (!i->traversed()) {
+ compile_recursive(&*i, compiled_patch);
+ }
}
- assert(compiled_patch->size() == _nodes.size());
+ if (compiled_patch->size() != _nodes.size()) {
+ Raul::error(Raul::fmt("Failed to compile patch %1%\n") % _path);
+ delete compiled_patch;
+ return NULL;
+ }
return compiled_patch;
}
diff --git a/src/server/PatchImpl.hpp b/src/server/PatchImpl.hpp
index ac8a80ca..793f535b 100644
--- a/src/server/PatchImpl.hpp
+++ b/src/server/PatchImpl.hpp
@@ -18,12 +18,11 @@
#define INGEN_ENGINE_PATCHIMPL_HPP
#include <cstdlib>
-#include <list>
-#include <string>
#include "raul/List.hpp"
#include "CompiledPatch.hpp"
+#include "DuplexPort.hpp"
#include "NodeImpl.hpp"
#include "PluginImpl.hpp"
#include "PortType.hpp"
@@ -96,38 +95,40 @@ public:
// Patch specific stuff not inherited from Node
- typedef Raul::List<NodeImpl*> Nodes;
+ typedef boost::intrusive::slist<
+ NodeImpl, boost::intrusive::constant_time_size<true> > Nodes;
- void add_node(Nodes::Node* tn);
- Nodes::Node* remove_node(const Raul::Symbol& symbol);
+ void add_node(NodeImpl& node);
+ void remove_node(NodeImpl& node);
Nodes& nodes() { return _nodes; }
const Nodes& nodes() const { return _nodes; }
uint32_t num_ports_non_rt() const;
- PortImpl* create_port(BufferFactory& bufs,
- const Raul::Symbol& symbol,
- PortType type,
- LV2_URID buffer_type,
- uint32_t buffer_size,
- bool is_output,
- bool polyphonic);
+ DuplexPort* create_port(BufferFactory& bufs,
+ const Raul::Symbol& symbol,
+ PortType type,
+ LV2_URID buffer_type,
+ uint32_t buffer_size,
+ bool is_output,
+ bool polyphonic);
- typedef Raul::List<PortImpl*> Ports;
+ typedef boost::intrusive::slist<
+ DuplexPort, boost::intrusive::constant_time_size<true> > Ports;
- void add_input(Ports::Node* port) {
+ void add_input(DuplexPort& port) {
ThreadManager::assert_thread(THREAD_PRE_PROCESS);
- _inputs.push_back(port);
+ _inputs.push_front(port);
}
- void add_output(Ports::Node* port) {
+ void add_output(DuplexPort& port) {
ThreadManager::assert_thread(THREAD_PRE_PROCESS);
- _outputs.push_back(port);
+ _outputs.push_front(port);
}
- Ports::Node* remove_port(const Raul::Symbol& symbol);
- void clear_ports();
+ void remove_port(DuplexPort& port);
+ void clear_ports();
void add_edge(SharedPtr<EdgeImpl> c);
@@ -142,8 +143,8 @@ public:
Raul::Array<PortImpl*>* external_ports() { return _ports; }
void external_ports(Raul::Array<PortImpl*>* pa) { _ports = pa; }
- CompiledPatch* compile() const;
- Raul::Array<PortImpl*>* build_ports_array() const;
+ CompiledPatch* compile();
+ Raul::Array<PortImpl*>* build_ports_array();
/** Whether to run this patch's DSP bits in the audio thread */
bool enabled() const { return _process; }
diff --git a/src/server/events/CreateNode.cpp b/src/server/events/CreateNode.cpp
index e88434b7..02902db5 100644
--- a/src/server/events/CreateNode.cpp
+++ b/src/server/events/CreateNode.cpp
@@ -97,8 +97,8 @@ CreateNode::pre_process()
_node->properties().insert(_properties.begin(), _properties.end());
_node->activate(*_engine.buffer_factory());
- // Add node to the store and the patch's pre-processor only node list
- _patch->add_node(new PatchImpl::Nodes::Node(_node));
+ // Add node to the store and the patch's pre-processor only node list
+ _patch->add_node(*_node);
_engine.store()->add(_node);
/* Compile patch with new node added for insertion in audio thread
diff --git a/src/server/events/CreatePatch.cpp b/src/server/events/CreatePatch.cpp
index 368f8883..25f90d5d 100644
--- a/src/server/events/CreatePatch.cpp
+++ b/src/server/events/CreatePatch.cpp
@@ -83,7 +83,7 @@ CreatePatch::pre_process()
_patch->add_property(uris.rdf_type,
Resource::Property(uris.ingen_Node, Resource::EXTERNAL));
- _parent->add_node(new PatchImpl::Nodes::Node(_patch));
+ _parent->add_node(*_patch);
if (_parent->enabled()) {
_patch->enable();
_compiled_patch = _parent->compile();
diff --git a/src/server/events/CreatePort.cpp b/src/server/events/CreatePort.cpp
index 2782d654..49ceed95 100644
--- a/src/server/events/CreatePort.cpp
+++ b/src/server/events/CreatePort.cpp
@@ -140,9 +140,9 @@ CreatePort::pre_process()
_engine.store()->add(_patch_port);
if (_is_output) {
- _patch->add_output(new Raul::List<PortImpl*>::Node(_patch_port));
+ _patch->add_output(*_patch_port);
} else {
- _patch->add_input(new Raul::List<PortImpl*>::Node(_patch_port));
+ _patch->add_input(*_patch_port);
}
if (!_patch->parent()) {
diff --git a/src/server/events/CreatePort.hpp b/src/server/events/CreatePort.hpp
index 22304b4c..c8e4c695 100644
--- a/src/server/events/CreatePort.hpp
+++ b/src/server/events/CreatePort.hpp
@@ -28,9 +28,10 @@
namespace Ingen {
namespace Server {
+class DuplexPort;
+class EnginePort;
class PatchImpl;
class PortImpl;
-class EnginePort;
namespace Events {
@@ -58,7 +59,7 @@ private:
PortType _port_type;
LV2_URID _buf_type;
PatchImpl* _patch;
- PortImpl* _patch_port;
+ DuplexPort* _patch_port;
Raul::Array<PortImpl*>* _ports_array; ///< New external port array for Patch
Raul::Array<PortImpl*>* _old_ports_array;
EnginePort* _engine_port; ///< Driver port if on the root
diff --git a/src/server/events/Delete.cpp b/src/server/events/Delete.cpp
index 84b29a6f..e7001287 100644
--- a/src/server/events/Delete.cpp
+++ b/src/server/events/Delete.cpp
@@ -42,8 +42,6 @@ Delete::Delete(Engine& engine,
: Event(engine, client, id, time)
, _uri(uri)
, _engine_port(NULL)
- , _patch_node_listnode(NULL)
- , _patch_port_listnode(NULL)
, _ports_array(NULL)
, _compiled_patch(NULL)
, _disconnect_event(NULL)
@@ -62,7 +60,7 @@ Delete::~Delete()
bool
Delete::pre_process()
{
- if (_path == "/" || _path == "/control_in" || _path == "/control_out") {
+ if (_path.is_root() || _path == "/control_in" || _path == "/control_out") {
return Event::pre_process_done(NOT_DELETABLE, _path);
}
@@ -71,49 +69,47 @@ Delete::pre_process()
_removed_bindings = _engine.control_bindings()->remove(_path);
Store::iterator iter = _engine.store()->find(_path);
- if (iter != _engine.store()->end()) {
- if (!(_node = PtrCast<NodeImpl>(iter->second))) {
- _port = PtrCast<PortImpl>(iter->second);
- }
+ if (iter == _engine.store()->end()) {
+ return Event::pre_process_done(NOT_FOUND, _path);
}
- if (iter != _engine.store()->end()) {
- _engine.store()->remove(iter, _removed_objects);
+ if (!(_node = PtrCast<NodeImpl>(iter->second))) {
+ _port = PtrCast<DuplexPort>(iter->second);
}
- if (_node && !_path.is_root()) {
- assert(_node->parent_patch());
- _patch_node_listnode = _node->parent_patch()->remove_node(Raul::Symbol(_path.symbol()));
- if (_patch_node_listnode) {
- assert(_patch_node_listnode->elem() == _node.get());
+ if (!_node && !_port) {
+ return Event::pre_process_done(NOT_DELETABLE, _path);
+ }
- _disconnect_event = new DisconnectAll(_engine, _node->parent_patch(), _node.get());
- _disconnect_event->pre_process();
+ PatchImpl* parent = _node ? _node->parent_patch() : _port->parent_patch();
+ if (!parent) {
+ return Event::pre_process_done(INTERNAL_ERROR, _path);
+ }
- if (_node->parent_patch()->enabled()) {
- _compiled_patch = _node->parent_patch()->compile();
- }
+ _engine.store()->remove(iter, _removed_objects);
+
+ if (_node) {
+ parent->remove_node(*_node);
+ _disconnect_event = new DisconnectAll(_engine, parent, _node.get());
+ _disconnect_event->pre_process();
+
+ if (parent->enabled()) {
+ _compiled_patch = parent->compile();
}
} else if (_port) {
- assert(_port->parent_patch());
- _patch_port_listnode = _port->parent_patch()->remove_port(Raul::Symbol(_path.symbol()));
- if (_patch_port_listnode) {
- assert(_patch_port_listnode->elem() == _port.get());
-
- _disconnect_event = new DisconnectAll(_engine, _port->parent_patch(), _port.get());
- _disconnect_event->pre_process();
-
- if (_port->parent_patch()->enabled()) {
- _compiled_patch = _port->parent_patch()->compile();
- _ports_array = _port->parent_patch()->build_ports_array();
- assert(_ports_array->size() == _port->parent_patch()->num_ports_non_rt());
- }
-
- if (!_port->parent_patch()->parent()) {
- _engine_port = _engine.driver()->get_port(_port->path());
- }
+ parent->remove_port(*_port);
+ _disconnect_event = new DisconnectAll(_engine, parent, _port.get());
+ _disconnect_event->pre_process();
+
+ if (parent->enabled()) {
+ _compiled_patch = parent->compile();
+ _ports_array = parent->build_ports_array();
+ assert(_ports_array->size() == parent->num_ports_non_rt());
}
+ if (!parent->parent()) {
+ _engine_port = _engine.driver()->get_port(_port->path());
+ }
}
return Event::pre_process_done(SUCCESS);
@@ -122,35 +118,23 @@ Delete::pre_process()
void
Delete::execute(ProcessContext& context)
{
- PatchImpl* parent_patch = NULL;
-
- if (_patch_node_listnode) {
- assert(_node);
-
- if (_disconnect_event)
- _disconnect_event->execute(context);
-
- parent_patch = _node->parent_patch();
-
- } else if (_patch_port_listnode) {
- assert(_port);
-
- if (_disconnect_event)
- _disconnect_event->execute(context);
-
- parent_patch = _port->parent_patch();
+ if (_disconnect_event) {
+ _disconnect_event->execute(context);
+ }
- _engine.maid()->push(_port->parent_patch()->external_ports());
- _port->parent_patch()->external_ports(_ports_array);
+ PatchImpl* parent = _node ? _node->parent_patch() : _port->parent_patch();
+ if (_port) {
+ _engine.maid()->push(parent->external_ports());
+ parent->external_ports(_ports_array);
if (_engine_port) {
_engine.driver()->remove_port(context, _engine_port);
}
}
- if (parent_patch) {
- _engine.maid()->push(parent_patch->compiled_patch());
- parent_patch->compiled_patch(_compiled_patch);
+ if (parent) {
+ _engine.maid()->push(parent->compiled_patch());
+ parent->compiled_patch(_compiled_patch);
}
}
@@ -159,12 +143,9 @@ Delete::post_process()
{
_lock.release();
_removed_bindings.reset();
- if (!respond() && (_patch_node_listnode || _patch_port_listnode)) {
- if (_patch_node_listnode) {
+ if (!respond() && (_node || _port)) {
+ if (_node) {
_node->deactivate();
- delete _patch_node_listnode;
- } else if (_patch_port_listnode) {
- delete _patch_port_listnode;
}
_engine.broadcaster()->bundle_begin();
diff --git a/src/server/events/Delete.hpp b/src/server/events/Delete.hpp
index a493fcf7..f307eba4 100644
--- a/src/server/events/Delete.hpp
+++ b/src/server/events/Delete.hpp
@@ -32,6 +32,7 @@ namespace Server {
class NodeImpl;
class PortImpl;
+class DuplexPort;
class EnginePort;
class CompiledPatch;
@@ -69,16 +70,14 @@ public:
void post_process();
private:
- Raul::URI _uri;
- Raul::Path _path;
- SharedPtr<NodeImpl> _node; ///< Non-NULL iff a node
- SharedPtr<PortImpl> _port; ///< Non-NULL iff a port
- EnginePort* _engine_port;
- PatchImpl::Nodes::Node* _patch_node_listnode;
- 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
- DisconnectAll* _disconnect_event;
+ Raul::URI _uri;
+ Raul::Path _path;
+ SharedPtr<NodeImpl> _node; ///< Non-NULL iff a node
+ SharedPtr<DuplexPort> _port; ///< Non-NULL iff a port
+ EnginePort* _engine_port;
+ Raul::Array<PortImpl*>* _ports_array; ///< New (external) ports for Patch
+ CompiledPatch* _compiled_patch; ///< Patch's new process order
+ DisconnectAll* _disconnect_event;
SharedPtr<ControlBindings::Bindings> _removed_bindings;
Store::Objects _removed_objects;
diff --git a/src/server/events/Get.cpp b/src/server/events/Get.cpp
index b826aa5d..294a15b3 100644
--- a/src/server/events/Get.cpp
+++ b/src/server/events/Get.cpp
@@ -109,16 +109,14 @@ send_patch(Interface* client, const PatchImpl* patch)
Resource::EXTERNAL);
// Send nodes
- for (Raul::List<NodeImpl*>::const_iterator j = patch->nodes().begin();
+ for (PatchImpl::Nodes::const_iterator j = patch->nodes().begin();
j != patch->nodes().end(); ++j) {
- const NodeImpl* const node = (*j);
- send_node(client, node);
+ send_node(client, &*j);
}
// Send ports
for (uint32_t i = 0; i < patch->num_ports_non_rt(); ++i) {
- PortImpl* const port = patch->port_impl(i);
- send_port(client, port);
+ send_port(client, patch->port_impl(i));
}
// Send edges