diff options
author | David Robillard <d@drobilla.net> | 2009-11-22 03:06:25 +0000 |
---|---|---|
committer | David Robillard <d@drobilla.net> | 2009-11-22 03:06:25 +0000 |
commit | e479da3c26d41e977cf55b8e2355db45991be09f (patch) | |
tree | f6887a9b19eaee951dafd17fea8021556bff1169 /src/engine/MessageContext.cpp | |
parent | 58807f5840592959c31b415f7e2d64967594b5ee (diff) | |
download | ingen-e479da3c26d41e977cf55b8e2355db45991be09f.tar.gz ingen-e479da3c26d41e977cf55b8e2355db45991be09f.tar.bz2 ingen-e479da3c26d41e977cf55b8e2355db45991be09f.zip |
Partial support for message/value ports and the message context.
This use case now works:
- Add an event input and the "print" plugin from imum.lv2 to ingen
- Connect the event input to the input of "print"
- Hook Ingen up to JACK and play some MIDI events
(or get events to the print plugin from anywhere else)
- The "print" plugin will print the received events to the console
in the message context (i.e. the audio thread is realtime safe)
git-svn-id: http://svn.drobilla.net/lad/trunk/ingen@2281 a436a847-0d15-0410-975c-d299462d15a1
Diffstat (limited to 'src/engine/MessageContext.cpp')
-rw-r--r-- | src/engine/MessageContext.cpp | 53 |
1 files changed, 50 insertions, 3 deletions
diff --git a/src/engine/MessageContext.cpp b/src/engine/MessageContext.cpp index ba03088d..5a180a10 100644 --- a/src/engine/MessageContext.cpp +++ b/src/engine/MessageContext.cpp @@ -24,20 +24,68 @@ #include "PatchImpl.hpp" #include "PortImpl.hpp" #include "ProcessContext.hpp" +#include "ThreadManager.hpp" using namespace std; namespace Ingen { + void MessageContext::run(NodeImpl* node) { + if (ThreadManager::current_thread_id() == THREAD_PRE_PROCESS) { + assert(node); + Glib::Mutex::Lock lock(_mutex); + _request = node; + _sem.post(); + _cond.wait(_mutex); + } else if (ThreadManager::current_thread_id() == THREAD_PROCESS) { + _requests.write(sizeof(NodeImpl*), &node); + // signal() will be called at the end of this process cycle + } else if (ThreadManager::current_thread_id() == THREAD_MESSAGE) { + cout << "Message context recursion at " << node->path() << endl; + } else { + cout << "[MessageContext] ERROR: Run requested from unknown thread" << endl; + } +} + + +void +MessageContext::_run() +{ + NodeImpl* node = NULL; + + while (true) { + _sem.wait(); + + // Run a node requested by the pre-process thread + { + Glib::Mutex::Lock lock(_mutex); + node = _request.get(); + if (node) { + _cond.broadcast(); // Notify caller we got the message + run_node(node); + } + } + + // Run nodes requested by the audio thread + while (has_requests()) { + _requests.full_read(sizeof(NodeImpl*), &node); + run_node(node); + } + } +} + + +void +MessageContext::run_node(NodeImpl* node) +{ node->message_run(*this); void* valid_ports = node->valid_ports(); PatchImpl* patch = node->parent_patch(); - //cout << "MESSAGE RUN " << node->path() << " {" << endl; for (uint32_t i = 0; i < node->num_ports(); ++i) { PortImpl* p = node->port_impl(i); if (p->is_output() && p->context() == Context::MESSAGE && @@ -47,12 +95,11 @@ MessageContext::run(NodeImpl* node) ConnectionImpl* ci = dynamic_cast<ConnectionImpl*>(c->get()); if (ci->src_port() == p) { ci->dst_port()->pre_process(*_engine.message_context()); - run(ci->dst_port()->parent_node()); + run_node(ci->dst_port()->parent_node()); } } } } - //cout << "}" << endl; node->reset_valid_ports(); } |