From 69c5e7fe16b7d9d08db81a6d5e2762f0be3b081f Mon Sep 17 00:00:00 2001 From: David Robillard Date: Sat, 6 Jan 2007 19:39:56 +0000 Subject: 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 --- src/libs/engine/Engine.cpp | 20 ++++++------ src/libs/engine/Event.h | 15 ++++++--- src/libs/engine/GraphObject.cpp | 3 ++ src/libs/engine/JackAudioDriver.cpp | 14 +++++++++ src/libs/engine/JackAudioDriver.h | 14 +++++++-- src/libs/engine/Makefile.am | 1 + src/libs/engine/NodeFactory.cpp | 3 ++ src/libs/engine/OSCEngineReceiver.cpp | 3 +- src/libs/engine/Patch.cpp | 45 +++++++++++++++++++++++++-- src/libs/engine/Patch.h | 3 ++ src/libs/engine/QueuedEvent.h | 1 + src/libs/engine/QueuedEventSource.cpp | 8 ++++- src/libs/engine/ThreadManager.h | 40 ++++++++++++++++++++++++ src/libs/engine/events/AddPortEvent.cpp | 9 +++--- src/libs/engine/events/CreatePatchEvent.cpp | 14 ++++----- src/libs/engine/events/DestroyEvent.cpp | 15 ++++++--- src/libs/engine/events/DestroyEvent.h | 1 + src/libs/engine/tests/Makefile.am | 6 +--- src/libs/engine/tests/queue_test.cpp | 47 ----------------------------- src/progs/ingenuity/NodeModule.cpp | 8 +++++ src/progs/ingenuity/NodeModule.h | 2 +- src/progs/ingenuity/PatchCanvas.cpp | 4 +-- src/progs/ingenuity/PatchPortModule.cpp | 2 +- src/progs/server/Makefile.am | 2 +- 24 files changed, 183 insertions(+), 97 deletions(-) create mode 100644 src/libs/engine/ThreadManager.h delete mode 100644 src/libs/engine/tests/queue_test.cpp 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 ad, SharedPtr es) m_event_source->activate(); // Create root patch - CreatePatchEvent create_ev(*this, SharedPtr(new Responder()), 0, "/", 1); - create_ev.pre_process(); - create_ev.execute(1, 0, 1); - create_ev.post_process(); - EnablePatchEvent enable_ev(*this, SharedPtr(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; - FrameTime _time; - bool _executed; + Engine& _engine; + SharedPtr _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* 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); } @@ -309,11 +312,22 @@ 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 #include +#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 #include #include +#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, 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 #include #include +#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* Patch::remove_port(const string& name) { + assert(ThreadManager::current_thread_id() == THREAD_PRE_PROCESS); + bool found = false; ListNode* ret = NULL; for (List::iterator i = _input_ports.begin(); i != _input_ports.end(); ++i) { @@ -296,6 +316,25 @@ Patch::remove_port(const string& name) } +Array* +Patch::build_ports_array() const +{ + assert(ThreadManager::current_thread_id() == THREAD_PRE_PROCESS); + + Array* const result = new Array(_input_ports.size() + _output_ports.size()); + + size_t i = 0; + + for (List::const_iterator p = _input_ports.begin(); p != _input_ports.end(); ++p,++i) + result->at(i) = *p; + + for (List::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* Patch::build_process_order() const { + assert(ThreadManager::current_thread_id() == THREAD_PRE_PROCESS); + cerr << "*********** Building process order for " << path() << endl; Array* const process_order = new Array(_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& nodes() const { return _nodes; } const List& 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) { _input_ports.push_back(port); } ///< Preprocesser thread void add_output(ListNode* port) { _output_ports.push_back(port); } ///< Preprocessor thread @@ -91,6 +93,7 @@ public: void external_ports(Array* pa) { _ports = pa; } Array* build_process_order() const; + Array* 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 #include 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(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*>(_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 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, 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, 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* _patch_node_listnode; ListNode* _patch_port_listnode; TreeNode* _store_treenode; + Array* _ports_array; ///< New (external) ports array for Patch Array* _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 -#include -#include "../../common/Queue.h" - -using std::string; using std::cerr; using std::cout; using std::endl; - - -int main() -{ - Queue 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 @@ -81,6 +81,14 @@ NodeModule::add_port(SharedPtr port, bool resize_to_fit) } +void +NodeModule::remove_port(SharedPtr port) +{ + SharedPtr p = Module::remove_port(port->path().name()); + p.reset(); +} + + void NodeModule::show_control_window() { 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 port, bool resize=true); - void remove_port(SharedPtr port) { Module::remove_port(port->path().name()); } + void remove_port(SharedPtr port); SharedPtr 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 pm) void PatchCanvas::remove_port(SharedPtr 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 canvas, SharedPtr 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 \ -- cgit v1.2.1