summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDavid Robillard <d@drobilla.net>2007-01-06 19:39:56 +0000
committerDavid Robillard <d@drobilla.net>2007-01-06 19:39:56 +0000
commit69c5e7fe16b7d9d08db81a6d5e2762f0be3b081f (patch)
tree68fd1ea83beedaaaa97846ed09240a3585b2d931
parent2122a857662203936a04a39df7d0e1ad1db82853 (diff)
downloadingen-69c5e7fe16b7d9d08db81a6d5e2762f0be3b081f.tar.gz
ingen-69c5e7fe16b7d9d08db81a6d5e2762f0be3b081f.tar.bz2
ingen-69c5e7fe16b7d9d08db81a6d5e2762f0be3b081f.zip
Added ability to get Raul Thread for current calling context.
Strong threading assertions. Flowcanvas port removal fixes. Patch port destruction. Code cleanups, bug fixes. git-svn-id: http://svn.drobilla.net/lad/ingen@234 a436a847-0d15-0410-975c-d299462d15a1
-rw-r--r--src/libs/engine/Engine.cpp20
-rw-r--r--src/libs/engine/Event.h15
-rw-r--r--src/libs/engine/GraphObject.cpp3
-rw-r--r--src/libs/engine/JackAudioDriver.cpp14
-rw-r--r--src/libs/engine/JackAudioDriver.h14
-rw-r--r--src/libs/engine/Makefile.am1
-rw-r--r--src/libs/engine/NodeFactory.cpp3
-rw-r--r--src/libs/engine/OSCEngineReceiver.cpp3
-rw-r--r--src/libs/engine/Patch.cpp45
-rw-r--r--src/libs/engine/Patch.h3
-rw-r--r--src/libs/engine/QueuedEvent.h1
-rw-r--r--src/libs/engine/QueuedEventSource.cpp8
-rw-r--r--src/libs/engine/ThreadManager.h40
-rw-r--r--src/libs/engine/events/AddPortEvent.cpp9
-rw-r--r--src/libs/engine/events/CreatePatchEvent.cpp14
-rw-r--r--src/libs/engine/events/DestroyEvent.cpp15
-rw-r--r--src/libs/engine/events/DestroyEvent.h1
-rw-r--r--src/libs/engine/tests/Makefile.am6
-rw-r--r--src/libs/engine/tests/queue_test.cpp47
-rw-r--r--src/progs/ingenuity/NodeModule.cpp8
-rw-r--r--src/progs/ingenuity/NodeModule.h2
-rw-r--r--src/progs/ingenuity/PatchCanvas.cpp4
-rw-r--r--src/progs/ingenuity/PatchPortModule.cpp2
-rw-r--r--src/progs/server/Makefile.am2
24 files changed, 183 insertions, 97 deletions
diff --git a/src/libs/engine/Engine.cpp b/src/libs/engine/Engine.cpp
index b83c7244..1af94931 100644
--- a/src/libs/engine/Engine.cpp
+++ b/src/libs/engine/Engine.cpp
@@ -161,16 +161,16 @@ Engine::activate(SharedPtr<AudioDriver> ad, SharedPtr<EventSource> es)
m_event_source->activate();
// Create root patch
- CreatePatchEvent create_ev(*this, SharedPtr<Responder>(new Responder()), 0, "/", 1);
- create_ev.pre_process();
- create_ev.execute(1, 0, 1);
- create_ev.post_process();
- EnablePatchEvent enable_ev(*this, SharedPtr<Responder>(new Responder()), 0, "/");
- enable_ev.pre_process();
- enable_ev.execute(1, 0, 1);
- enable_ev.post_process();
-
- assert(m_audio_driver->root_patch() != NULL);
+
+ Patch* root_patch = new Patch("", 1, NULL,
+ m_audio_driver->sample_rate(), m_audio_driver->buffer_size(), 1);
+ root_patch->activate();
+ root_patch->add_to_store(m_object_store);
+ root_patch->process_order(root_patch->build_process_order());
+ root_patch->enable();
+
+ assert(m_audio_driver->root_patch() == NULL);
+ m_audio_driver->set_root_patch(root_patch);
m_audio_driver->activate();
#ifdef HAVE_ALSA_MIDI
diff --git a/src/libs/engine/Event.h b/src/libs/engine/Event.h
index 5ba9b2a2..c2e18949 100644
--- a/src/libs/engine/Event.h
+++ b/src/libs/engine/Event.h
@@ -22,6 +22,7 @@
#include "types.h"
#include "MaidObject.h"
#include "Responder.h"
+#include "ThreadManager.h"
namespace Ingen {
@@ -47,6 +48,7 @@ public:
/** Execute this event in the audio thread (MUST be realtime safe). */
virtual void execute(SampleCount nframes, FrameTime start, FrameTime end)
{
+ assert(ThreadManager::current_thread_id() == THREAD_PROCESS);
assert(!_executed);
assert(_time <= end);
@@ -59,7 +61,10 @@ public:
/** Perform any actions after execution (ie send replies to commands)
* (no realtime requirements). */
- virtual void post_process() {}
+ virtual void post_process()
+ {
+ assert(ThreadManager::current_thread_id() == THREAD_POST_PROCESS);
+ }
inline SampleCount time() { return _time; }
@@ -71,10 +76,10 @@ protected:
, _executed(false)
{}
- Engine& _engine;
- SharedPtr<Responder> _responder;
- FrameTime _time;
- bool _executed;
+ Engine& _engine;
+ SharedPtr<Responder> _responder;
+ FrameTime _time;
+ bool _executed;
};
diff --git a/src/libs/engine/GraphObject.cpp b/src/libs/engine/GraphObject.cpp
index 03b4eae7..7173e6f8 100644
--- a/src/libs/engine/GraphObject.cpp
+++ b/src/libs/engine/GraphObject.cpp
@@ -33,6 +33,7 @@ GraphObject::parent_patch() const
void
GraphObject::add_to_store(ObjectStore* store)
{
+ assert(!_store);
store->add(this);
_store = store;
}
@@ -41,6 +42,8 @@ GraphObject::add_to_store(ObjectStore* store)
void
GraphObject::remove_from_store()
{
+ assert(_store);
+
if (_store) {
TreeNode<GraphObject*>* node = _store->remove(path());
if (node != NULL) {
diff --git a/src/libs/engine/JackAudioDriver.cpp b/src/libs/engine/JackAudioDriver.cpp
index 082afe5a..58834139 100644
--- a/src/libs/engine/JackAudioDriver.cpp
+++ b/src/libs/engine/JackAudioDriver.cpp
@@ -22,6 +22,7 @@
#include "Engine.h"
#include "util.h"
#include "Event.h"
+#include "ThreadManager.h"
#include "QueuedEvent.h"
#include "EventSource.h"
#include "PostProcessor.h"
@@ -122,6 +123,7 @@ JackAudioDriver::JackAudioDriver(Engine& engine,
std::string server_name,
jack_client_t* jack_client)
: _engine(engine),
+ _jack_thread(NULL),
_client(jack_client),
_buffer_size(jack_client ? jack_get_buffer_size(jack_client) : 0),
_sample_rate(jack_client ? jack_get_sample_rate(jack_client) : 0),
@@ -159,6 +161,7 @@ JackAudioDriver::JackAudioDriver(Engine& engine,
jack_on_shutdown(_client, shutdown_cb, this);
+ jack_set_thread_init_callback(_client, thread_init_cb, this);
jack_set_sample_rate_callback(_client, sample_rate_cb, this);
jack_set_buffer_size_callback(_client, buffer_size_cb, this);
}
@@ -310,10 +313,21 @@ JackAudioDriver::_process_cb(jack_nframes_t nframes)
void
+JackAudioDriver::_thread_init_cb()
+{
+ // Initialize thread specific data
+ _jack_thread = Thread::create_for_this_thread("Jack");
+ assert(&Thread::get() == _jack_thread);
+ _jack_thread->set_context(THREAD_PROCESS);
+ assert(ThreadManager::current_thread_id() == THREAD_PROCESS);
+}
+
+void
JackAudioDriver::_shutdown_cb()
{
cout << "[JackAudioDriver] Jack shutdown. Exiting." << endl;
_engine.quit();
+ _jack_thread = NULL;
}
diff --git a/src/libs/engine/JackAudioDriver.h b/src/libs/engine/JackAudioDriver.h
index 15651c26..53f48035 100644
--- a/src/libs/engine/JackAudioDriver.h
+++ b/src/libs/engine/JackAudioDriver.h
@@ -19,6 +19,7 @@
#include <jack/jack.h>
#include <jack/transport.h>
+#include "raul/Thread.h"
#include "List.h"
#include "AudioDriver.h"
#include "Buffer.h"
@@ -111,18 +112,21 @@ private:
// These are the static versions of the callbacks, they call
// the non-static ones below
- inline static int process_cb(jack_nframes_t nframes, void* const jack_driver);
+ inline static void thread_init_cb(void* const jack_driver);
inline static void shutdown_cb(void* const jack_driver);
+ inline static int process_cb(jack_nframes_t nframes, void* const jack_driver);
inline static int buffer_size_cb(jack_nframes_t nframes, void* const jack_driver);
inline static int sample_rate_cb(jack_nframes_t nframes, void* const jack_driver);
// Non static callbacks
- int _process_cb(jack_nframes_t nframes);
+ void _thread_init_cb();
void _shutdown_cb();
+ int _process_cb(jack_nframes_t nframes);
int _buffer_size_cb(jack_nframes_t nframes);
int _sample_rate_cb(jack_nframes_t nframes);
Engine& _engine;
+ Thread* _jack_thread;
jack_client_t* _client;
jack_nframes_t _buffer_size;
jack_nframes_t _sample_rate;
@@ -143,6 +147,12 @@ inline int JackAudioDriver::process_cb(jack_nframes_t nframes, void* jack_driver
return ((JackAudioDriver*)jack_driver)->_process_cb(nframes);
}
+inline void JackAudioDriver::thread_init_cb(void* jack_driver)
+{
+ assert(jack_driver);
+ return ((JackAudioDriver*)jack_driver)->_thread_init_cb();
+}
+
inline void JackAudioDriver::shutdown_cb(void* jack_driver)
{
assert(jack_driver);
diff --git a/src/libs/engine/Makefile.am b/src/libs/engine/Makefile.am
index eac42257..97eadb29 100644
--- a/src/libs/engine/Makefile.am
+++ b/src/libs/engine/Makefile.am
@@ -12,6 +12,7 @@ libingen_la_SOURCES = \
util.h \
tuning.h \
events.h \
+ ThreadManager.h \
DataType.h \
Node.h \
NodeBase.h \
diff --git a/src/libs/engine/NodeFactory.cpp b/src/libs/engine/NodeFactory.cpp
index 1cbabaeb..f7cc07fb 100644
--- a/src/libs/engine/NodeFactory.cpp
+++ b/src/libs/engine/NodeFactory.cpp
@@ -22,6 +22,7 @@
#include <float.h>
#include <cmath>
#include <dlfcn.h>
+#include "ThreadManager.h"
#include "MidiNoteNode.h"
#include "MidiTriggerNode.h"
#include "MidiControlNode.h"
@@ -124,6 +125,8 @@ NodeFactory::plugin(const string& type, const string& lib, const string& label)
void
NodeFactory::load_plugins()
{
+ assert(ThreadManager::current_thread_id() == THREAD_PRE_PROCESS);
+
// Only load if we havn't already, so every client connecting doesn't cause
// this (expensive!) stuff to happen. Not the best solution - would be nice
// if clients could refresh plugins list for whatever reason :/
diff --git a/src/libs/engine/OSCEngineReceiver.cpp b/src/libs/engine/OSCEngineReceiver.cpp
index 26377a37..35dd5bcb 100644
--- a/src/libs/engine/OSCEngineReceiver.cpp
+++ b/src/libs/engine/OSCEngineReceiver.cpp
@@ -125,7 +125,7 @@ OSCEngineReceiver::OSCEngineReceiver(SharedPtr<Engine> engine, size_t queue_size
lo_server_add_method(_server, NULL, NULL, unknown_cb, NULL);
- Thread::set_name("OSC Receiver");
+ Thread::set_name("OSCEngineReceiver");
}
@@ -143,7 +143,6 @@ OSCEngineReceiver::~OSCEngineReceiver()
void
OSCEngineReceiver::activate()
{
- set_name("OSCEngineReceiver");
QueuedEventSource::activate();
set_scheduling(SCHED_FIFO, 10);
}
diff --git a/src/libs/engine/Patch.cpp b/src/libs/engine/Patch.cpp
index d1d3e84a..549c9e0f 100644
--- a/src/libs/engine/Patch.cpp
+++ b/src/libs/engine/Patch.cpp
@@ -17,6 +17,7 @@
#include <cassert>
#include <cmath>
#include <iostream>
+#include "ThreadManager.h"
#include "Node.h"
#include "Patch.h"
#include "Plugin.h"
@@ -244,6 +245,19 @@ Patch::remove_bridge_node(const InternalNode* node)
}
#endif
+
+size_t
+Patch::num_ports() const
+{
+ ThreadID context = ThreadManager::current_thread_id();
+
+ if (context == THREAD_PROCESS)
+ return NodeBase::num_ports();
+ else
+ return _input_ports.size() + _output_ports.size();
+}
+
+
/** Create a port. Not realtime safe.
*/
Port*
@@ -266,12 +280,18 @@ Patch::create_port(const string& name, DataType type, size_t buffer_size, bool i
}
-/** Remove a port.
- * Realtime safe. Preprocessing thread.
+/** Remove port from ports list used in pre-processing thread.
+ *
+ * Port is not removed from ports array for process thread (which could be
+ * simultaneously running).
+ *
+ * Realtime safe. Preprocessing thread only.
*/
ListNode<Port*>*
Patch::remove_port(const string& name)
{
+ assert(ThreadManager::current_thread_id() == THREAD_PRE_PROCESS);
+
bool found = false;
ListNode<Port*>* ret = NULL;
for (List<Port*>::iterator i = _input_ports.begin(); i != _input_ports.end(); ++i) {
@@ -296,6 +316,25 @@ Patch::remove_port(const string& name)
}
+Array<Port*>*
+Patch::build_ports_array() const
+{
+ assert(ThreadManager::current_thread_id() == THREAD_PRE_PROCESS);
+
+ Array<Port*>* const result = new Array<Port*>(_input_ports.size() + _output_ports.size());
+
+ size_t i = 0;
+
+ for (List<Port*>::const_iterator p = _input_ports.begin(); p != _input_ports.end(); ++p,++i)
+ result->at(i) = *p;
+
+ for (List<Port*>::const_iterator p = _output_ports.begin(); p != _output_ports.end(); ++p,++i)
+ result->at(i) = *p;
+
+ return result;
+}
+
+
/** Find the process order for this Patch.
*
* The process order is a flat list that the patch will execute in order
@@ -309,6 +348,8 @@ Patch::remove_port(const string& name)
Array<Node*>*
Patch::build_process_order() const
{
+ assert(ThreadManager::current_thread_id() == THREAD_PRE_PROCESS);
+
cerr << "*********** Building process order for " << path() << endl;
Array<Node*>* const process_order = new Array<Node*>(_nodes.size(), NULL);
diff --git a/src/libs/engine/Patch.h b/src/libs/engine/Patch.h
index 3a4f08d5..b0fab692 100644
--- a/src/libs/engine/Patch.h
+++ b/src/libs/engine/Patch.h
@@ -76,6 +76,8 @@ public:
const List<Node*>& nodes() const { return _nodes; }
const List<Connection*>& connections() const { return _connections; }
+ size_t num_ports() const;
+
Port* create_port(const string& name, DataType type, size_t buffer_size, bool is_output);
void add_input(ListNode<Port*>* port) { _input_ports.push_back(port); } ///< Preprocesser thread
void add_output(ListNode<Port*>* port) { _output_ports.push_back(port); } ///< Preprocessor thread
@@ -91,6 +93,7 @@ public:
void external_ports(Array<Port*>* pa) { _ports = pa; }
Array<Node*>* build_process_order() const;
+ Array<Port*>* build_ports_array() const;
/** Whether to run this patch's DSP bits in the audio thread */
bool enabled() const { return _process; }
diff --git a/src/libs/engine/QueuedEvent.h b/src/libs/engine/QueuedEvent.h
index c400da8c..acd0da80 100644
--- a/src/libs/engine/QueuedEvent.h
+++ b/src/libs/engine/QueuedEvent.h
@@ -45,6 +45,7 @@ public:
/** Process this event into a realtime-suitable event.
*/
virtual void pre_process() {
+ assert(ThreadManager::current_thread_id() == THREAD_PRE_PROCESS);
assert(_pre_processed == false);
_pre_processed = true;
}
diff --git a/src/libs/engine/QueuedEventSource.cpp b/src/libs/engine/QueuedEventSource.cpp
index 08e1c63e..ea6f2c34 100644
--- a/src/libs/engine/QueuedEventSource.cpp
+++ b/src/libs/engine/QueuedEventSource.cpp
@@ -17,6 +17,7 @@
#include "QueuedEventSource.h"
#include "QueuedEvent.h"
#include "PostProcessor.h"
+#include "ThreadManager.h"
#include <sys/mman.h>
#include <iostream>
using std::cout; using std::cerr; using std::endl;
@@ -37,7 +38,8 @@ QueuedEventSource::QueuedEventSource(size_t queued_size, size_t stamped_size)
mlock(_events, _size * sizeof(QueuedEvent*));
- Thread::set_name("PreProcessor");
+ Thread::set_context(THREAD_PRE_PROCESS);
+ assert(context() == THREAD_PRE_PROCESS);
}
@@ -74,6 +76,8 @@ QueuedEventSource::push_queued(QueuedEvent* const ev)
void
QueuedEventSource::process(PostProcessor& dest, SampleCount nframes, FrameTime cycle_start, FrameTime cycle_end)
{
+ assert(ThreadManager::current_thread_id() == THREAD_PROCESS);
+
Event* ev = NULL;
/* Limit the maximum number of queued events to process per cycle. This
@@ -118,6 +122,8 @@ QueuedEventSource::process(PostProcessor& dest, SampleCount nframes, FrameTime c
Event*
QueuedEventSource::pop_earliest_queued_before(const SampleCount time)
{
+ assert(ThreadManager::current_thread_id() == THREAD_PROCESS);
+
QueuedEvent* const front_event = _events[_front];
// Pop
diff --git a/src/libs/engine/ThreadManager.h b/src/libs/engine/ThreadManager.h
new file mode 100644
index 00000000..24ca414c
--- /dev/null
+++ b/src/libs/engine/ThreadManager.h
@@ -0,0 +1,40 @@
+/* This file is part of Ingen. Copyright (C) 2007 Dave Robillard.
+ *
+ * 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 THREADMANAGER_H
+#define THREADMANAGER_H
+
+#include "raul/Thread.h"
+
+namespace Ingen {
+
+
+enum ThreadID {
+ THREAD_PRE_PROCESS,
+ THREAD_PROCESS,
+ THREAD_POST_PROCESS
+};
+
+
+class ThreadManager {
+public:
+ inline static ThreadID current_thread_id() { return (ThreadID)Thread::get().context(); }
+};
+
+
+} // namespace Ingen
+
+#endif // THREADMANAGER_H
diff --git a/src/libs/engine/events/AddPortEvent.cpp b/src/libs/engine/events/AddPortEvent.cpp
index aa7c3ca5..bdce9267 100644
--- a/src/libs/engine/events/AddPortEvent.cpp
+++ b/src/libs/engine/events/AddPortEvent.cpp
@@ -106,8 +106,8 @@ AddPortEvent::pre_process()
_ports_array = new Array<Port*>(old_num_ports + 1, NULL);
- _ports_array->at(_patch->num_ports()) = _patch_port;
- _engine.object_store()->add(_patch_port);
+ _ports_array->at(_patch->num_ports()-1) = _patch_port;
+ _patch_port->add_to_store(_engine.object_store());
if (!_patch->parent()) {
if (_type == "ingen:audio")
@@ -118,8 +118,9 @@ AddPortEvent::pre_process()
dynamic_cast<DuplexPort<MidiMessage>*>(_patch_port));
}
- assert(_patch->num_ports() == old_num_ports);
- assert(_ports_array->size() == _patch->num_ports() + 1);
+ assert(_ports_array->size() == _patch->num_ports());
+
+
}
}
QueuedEvent::pre_process();
diff --git a/src/libs/engine/events/CreatePatchEvent.cpp b/src/libs/engine/events/CreatePatchEvent.cpp
index 9124f280..73813dbb 100644
--- a/src/libs/engine/events/CreatePatchEvent.cpp
+++ b/src/libs/engine/events/CreatePatchEvent.cpp
@@ -45,7 +45,7 @@ CreatePatchEvent::CreatePatchEvent(Engine& engine, SharedPtr<Responder> responde
void
CreatePatchEvent::pre_process()
{
- if (_engine.object_store()->find(m_path) != NULL) {
+ if (m_path == "/" || _engine.object_store()->find(m_path) != NULL) {
m_error = OBJECT_EXISTS;
QueuedEvent::pre_process();
return;
@@ -57,13 +57,11 @@ CreatePatchEvent::pre_process()
return;
}
- if (m_path != "/") {
- m_parent = _engine.object_store()->find_patch(m_path.parent());
- if (m_parent == NULL) {
- m_error = PARENT_NOT_FOUND;
- QueuedEvent::pre_process();
- return;
- }
+ m_parent = _engine.object_store()->find_patch(m_path.parent());
+ if (m_parent == NULL) {
+ m_error = PARENT_NOT_FOUND;
+ QueuedEvent::pre_process();
+ return;
}
size_t poly = 1;
diff --git a/src/libs/engine/events/DestroyEvent.cpp b/src/libs/engine/events/DestroyEvent.cpp
index 9801f0fe..26902697 100644
--- a/src/libs/engine/events/DestroyEvent.cpp
+++ b/src/libs/engine/events/DestroyEvent.cpp
@@ -43,6 +43,7 @@ DestroyEvent::DestroyEvent(Engine& engine, SharedPtr<Responder> responder, Frame
_patch_node_listnode(NULL),
_patch_port_listnode(NULL),
_store_treenode(NULL),
+ _ports_array(NULL),
_process_order(NULL),
_disconnect_node_event(NULL),
_disconnect_port_event(NULL)
@@ -60,6 +61,7 @@ DestroyEvent::DestroyEvent(Engine& engine, SharedPtr<Responder> responder, Frame
_patch_node_listnode(NULL),
_patch_port_listnode(NULL),
_store_treenode(NULL),
+ _ports_array(NULL),
_process_order(NULL),
_disconnect_node_event(NULL),
_disconnect_port_event(NULL)
@@ -131,11 +133,8 @@ DestroyEvent::pre_process()
if (_port->parent_patch()->enabled()) {
// FIXME: is this called multiple times?
_process_order = _port->parent_patch()->build_process_order();
- // Remove port to be removed from the process order so it isn't executed by
- // Patch::run and can safely be destroyed
- //for (size_t i=0; i < _process_order->size(); ++i)
- // if (_process_order->at(i) == _port)
- // _process_order->at(i) = NULL; // ew, gap
+ _ports_array = _port->parent_patch()->build_ports_array();
+ assert(_ports_array->size() == _port->parent_patch()->num_ports());
}
}
@@ -168,7 +167,13 @@ DestroyEvent::execute(SampleCount nframes, FrameTime start, FrameTime end)
if (_port->parent_patch()->process_order() != NULL)
_engine.maid()->push(_port->parent_patch()->process_order());
+
_port->parent_patch()->process_order(_process_order);
+
+ if (_port->parent_patch()->external_ports() != NULL)
+ _engine.maid()->push(_port->parent_patch()->external_ports());
+
+ _port->parent_patch()->external_ports(_ports_array);
}
}
diff --git a/src/libs/engine/events/DestroyEvent.h b/src/libs/engine/events/DestroyEvent.h
index ad67bbca..6dfebbf7 100644
--- a/src/libs/engine/events/DestroyEvent.h
+++ b/src/libs/engine/events/DestroyEvent.h
@@ -61,6 +61,7 @@ private:
ListNode<Node*>* _patch_node_listnode;
ListNode<Port*>* _patch_port_listnode;
TreeNode<GraphObject*>* _store_treenode;
+ Array<Port*>* _ports_array; ///< New (external) ports array for Patch
Array<Node*>* _process_order; ///< Patch's new process order
DisconnectNodeEvent* _disconnect_node_event;
DisconnectPortEvent* _disconnect_port_event;
diff --git a/src/libs/engine/tests/Makefile.am b/src/libs/engine/tests/Makefile.am
index 0da5ee09..993c9831 100644
--- a/src/libs/engine/tests/Makefile.am
+++ b/src/libs/engine/tests/Makefile.am
@@ -3,9 +3,8 @@ if BUILD_UNIT_TESTS
AM_CXXFLAGS = @JACK_CFLAGS@ @LOSC_CFLAGS@ @ALSA_CFLAGS@ -I../../common
common_ldadd = @JACK_LIBS@ @LOSC_LIBS@ @ALSA_LIBS@ -lrt
node_tree_test_LDADD = $(common_ldadd)
-queue_test_LDADD = $(common_ldadd)
-bin_PROGRAMS = node_tree_test queue_test list_test
+bin_PROGRAMS = node_tree_test list_test
list_test_SOURCES = \
../List.h \
@@ -14,7 +13,4 @@ list_test_SOURCES = \
node_tree_test_SOURCES = \
node_tree_test.cpp
-queue_test_SOURCES = \
- queue_test.cpp
-
endif # BUILD_UNIT_TESTS
diff --git a/src/libs/engine/tests/queue_test.cpp b/src/libs/engine/tests/queue_test.cpp
deleted file mode 100644
index 3381a329..00000000
--- a/src/libs/engine/tests/queue_test.cpp
+++ /dev/null
@@ -1,47 +0,0 @@
-#include <iostream>
-#include <string>
-#include "../../common/Queue.h"
-
-using std::string; using std::cerr; using std::cout; using std::endl;
-
-
-int main()
-{
- Queue<int> q(10);
-
- cout << "New queue. Should be empty: " << q.is_empty() << endl;
- cout << "Capacity: " << q.capacity() << endl;
- cout << "Fill: " << q.fill() << endl;
-
- for (uint i=0; i < 5; ++i) {
- q.push(i);
- assert(!q.is_full());
- q.pop();
- }
- cout << "Pushed and popped 5 elements. Queue should be empty: " << q.is_empty() << endl;
- cout << "Fill: " << q.fill() << endl;
-
- for (uint i=10; i < 20; ++i) {
- q.push(i);
- }
- cout << "Pushed 10 elements. Queue should be full: " << q.is_full() << endl;
- cout << "Fill: " << q.fill() << endl;
-
- cout << "The digits 10->19 should print: " << endl;
- while (!q.is_empty()) {
- int foo = q.pop();
- cout << "Popped: " << foo << endl;
- }
- cout << "Queue should be empty: " << q.is_empty() << endl;
- cout << "Fill: " << q.fill() << endl;
-
- cout << "Attempting to add eleven elements to queue of size 10. Only first 10 should succeed:" << endl;
- for (uint i=20; i <= 39; ++i) {
- cout << i;
- cout << " - Fill: " << q.fill();
- cout << ", is full: " << q.is_full();
- cout << ", succeeded: " << q.push(i) << endl;
- }
-
- return 0;
-}
diff --git a/src/progs/ingenuity/NodeModule.cpp b/src/progs/ingenuity/NodeModule.cpp
index bec6e89c..95ab69e1 100644
--- a/src/progs/ingenuity/NodeModule.cpp
+++ b/src/progs/ingenuity/NodeModule.cpp
@@ -82,6 +82,14 @@ NodeModule::add_port(SharedPtr<PortModel> port, bool resize_to_fit)
void
+NodeModule::remove_port(SharedPtr<PortModel> port)
+{
+ SharedPtr<LibFlowCanvas::Port> p = Module::remove_port(port->path().name());
+ p.reset();
+}
+
+
+void
NodeModule::show_control_window()
{
App::instance().window_factory()->present_controls(m_node);
diff --git a/src/progs/ingenuity/NodeModule.h b/src/progs/ingenuity/NodeModule.h
index 625241e7..12012f97 100644
--- a/src/progs/ingenuity/NodeModule.h
+++ b/src/progs/ingenuity/NodeModule.h
@@ -77,7 +77,7 @@ protected:
void metadata_update(const string& key, const Atom& value);
void add_port(SharedPtr<PortModel> port, bool resize=true);
- void remove_port(SharedPtr<PortModel> port) { Module::remove_port(port->path().name()); }
+ void remove_port(SharedPtr<PortModel> port);
SharedPtr<NodeModel> m_node;
NodeMenu m_menu;
diff --git a/src/progs/ingenuity/PatchCanvas.cpp b/src/progs/ingenuity/PatchCanvas.cpp
index fe65a05f..f7c80987 100644
--- a/src/progs/ingenuity/PatchCanvas.cpp
+++ b/src/progs/ingenuity/PatchCanvas.cpp
@@ -152,9 +152,7 @@ PatchCanvas::add_port(SharedPtr<PortModel> pm)
void
PatchCanvas::remove_port(SharedPtr<PortModel> pm)
{
- cerr << "FIXME: PORT REMOVE" << endl;
- //LibFlowCanvas::Module* module = get_module(pm->path().name());
- //delete module;
+ remove_module(pm->path().name()); // should cut all references
}
diff --git a/src/progs/ingenuity/PatchPortModule.cpp b/src/progs/ingenuity/PatchPortModule.cpp
index e4c00130..53b56854 100644
--- a/src/progs/ingenuity/PatchPortModule.cpp
+++ b/src/progs/ingenuity/PatchPortModule.cpp
@@ -30,7 +30,7 @@ namespace Ingenuity {
PatchPortModule::PatchPortModule(boost::shared_ptr<PatchCanvas> canvas, SharedPtr<PortModel> port)
-: LibFlowCanvas::Module(canvas, "", 0, 0), // FIXME: coords?
+: LibFlowCanvas::Module(canvas, port->path().name(), 0, 0, false), // FIXME: coords?
m_port(port)
{
/*if (port_model()->polyphonic() && port_model()->parent() != NULL
diff --git a/src/progs/server/Makefile.am b/src/progs/server/Makefile.am
index 9388b12a..02a72855 100644
--- a/src/progs/server/Makefile.am
+++ b/src/progs/server/Makefile.am
@@ -9,7 +9,7 @@ if BUILD_SERVER
bin_PROGRAMS = ingen
ingen_DEPENDENCIES = ../../libs/engine/libingen.la
-ingen_LDADD = @JACK_LIBS@ @LOSC_LIBS@ @ALSA_LIBS@ @LASH_LIBS@ @SLV2_LIBS@ -lrt ../../libs/engine/libingen.la
+ingen_LDADD = @RAUL_LIBS@ @JACK_LIBS@ @LOSC_LIBS@ @ALSA_LIBS@ @LASH_LIBS@ @SLV2_LIBS@ -lrt ../../libs/engine/libingen.la
ingen_SOURCES = \
main.cpp \