summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/engine/CompiledPatch.hpp22
-rw-r--r--src/engine/PatchImpl.cpp18
2 files changed, 23 insertions, 17 deletions
diff --git a/src/engine/CompiledPatch.hpp b/src/engine/CompiledPatch.hpp
index 7cb713e2..f2c99562 100644
--- a/src/engine/CompiledPatch.hpp
+++ b/src/engine/CompiledPatch.hpp
@@ -25,6 +25,7 @@
namespace Ingen {
+class ConnectionImpl;
/** All information required about a node to execute it in an audio thread.
*/
@@ -51,23 +52,22 @@ private:
};
-/** A patch and a set of connections, "compiled" into a flat structure with
- * the correct order so the audio thread(s) can execute it without
- * threading problems (since the preprocessor thread fiddles with other
- * things).
- *
- * Currently objects still have some 'heavyweight' connection state, but
- * eventually this should be the only place a particular set of connections
- * in a patch is stored, so various "connection presets" can be switched
- * in a realtime safe way.
+/** A patch ``compiled'' into a flat structure with the correct order so
+ * the audio thread(s) can execute it without threading problems (since
+ * the preprocessor thread modifies the graph).
*
* The nodes contained here are sorted in the order they must be executed.
* The parallel processing algorithm guarantees no node will be executed
- * before it's providers, using this order as well as semaphores.
+ * before its providers, using this order as well as semaphores.
*/
struct CompiledPatch : public std::vector<CompiledNode>
, public Raul::Deletable
- , public boost::noncopyable {
+ , public boost::noncopyable
+{
+ typedef std::vector<ConnectionImpl*> QueuedConnections;
+
+ /** All (audio context => other context) connections */
+ std::vector<ConnectionImpl*> queued_connections;
};
diff --git a/src/engine/PatchImpl.cpp b/src/engine/PatchImpl.cpp
index 6b31532a..7ee82803 100644
--- a/src/engine/PatchImpl.cpp
+++ b/src/engine/PatchImpl.cpp
@@ -172,12 +172,9 @@ PatchImpl::process(ProcessContext& context)
}
// Queue any cross-context connections
- for (Connections::iterator i = _connections.begin(); i != _connections.end(); ++i) {
- ConnectionImpl* const c = (ConnectionImpl*)i->get();
- if (c->src_port()->context() == Context::AUDIO &&
- c->dst_port()->context() == Context::MESSAGE) {
- c->queue(context);
- }
+ for (CompiledPatch::QueuedConnections::iterator i = _compiled_patch->queued_connections.begin();
+ i != _compiled_patch->queued_connections.end(); ++i) {
+ (*i)->queue(context);
}
NodeImpl::post_process(context);
@@ -480,6 +477,15 @@ PatchImpl::compile() const
compile_recursive(node, compiled_patch);
}
+ // Add any queued connections that must be run after a cycle
+ for (Connections::const_iterator i = _connections.begin(); i != _connections.end(); ++i) {
+ ConnectionImpl* const c = (ConnectionImpl*)i->get();
+ if (c->src_port()->context() == Context::AUDIO &&
+ c->dst_port()->context() == Context::MESSAGE) {
+ compiled_patch->queued_connections.push_back(c);
+ }
+ }
+
assert(compiled_patch->size() == _nodes.size());
return compiled_patch;