summaryrefslogtreecommitdiffstats
path: root/src/engine
diff options
context:
space:
mode:
authorDavid Robillard <d@drobilla.net>2011-01-08 05:20:34 +0000
committerDavid Robillard <d@drobilla.net>2011-01-08 05:20:34 +0000
commit79fceb7b387cf45deab770a12f116493a24e5350 (patch)
tree7c12f6103b4772622cf10d18039b08655d0986b3 /src/engine
parente1f6dcf7dca9363f901cd96fc389e03f4cf75e12 (diff)
downloadingen-79fceb7b387cf45deab770a12f116493a24e5350.tar.gz
ingen-79fceb7b387cf45deab770a12f116493a24e5350.tar.bz2
ingen-79fceb7b387cf45deab770a12f116493a24e5350.zip
Support "request run" feature from contexts extension.
git-svn-id: http://svn.drobilla.net/lad/trunk/ingen@2791 a436a847-0d15-0410-975c-d299462d15a1
Diffstat (limited to 'src/engine')
-rw-r--r--src/engine/ConnectionImpl.cpp2
-rw-r--r--src/engine/JackDriver.cpp2
-rw-r--r--src/engine/LV2BlobFeature.hpp2
-rw-r--r--src/engine/LV2EventFeature.hpp2
-rw-r--r--src/engine/LV2Info.cpp17
-rw-r--r--src/engine/LV2Node.cpp9
-rw-r--r--src/engine/LV2RequestRunFeature.hpp82
-rw-r--r--src/engine/LV2ResizeFeature.hpp2
-rw-r--r--src/engine/MessageContext.cpp28
-rw-r--r--src/engine/MessageContext.hpp10
-rw-r--r--src/engine/events/SetPortValue.cpp2
11 files changed, 123 insertions, 35 deletions
diff --git a/src/engine/ConnectionImpl.cpp b/src/engine/ConnectionImpl.cpp
index a69a9e05..6c899796 100644
--- a/src/engine/ConnectionImpl.cpp
+++ b/src/engine/ConnectionImpl.cpp
@@ -119,7 +119,7 @@ ConnectionImpl::queue(Context& context)
debug << endl;*/
_queue->write(sizeof(LV2_Atom) + obj->size, obj);
- context.engine().message_context()->run(_dst_port, context.start() + ev->frames);
+ context.engine().message_context()->run(_dst_port->parent_node(), context.start() + ev->frames);
}
}
diff --git a/src/engine/JackDriver.cpp b/src/engine/JackDriver.cpp
index a432e789..3e546c46 100644
--- a/src/engine/JackDriver.cpp
+++ b/src/engine/JackDriver.cpp
@@ -415,7 +415,7 @@ JackDriver::_process_cb(jack_nframes_t nframes)
// FIXME: all of this time stuff is screwy
// FIXME: support nframes != buffer_size, even though that never damn well happens
- assert(nframes == _block_length);
+ //assert(nframes == _block_length);
// Note that Jack can not call this function for a cycle, if overloaded
const jack_nframes_t start_of_current_cycle = jack_last_frame_time(_client);
diff --git a/src/engine/LV2BlobFeature.hpp b/src/engine/LV2BlobFeature.hpp
index 8d2977c1..c40dd985 100644
--- a/src/engine/LV2BlobFeature.hpp
+++ b/src/engine/LV2BlobFeature.hpp
@@ -51,7 +51,7 @@ struct BlobFeature : public Shared::LV2Features::Feature {
uint32_t type,
size_t size) {}
- SharedPtr<LV2_Feature> feature(Shared::Node*) {
+ SharedPtr<LV2_Feature> feature(Shared::World*, Shared::Node*) {
return SharedPtr<LV2_Feature>(&_feature, NullDeleter<LV2_Feature>);
}
diff --git a/src/engine/LV2EventFeature.hpp b/src/engine/LV2EventFeature.hpp
index f58ecfbb..768e583c 100644
--- a/src/engine/LV2EventFeature.hpp
+++ b/src/engine/LV2EventFeature.hpp
@@ -39,7 +39,7 @@ struct EventFeature : public Shared::LV2Features::Feature {
static uint32_t event_unref(LV2_Event_Callback_Data callback_data,
LV2_Event* event) { return 0; }
- SharedPtr<LV2_Feature> feature(Shared::Node*) {
+ SharedPtr<LV2_Feature> feature(Shared::World*, Shared::Node*) {
return SharedPtr<LV2_Feature>(&_feature, NullDeleter<LV2_Feature>);
}
diff --git a/src/engine/LV2Info.cpp b/src/engine/LV2Info.cpp
index f736dffb..e67c207d 100644
--- a/src/engine/LV2Info.cpp
+++ b/src/engine/LV2Info.cpp
@@ -16,14 +16,21 @@
*/
#define __STDC_LIMIT_MACROS 1
-#include <cassert>
+
#include <stdint.h>
+
+#include <cassert>
+
#include "lv2/lv2plug.in/ns/ext/atom/atom.h"
-#include "LV2Info.hpp"
+#include "lv2/lv2plug.in/ns/ext/contexts/contexts.h"
+
#include "module/World.hpp"
-#include "LV2Features.hpp"
-#include "LV2EventFeature.hpp"
+
#include "LV2BlobFeature.hpp"
+#include "LV2EventFeature.hpp"
+#include "LV2Features.hpp"
+#include "LV2Info.hpp"
+#include "LV2RequestRunFeature.hpp"
#include "LV2ResizeFeature.hpp"
using namespace std;
@@ -50,6 +57,8 @@ LV2Info::LV2Info(Ingen::Shared::World* world)
SharedPtr<Shared::LV2Features::Feature>(new BlobFeature()));
world->lv2_features()->add_feature(LV2_RESIZE_PORT_URI,
SharedPtr<Shared::LV2Features::Feature>(new ResizeFeature()));
+ world->lv2_features()->add_feature(LV2_CONTEXTS_URI "#RequestRunFeature",
+ SharedPtr<Shared::LV2Features::Feature>(new RequestRunFeature()));
}
LV2Info::~LV2Info()
diff --git a/src/engine/LV2Node.cpp b/src/engine/LV2Node.cpp
index 8291adf2..26ad0b77 100644
--- a/src/engine/LV2Node.cpp
+++ b/src/engine/LV2Node.cpp
@@ -149,10 +149,11 @@ LV2Node::instantiate(BufferFactory& bufs)
_ports = new Raul::Array<PortImpl*>(num_ports, NULL);
_instances = new Instances(_polyphony, SharedPtr<void>());
- _features = info->world().lv2_features()->lv2_features(this);
+ _features = info->world().lv2_features()->lv2_features(&info->world(), this);
uint32_t port_buffer_size = 0;
- SLV2Value ctx_ext_uri = slv2_value_new_uri(info->lv2_world(), LV2_CONTEXT_MESSAGE);
+ SLV2Value ctx_ext_uri = slv2_value_new_uri(info->lv2_world(),
+ LV2_CONTEXTS_URI "#MessageContext");
for (uint32_t i = 0; i < _polyphony; ++i) {
(*_instances)[i] = SharedPtr<void>(
@@ -169,7 +170,7 @@ LV2Node::instantiate(BufferFactory& bufs)
continue;
const void* ctx_ext = slv2_instance_get_extension_data(
- instance(i), LV2_CONTEXT_MESSAGE);
+ instance(i), LV2_CONTEXTS_URI "#MessageContext");
if (i == 0 && ctx_ext) {
assert(!_message_funcs);
@@ -320,7 +321,7 @@ LV2Node::instantiate(BufferFactory& bufs)
for (uint32_t i = 0; i < slv2_values_size(contexts); ++i) {
SLV2Value c = slv2_values_get_at(contexts, i);
const char* context = slv2_value_as_string(c);
- if (!strcmp(LV2_CONTEXT_MESSAGE, context)) {
+ if (!strcmp(LV2_CONTEXTS_URI "#MessageContext", context)) {
if (!_message_funcs) {
warn << _lv2_plugin->uri()
<< " has a message port, but no context extension data." << endl;
diff --git a/src/engine/LV2RequestRunFeature.hpp b/src/engine/LV2RequestRunFeature.hpp
new file mode 100644
index 00000000..40de2cfb
--- /dev/null
+++ b/src/engine/LV2RequestRunFeature.hpp
@@ -0,0 +1,82 @@
+/* This file is part of Ingen.
+ * Copyright (C) 2010 David Robillard <http://drobilla.net>
+ *
+ * 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 INGEN_ENGINE_LV2_REQUEST_RUN_FEATURE_HPP
+#define INGEN_ENGINE_LV2_REQUEST_RUN_FEATURE_HPP
+
+#include "lv2/lv2plug.in/ns/ext/contexts/contexts.h"
+
+#include "raul/log.hpp"
+
+#include "shared/LV2Features.hpp"
+
+#include "Driver.hpp"
+#include "Engine.hpp"
+#include "MessageContext.hpp"
+#include "NodeImpl.hpp"
+#include "PortImpl.hpp"
+
+using namespace std;
+using namespace Raul;
+
+namespace Ingen {
+
+struct RequestRunFeature : public Shared::LV2Features::Feature {
+ struct Data {
+ inline Data(Shared::World* w, Shared::Node* n) : world(w), node(n) {}
+ Shared::World* world;
+ Shared::Node* node;
+ };
+
+ static void request_run(LV2_Contexts_Request_Run_Data data_ptr,
+ uint32_t context_uri) {
+ Data* data = reinterpret_cast<Data*>(data_ptr);
+ if (!data->world->local_engine())
+ return;
+
+ data->world->local_engine()->message_context()->run(
+ dynamic_cast<NodeImpl*>(data->node),
+ data->world->local_engine()->driver()->frame_time());
+ }
+
+ static void delete_feature(LV2_Feature* feature) {
+ delete (Data*)feature->data;
+ free(feature);
+ }
+
+ SharedPtr<LV2_Feature> feature(Shared::World* world, Shared::Node* n) {
+ info << "REQUEST RUN FEATURE FOR NODE " << n->path() << endl;
+ NodeImpl* node = dynamic_cast<NodeImpl*>(n);
+ if (!node)
+ return SharedPtr<LV2_Feature>();
+
+ typedef LV2_Contexts_Request_Run_Feature Feature;
+ Feature* data = (Feature*)malloc(sizeof(Feature));
+ data->data = new Data(world, n);
+ data->request_run = &request_run;
+
+ LV2_Feature* f = (LV2_Feature*)malloc(sizeof(LV2_Feature));
+ f->URI = LV2_CONTEXTS_URI "#RequestRunFeature";
+ f->data = data;
+
+ return SharedPtr<LV2_Feature>(f, &delete_feature);
+ }
+};
+
+} // namespace Ingen
+
+#endif // INGEN_ENGINE_LV2_REQUEST_RUN_FEATURE_HPP
diff --git a/src/engine/LV2ResizeFeature.hpp b/src/engine/LV2ResizeFeature.hpp
index 46ca74ec..14f2237a 100644
--- a/src/engine/LV2ResizeFeature.hpp
+++ b/src/engine/LV2ResizeFeature.hpp
@@ -51,7 +51,7 @@ struct ResizeFeature : public Shared::LV2Features::Feature {
free(feature);
}
- SharedPtr<LV2_Feature> feature(Shared::Node* n) {
+ SharedPtr<LV2_Feature> feature(Shared::World* w, Shared::Node* n) {
NodeImpl* node = dynamic_cast<NodeImpl*>(n);
if (!node)
return SharedPtr<LV2_Feature>();
diff --git a/src/engine/MessageContext.cpp b/src/engine/MessageContext.cpp
index 5a032884..541f457f 100644
--- a/src/engine/MessageContext.cpp
+++ b/src/engine/MessageContext.cpp
@@ -34,22 +34,18 @@ namespace Ingen {
void
-MessageContext::run(PortImpl* port, FrameTime time)
+MessageContext::run(NodeImpl* node, FrameTime time)
{
- if (ThreadManager::thread_is(THREAD_PRE_PROCESS)) {
- assert(port);
- Glib::Mutex::Lock lock(_mutex);
- _non_rt_request = Request(time, port);
- _sem.post();
- _cond.wait(_mutex);
- } else if (ThreadManager::thread_is(THREAD_PROCESS)) {
- Request r(time, port);
+ if (ThreadManager::thread_is(THREAD_PROCESS)) {
+ const Request r(time, node);
_requests.write(sizeof(Request), &r);
// signal() will be called at the end of this process cycle
- } else if (ThreadManager::thread_is(THREAD_MESSAGE)) {
- warn << "Message context recursion at " << port->path() << endl;
} else {
- error << "Run requested from unknown thread" << endl;
+ assert(node);
+ Glib::Mutex::Lock lock(_mutex);
+ _non_rt_request = Request(time, node);
+ _sem.post();
+ _cond.wait(_mutex);
}
}
@@ -66,7 +62,7 @@ MessageContext::_run()
{
Glib::Mutex::Lock lock(_mutex);
const Request req = _non_rt_request;
- if (req.port) {
+ if (req.node) {
_queue.insert(req);
_end_time = std::max(_end_time, req.time);
_cond.broadcast(); // Notify caller we got the message
@@ -76,7 +72,7 @@ MessageContext::_run()
// Enqueue (and thereby sort) requests from audio thread
while (has_requests()) {
_requests.full_read(sizeof(Request), &req);
- if (req.port) {
+ if (req.node) {
_queue.insert(req);
} else {
_end_time = req.time;
@@ -105,7 +101,7 @@ MessageContext::_run()
void
MessageContext::execute(const Request& req)
{
- NodeImpl* node = req.port->parent_node();
+ NodeImpl* node = req.node;
node->message_run(*this);
void* valid_ports = node->valid_ports();
@@ -119,7 +115,7 @@ MessageContext::execute(const Request& req)
for (PatchImpl::Connections::iterator c = wires.begin(); c != wires.end(); ++c) {
ConnectionImpl* ci = (ConnectionImpl*)c->second.get();
if (ci->src_port() == p && ci->dst_port()->context() == Context::MESSAGE) {
- _queue.insert(Request(req.time, ci->dst_port()));
+ _queue.insert(Request(req.time, ci->dst_port()->parent_node()));
}
}
}
diff --git a/src/engine/MessageContext.hpp b/src/engine/MessageContext.hpp
index a33f8836..1eb92ff5 100644
--- a/src/engine/MessageContext.hpp
+++ b/src/engine/MessageContext.hpp
@@ -31,7 +31,7 @@
namespace Ingen {
-class PortImpl;
+class NodeImpl;
/** Context of a message_run() call.
*
@@ -55,16 +55,16 @@ public:
Thread::set_context(THREAD_MESSAGE);
}
- /** Schedule a port value change at a certain time.
+ /** Schedule a message context run at a certain time.
* Safe to call from either process thread or pre-process thread.
*/
- void run(PortImpl* port, FrameTime time);
+ void run(NodeImpl* node, FrameTime time);
protected:
struct Request {
- Request(FrameTime t=0, PortImpl* p=0) : time(t), port(p) {}
+ Request(FrameTime t=0, NodeImpl* n=0) : time(t), node(n) {}
FrameTime time;
- PortImpl* port;
+ NodeImpl* node;
};
public:
diff --git a/src/engine/events/SetPortValue.cpp b/src/engine/events/SetPortValue.cpp
index 86623888..a0c432c4 100644
--- a/src/engine/events/SetPortValue.cpp
+++ b/src/engine/events/SetPortValue.cpp
@@ -96,7 +96,7 @@ SetPortValue::pre_process()
if (_port && _port->context() == Context::MESSAGE) {
apply(*_engine.message_context());
_port->parent_node()->set_port_valid(_port->index());
- _engine.message_context()->run(_port,
+ _engine.message_context()->run(_port->parent_node(),
_engine.driver()->frame_time() + _engine.driver()->block_length());
}