summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorDavid Robillard <d@drobilla.net>2010-03-06 10:23:19 +0000
committerDavid Robillard <d@drobilla.net>2010-03-06 10:23:19 +0000
commit059f20c9666234f2be01498ee04f1e7ee795ba8f (patch)
treeef0d53073d53012aeaa7d084fccf477b166c0684 /src
parent085a451dfec54126be1b9346899c81d82e6eb58e (diff)
downloadingen-059f20c9666234f2be01498ee04f1e7ee795ba8f.tar.gz
ingen-059f20c9666234f2be01498ee04f1e7ee795ba8f.tar.bz2
ingen-059f20c9666234f2be01498ee04f1e7ee795ba8f.zip
Save Ingen patches as working standard LV2 plugin bundles.
This allows you to create an Ingen patch in Ingen running as a Jack client, save it, then load that patch as an LV2 plugin in any LV2 compliant host. Eliminate (hopefully) all static data in the engine (for multiple instantiations in a single process). More API/ABI stable interface for Ingen::Shared::World. git-svn-id: http://svn.drobilla.net/lad/trunk/ingen@2533 a436a847-0d15-0410-975c-d299462d15a1
Diffstat (limited to 'src')
-rw-r--r--src/bindings/ingen_bindings.cpp4
-rw-r--r--src/client/ClientStore.cpp26
-rw-r--r--src/client/ClientStore.hpp8
-rw-r--r--src/client/DeprecatedLoader.cpp58
-rw-r--r--src/client/DeprecatedLoader.hpp11
-rw-r--r--src/client/HTTPClientReceiver.cpp10
-rw-r--r--src/client/HTTPEngineSender.cpp4
-rw-r--r--src/client/HTTPEngineSender.hpp2
-rw-r--r--src/client/NodeModel.cpp13
-rw-r--r--src/client/NodeModel.hpp19
-rw-r--r--src/client/ObjectModel.cpp8
-rw-r--r--src/client/ObjectModel.hpp10
-rw-r--r--src/client/PatchModel.cpp6
-rw-r--r--src/client/PatchModel.hpp4
-rw-r--r--src/client/PluginModel.cpp7
-rw-r--r--src/client/PluginModel.hpp4
-rw-r--r--src/client/PluginUI.cpp20
-rw-r--r--src/client/PortModel.cpp17
-rw-r--r--src/client/PortModel.hpp7
-rw-r--r--src/common/interface/Node.hpp1
-rw-r--r--src/engine/BufferFactory.cpp32
-rw-r--r--src/engine/BufferFactory.hpp9
-rw-r--r--src/engine/ClientBroadcaster.hpp1
-rw-r--r--src/engine/ConnectionImpl.cpp2
-rw-r--r--src/engine/Context.hpp1
-rw-r--r--src/engine/ControlBindings.cpp24
-rw-r--r--src/engine/ControlBindings.hpp7
-rw-r--r--src/engine/Driver.hpp8
-rw-r--r--src/engine/DuplexPort.cpp2
-rw-r--r--src/engine/Engine.cpp37
-rw-r--r--src/engine/Engine.hpp30
-rw-r--r--src/engine/EventSource.cpp1
-rw-r--r--src/engine/GraphObjectImpl.cpp7
-rw-r--r--src/engine/GraphObjectImpl.hpp5
-rw-r--r--src/engine/HTTPClientSender.cpp6
-rw-r--r--src/engine/HTTPEngineReceiver.cpp10
-rw-r--r--src/engine/InputPort.cpp6
-rw-r--r--src/engine/InternalPlugin.cpp15
-rw-r--r--src/engine/InternalPlugin.hpp7
-rw-r--r--src/engine/JackDriver.cpp21
-rw-r--r--src/engine/JackDriver.hpp2
-rw-r--r--src/engine/LADSPANode.cpp2
-rw-r--r--src/engine/LADSPAPlugin.cpp6
-rw-r--r--src/engine/LADSPAPlugin.hpp12
-rw-r--r--src/engine/LV2Info.cpp20
-rw-r--r--src/engine/LV2Info.hpp2
-rw-r--r--src/engine/LV2Node.cpp8
-rw-r--r--src/engine/LV2Plugin.cpp7
-rw-r--r--src/engine/MessageContext.cpp6
-rw-r--r--src/engine/NodeFactory.cpp37
-rw-r--r--src/engine/NodeImpl.cpp2
-rw-r--r--src/engine/ObjectSender.cpp4
-rw-r--r--src/engine/OutputPort.cpp4
-rw-r--r--src/engine/PatchImpl.cpp9
-rw-r--r--src/engine/PatchPlugin.hpp10
-rw-r--r--src/engine/PluginImpl.hpp7
-rw-r--r--src/engine/PortImpl.cpp12
-rw-r--r--src/engine/PortImpl.hpp2
-rw-r--r--src/engine/QueuedEngineInterface.cpp2
-rw-r--r--src/engine/ThreadManager.hpp8
-rw-r--r--src/engine/events/CreateNode.cpp4
-rw-r--r--src/engine/events/CreatePatch.cpp2
-rw-r--r--src/engine/events/CreatePort.cpp2
-rw-r--r--src/engine/events/Delete.cpp14
-rw-r--r--src/engine/events/Delete.hpp3
-rw-r--r--src/engine/events/RequestMetadata.cpp6
-rw-r--r--src/engine/events/SendBinding.cpp2
-rw-r--r--src/engine/events/SendPortValue.cpp2
-rw-r--r--src/engine/events/SetMetadata.cpp4
-rw-r--r--src/engine/events/SetPortValue.cpp12
-rw-r--r--src/engine/ingen_engine.cpp12
-rw-r--r--src/engine/ingen_http.cpp6
-rw-r--r--src/engine/ingen_jack.cpp8
-rw-r--r--src/engine/ingen_lv2.cpp369
-rw-r--r--src/engine/ingen_osc.cpp6
-rw-r--r--src/engine/internals/Controller.cpp21
-rw-r--r--src/engine/internals/Controller.hpp10
-rw-r--r--src/engine/internals/Delay.cpp18
-rw-r--r--src/engine/internals/Delay.hpp11
-rw-r--r--src/engine/internals/Note.cpp21
-rw-r--r--src/engine/internals/Note.hpp11
-rw-r--r--src/engine/internals/Trigger.cpp18
-rw-r--r--src/engine/internals/Trigger.hpp10
-rw-r--r--src/engine/wscript38
-rw-r--r--src/gui/App.cpp28
-rw-r--r--src/gui/App.hpp12
-rw-r--r--src/gui/ConnectWindow.cpp26
-rw-r--r--src/gui/LoadRemotePatchWindow.cpp6
-rw-r--r--src/gui/NodeModule.cpp2
-rw-r--r--src/gui/PatchCanvas.cpp7
-rw-r--r--src/gui/Port.cpp5
-rw-r--r--src/gui/PropertiesWindow.cpp5
-rw-r--r--src/gui/ThreadedLoader.cpp16
-rw-r--r--src/gui/ThreadedLoader.hpp2
-rw-r--r--src/ingen/main.cpp88
-rw-r--r--src/module/World.cpp141
-rw-r--r--src/module/World.hpp68
-rw-r--r--src/module/ingen_module.cpp38
-rw-r--r--src/module/ingen_module.hpp6
-rw-r--r--src/serialisation/Parser.cpp148
-rw-r--r--src/serialisation/Parser.hpp13
-rw-r--r--src/serialisation/Serialiser.cpp55
-rw-r--r--src/serialisation/serialisation.cpp8
-rw-r--r--src/shared/Builder.cpp7
-rw-r--r--src/shared/Builder.hpp8
-rw-r--r--src/shared/LV2Features.cpp1
-rw-r--r--src/shared/LV2Object.cpp8
-rw-r--r--src/shared/LV2Object.hpp5
-rw-r--r--src/shared/LV2URIMap.cpp22
-rw-r--r--src/shared/LV2URIMap.hpp5
-rw-r--r--src/shared/ResourceImpl.cpp8
-rw-r--r--src/shared/ResourceImpl.hpp11
-rw-r--r--src/shared/runtime_paths.cpp33
-rw-r--r--src/shared/runtime_paths.hpp2
-rw-r--r--src/shared/wscript1
115 files changed, 1251 insertions, 776 deletions
diff --git a/src/bindings/ingen_bindings.cpp b/src/bindings/ingen_bindings.cpp
index 913416c8..a16890cd 100644
--- a/src/bindings/ingen_bindings.cpp
+++ b/src/bindings/ingen_bindings.cpp
@@ -43,8 +43,8 @@ ingen_module_load() {
void
script_iteration(Ingen::Shared::World* world)
{
- if (world->local_engine)
- world->local_engine->main_iteration();
+ if (world->local_engine())
+ world->local_engine()->main_iteration();
}
} // extern "C"
diff --git a/src/client/ClientStore.cpp b/src/client/ClientStore.cpp
index fd73c4b5..82c87e1e 100644
--- a/src/client/ClientStore.cpp
+++ b/src/client/ClientStore.cpp
@@ -37,8 +37,10 @@ using namespace Shared;
namespace Client {
-ClientStore::ClientStore(SharedPtr<EngineInterface> engine, SharedPtr<SigClientInterface> emitter)
- : _engine(engine)
+ClientStore::ClientStore(SharedPtr<Shared::LV2URIMap> uris,
+ SharedPtr<EngineInterface> engine, SharedPtr<SigClientInterface> emitter)
+ : _uris(uris)
+ , _engine(engine)
, _emitter(emitter)
, _plugins(new Plugins())
{
@@ -257,14 +259,12 @@ ClientStore::put(const URI& uri, const Resource::Properties& properties)
bool is_path = Path::is_valid(uri.str());
bool is_meta = ResourceImpl::is_meta_uri(uri);
- const LV2URIMap& uris = Shared::LV2URIMap::instance();
-
if (!(is_path || is_meta)) {
- const Atom& type = properties.find(uris.rdf_type)->second;
+ const Atom& type = properties.find(_uris->rdf_type)->second;
if (type.type() == Atom::URI) {
const URI& type_uri = type.get_uri();
if (Plugin::type_from_uri(type_uri) != Plugin::NIL) {
- SharedPtr<PluginModel> p(new PluginModel(uri, type_uri, properties));
+ SharedPtr<PluginModel> p(new PluginModel(uris(), uri, type_uri, properties));
add_plugin(p);
return;
}
@@ -289,24 +289,24 @@ ClientStore::put(const URI& uri, const Resource::Properties& properties)
bool is_patch, is_node, is_port, is_output;
PortType data_type(PortType::UNKNOWN);
- ResourceImpl::type(properties, is_patch, is_node, is_port, is_output, data_type);
+ ResourceImpl::type(uris(), properties, is_patch, is_node, is_port, is_output, data_type);
if (is_patch) {
- SharedPtr<PatchModel> model(new PatchModel(path));
+ SharedPtr<PatchModel> model(new PatchModel(uris(), path));
model->set_properties(properties);
add_object(model);
} else if (is_node) {
- const Resource::Properties::const_iterator p = properties.find(uris.rdf_instanceOf);
+ const Resource::Properties::const_iterator p = properties.find(_uris->rdf_instanceOf);
SharedPtr<PluginModel> plug;
if (p->second.is_valid() && p->second.type() == Atom::URI) {
if (!(plug = plugin(p->second.get_uri()))) {
LOG(warn) << "Unable to find plugin " << p->second.get_uri() << endl;
plug = SharedPtr<PluginModel>(
- new PluginModel(p->second.get_uri(), uris.ingen_nil, Resource::Properties()));
+ new PluginModel(uris(), p->second.get_uri(), _uris->ingen_nil, Resource::Properties()));
add_plugin(plug);
}
- SharedPtr<NodeModel> n(new NodeModel(plug, path));
+ SharedPtr<NodeModel> n(new NodeModel(uris(), plug, path));
n->set_properties(properties);
add_object(n);
} else {
@@ -315,9 +315,9 @@ ClientStore::put(const URI& uri, const Resource::Properties& properties)
} else if (is_port) {
if (data_type != PortType::UNKNOWN) {
PortModel::Direction pdir = is_output ? PortModel::OUTPUT : PortModel::INPUT;
- const Resource::Properties::const_iterator i = properties.find(uris.lv2_index);
+ const Resource::Properties::const_iterator i = properties.find(_uris->lv2_index);
if (i != properties.end() && i->second.type() == Atom::INT) {
- SharedPtr<PortModel> p(new PortModel(path, i->second.get_int32(), data_type, pdir));
+ SharedPtr<PortModel> p(new PortModel(uris(), path, i->second.get_int32(), data_type, pdir));
p->set_properties(properties);
add_object(p);
} else {
diff --git a/src/client/ClientStore.hpp b/src/client/ClientStore.hpp
index 35dabdcf..ac77e6ab 100644
--- a/src/client/ClientStore.hpp
+++ b/src/client/ClientStore.hpp
@@ -52,8 +52,9 @@ class ConnectionModel;
*/
class ClientStore : public Shared::Store, public Shared::CommonInterface, public sigc::trackable {
public:
- ClientStore(SharedPtr<Shared::EngineInterface> engine=SharedPtr<Shared::EngineInterface>(),
- SharedPtr<SigClientInterface> emitter=SharedPtr<SigClientInterface>());
+ ClientStore(SharedPtr<Shared::LV2URIMap> uris,
+ SharedPtr<Shared::EngineInterface> engine=SharedPtr<Shared::EngineInterface>(),
+ SharedPtr<SigClientInterface> emitter=SharedPtr<SigClientInterface>());
SharedPtr<PluginModel> plugin(const Raul::URI& uri);
SharedPtr<ObjectModel> object(const Raul::Path& path);
@@ -66,6 +67,8 @@ public:
SharedPtr<Plugins> plugins() { return _plugins; }
void set_plugins(SharedPtr<Plugins> p) { _plugins = p; }
+ Shared::LV2URIMap& uris() { return *_uris.get(); }
+
// CommonInterface
bool new_object(const Shared::GraphObject* object);
void put(const Raul::URI& path, const Shared::Resource::Properties& properties);
@@ -99,6 +102,7 @@ private:
bool attempt_connection(const Raul::Path& src_port_path, const Raul::Path& dst_port_path);
+ SharedPtr<Shared::LV2URIMap> _uris;
SharedPtr<Shared::EngineInterface> _engine;
SharedPtr<SigClientInterface> _emitter;
diff --git a/src/client/DeprecatedLoader.cpp b/src/client/DeprecatedLoader.cpp
index ac71a32d..a9c7f895 100644
--- a/src/client/DeprecatedLoader.cpp
+++ b/src/client/DeprecatedLoader.cpp
@@ -212,15 +212,13 @@ DeprecatedLoader::load_patch(const Glib::ustring& filename,
size_t poly = 0;
- const LV2URIMap& uris = Shared::LV2URIMap::instance();
-
/* Use parameter overridden polyphony, if given */
- GraphObject::Properties::iterator poly_param = initial_data.find(uris.ingen_polyphony);
+ GraphObject::Properties::iterator poly_param = initial_data.find(_uris->ingen_polyphony);
if (poly_param != initial_data.end() && poly_param->second.type() == Atom::INT)
poly = poly_param->second.get_int32();
- if (initial_data.find(uris.ingen_document) == initial_data.end())
- initial_data.insert(make_pair(uris.ingen_document, filename));
+ if (initial_data.find(_uris->ingen_document) == initial_data.end())
+ initial_data.insert(make_pair(_uris->ingen_document, filename));
xmlDocPtr doc = xmlParseFile(filename.c_str());
@@ -284,8 +282,8 @@ DeprecatedLoader::load_patch(const Glib::ustring& filename,
// Create it, if we're not merging
if (!existing && !path.is_root()) {
Resource::Properties props;
- props.insert(make_pair(uris.rdf_type, uris.ingen_Patch));
- props.insert(make_pair(uris.ingen_polyphony, Atom((int32_t)poly)));
+ props.insert(make_pair(_uris->rdf_type, _uris->ingen_Patch));
+ props.insert(make_pair(_uris->ingen_polyphony, Atom((int32_t)poly)));
_engine->put(path, props);
for (GraphObject::Properties::const_iterator i = initial_data.begin(); i != initial_data.end(); ++i)
_engine->set_property(path, i->first, i->second);
@@ -330,7 +328,7 @@ DeprecatedLoader::load_patch(const Glib::ustring& filename,
for ( ; i != pm->controls().end(); ++i) {
const float value = i->value();
_engine->set_property(translate_load_path(i->port_path().str()),
- uris.ingen_value, Atom(value));
+ _uris->ingen_value, Atom(value));
}
} else {
LOG(warn) << "Unknown preset `" << pm->name() << "'" << endl;
@@ -347,7 +345,7 @@ DeprecatedLoader::load_patch(const Glib::ustring& filename,
// _engine->set_property(subject, i->first, i->second);
if (!existing)
- _engine->set_property(path, uris.ingen_enabled, (bool)true);
+ _engine->set_property(path, _uris->ingen_enabled, (bool)true);
_load_path_translations.clear();
@@ -439,8 +437,6 @@ DeprecatedLoader::load_node(const Path& parent, xmlDocPtr doc, const xmlNodePtr
return false;
}
- const LV2URIMap& uris = Shared::LV2URIMap::instance();
-
// Compatibility hacks for old patches that represent patch ports as nodes
if (plugin_uri.empty()) {
bool is_port = false;
@@ -450,23 +446,23 @@ DeprecatedLoader::load_node(const Path& parent, xmlDocPtr doc, const xmlNodePtr
if (plugin_type == "Internal") {
is_port = true;
if (plugin_label == "audio_input") {
- props.insert(make_pair(uris.rdf_type, uris.lv2_AudioPort));
- props.insert(make_pair(uris.rdf_type, uris.lv2_InputPort));
+ props.insert(make_pair(_uris->rdf_type, _uris->lv2_AudioPort));
+ props.insert(make_pair(_uris->rdf_type, _uris->lv2_InputPort));
} else if (plugin_label == "audio_output") {
- props.insert(make_pair(uris.rdf_type, uris.lv2_AudioPort));
- props.insert(make_pair(uris.rdf_type, uris.lv2_OutputPort));
+ props.insert(make_pair(_uris->rdf_type, _uris->lv2_AudioPort));
+ props.insert(make_pair(_uris->rdf_type, _uris->lv2_OutputPort));
} else if (plugin_label == "control_input") {
- props.insert(make_pair(uris.rdf_type, uris.lv2_ControlPort));
- props.insert(make_pair(uris.rdf_type, uris.lv2_InputPort));
+ props.insert(make_pair(_uris->rdf_type, _uris->lv2_ControlPort));
+ props.insert(make_pair(_uris->rdf_type, _uris->lv2_InputPort));
} else if (plugin_label == "control_output" ) {
- props.insert(make_pair(uris.rdf_type, uris.lv2_ControlPort));
- props.insert(make_pair(uris.rdf_type, uris.lv2_OutputPort));
+ props.insert(make_pair(_uris->rdf_type, _uris->lv2_ControlPort));
+ props.insert(make_pair(_uris->rdf_type, _uris->lv2_OutputPort));
} else if (plugin_label == "midi_input") {
- props.insert(make_pair(uris.rdf_type, uris.lv2ev_EventPort));
- props.insert(make_pair(uris.rdf_type, uris.lv2_InputPort));
+ props.insert(make_pair(_uris->rdf_type, _uris->lv2ev_EventPort));
+ props.insert(make_pair(_uris->rdf_type, _uris->lv2_InputPort));
} else if (plugin_label == "midi_output" ) {
- props.insert(make_pair(uris.rdf_type, uris.lv2ev_EventPort));
- props.insert(make_pair(uris.rdf_type, uris.lv2_OutputPort));
+ props.insert(make_pair(_uris->rdf_type, _uris->lv2ev_EventPort));
+ props.insert(make_pair(_uris->rdf_type, _uris->lv2_OutputPort));
} else {
is_port = false;
}
@@ -523,11 +519,11 @@ DeprecatedLoader::load_node(const Path& parent, xmlDocPtr doc, const xmlNodePtr
plugin_uri = "om:" + plugin_type + ":" + library_name + ":" + plugin_label;
Resource::Properties props;
- props.insert(make_pair(uris.rdf_type, uris.ingen_Node));
- props.insert(make_pair(uris.rdf_instanceOf, Atom(Atom::URI, plugin_uri)));
+ props.insert(make_pair(_uris->rdf_type, _uris->ingen_Node));
+ props.insert(make_pair(_uris->rdf_instanceOf, Atom(Atom::URI, plugin_uri)));
_engine->put(path, props);
- _engine->set_property(path, uris.ingen_polyphonic, bool(polyphonic));
+ _engine->set_property(path, _uris->ingen_polyphonic, bool(polyphonic));
for (GraphObject::Properties::const_iterator i = initial_data.begin(); i != initial_data.end(); ++i)
_engine->set_property(path, i->first, i->second);
@@ -538,10 +534,10 @@ DeprecatedLoader::load_node(const Path& parent, xmlDocPtr doc, const xmlNodePtr
// Not deprecated
} else {
Resource::Properties props;
- props.insert(make_pair(uris.rdf_type, uris.ingen_Node));
- props.insert(make_pair(uris.rdf_instanceOf, Atom(Atom::URI, plugin_uri)));
+ props.insert(make_pair(_uris->rdf_type, _uris->ingen_Node));
+ props.insert(make_pair(_uris->rdf_instanceOf, Atom(Atom::URI, plugin_uri)));
_engine->put(path, props);
- _engine->set_property(path, uris.ingen_polyphonic, bool(polyphonic));
+ _engine->set_property(path, _uris->ingen_polyphonic, bool(polyphonic));
for (GraphObject::Properties::const_iterator i = initial_data.begin(); i != initial_data.end(); ++i)
_engine->set_property(path, i->first, i->second);
return true;
@@ -562,15 +558,13 @@ DeprecatedLoader::load_subpatch(const string& base_filename, const Path& parent,
size_t poly = 0;
GraphObject::Properties initial_data;
- const LV2URIMap& uris = Shared::LV2URIMap::instance();
-
while (cur != NULL) {
key = xmlNodeListGetString(doc, cur->xmlChildrenNode, 1);
if ((!xmlStrcmp(cur->name, (const xmlChar*)"name"))) {
name = (const char*)key;
} else if ((!xmlStrcmp(cur->name, (const xmlChar*)"polyphony"))) {
- initial_data.insert(make_pair(uris.ingen_polyphony, (int)poly));
+ initial_data.insert(make_pair(_uris->ingen_polyphony, (int)poly));
} else if ((!xmlStrcmp(cur->name, (const xmlChar*)"filename"))) {
filename = Glib::build_filename(base_filename, (const char*)key);
} else { // Don't know what this tag is, add it as variable
diff --git a/src/client/DeprecatedLoader.hpp b/src/client/DeprecatedLoader.hpp
index 79878107..1fbb0c7e 100644
--- a/src/client/DeprecatedLoader.hpp
+++ b/src/client/DeprecatedLoader.hpp
@@ -33,6 +33,9 @@
namespace Raul { class Path; }
namespace Ingen {
+
+namespace Shared { class LV2URIMap; }
+
namespace Client {
class PresetModel; // defined in DeprecatedLoader.cpp
@@ -45,8 +48,11 @@ class PresetModel; // defined in DeprecatedLoader.cpp
class DeprecatedLoader
{
public:
- DeprecatedLoader(SharedPtr<Shared::EngineInterface> engine)
- : _engine(engine)
+ DeprecatedLoader(
+ SharedPtr<Shared::LV2URIMap> uris,
+ SharedPtr<Shared::EngineInterface> engine)
+ : _uris(uris)
+ , _engine(engine)
{
assert(_engine);
}
@@ -64,6 +70,7 @@ private:
std::string nameify_if_invalid(const std::string& name);
std::string translate_load_path(const std::string& path);
+ SharedPtr<Shared::LV2URIMap> _uris;
SharedPtr<Shared::EngineInterface> _engine;
/// Translations of paths from the loading file to actual paths (for deprecated patches)
diff --git a/src/client/HTTPClientReceiver.cpp b/src/client/HTTPClientReceiver.cpp
index 72d5a369..a85b3573 100644
--- a/src/client/HTTPClientReceiver.cpp
+++ b/src/client/HTTPClientReceiver.cpp
@@ -133,7 +133,7 @@ HTTPClientReceiver::close_session()
void
HTTPClientReceiver::update(const std::string& str)
{
- LOG(info) << _world->parser->parse_update(_world, _target.get(), str, _url);
+ LOG(info) << _world->parser()->parse_update(_world, _target.get(), str, _url);
}
void
@@ -188,7 +188,7 @@ HTTPClientReceiver::message_callback(SoupSession* session, SoupMessage* msg, voi
} else {
Glib::Mutex::Lock lock(me->_mutex);
me->_target->response_ok(0);
- me->_world->parser->parse_string(me->_world, me->_target.get(),
+ me->_world->parser()->parse_string(me->_world, me->_target.get(),
Glib::ustring(msg->response_body->data), me->_url);
}
@@ -198,7 +198,7 @@ HTTPClientReceiver::message_callback(SoupSession* session, SoupMessage* msg, voi
} else {
Glib::Mutex::Lock lock(me->_mutex);
me->_target->response_ok(0);
- me->_world->parser->parse_string(me->_world, me->_target.get(),
+ me->_world->parser()->parse_string(me->_world, me->_target.get(),
Glib::ustring(msg->response_body->data),
Glib::ustring("/patch/"));
}
@@ -226,9 +226,9 @@ HTTPClientReceiver::message_callback(SoupSession* session, SoupMessage* msg, voi
void
HTTPClientReceiver::start(bool dump)
{
- Glib::Mutex::Lock lock(_world->rdf_world->mutex());
+ Glib::Mutex::Lock lock(_world->rdf_world()->mutex());
- if (!_world->parser)
+ if (!_world->parser())
_world->load("ingen_serialisation");
SoupMessage* msg = soup_message_new("GET", (_url + "/stream").c_str());
diff --git a/src/client/HTTPEngineSender.cpp b/src/client/HTTPEngineSender.cpp
index dbe89b14..7c13f839 100644
--- a/src/client/HTTPEngineSender.cpp
+++ b/src/client/HTTPEngineSender.cpp
@@ -33,8 +33,8 @@ using namespace Shared;
namespace Client {
-HTTPEngineSender::HTTPEngineSender(const World* world, const URI& engine_url)
- : _world(*world->rdf_world)
+HTTPEngineSender::HTTPEngineSender(World* world, const URI& engine_url)
+ : _world(*world->rdf_world())
, _engine_url(engine_url)
, _id(0)
, _enabled(true)
diff --git a/src/client/HTTPEngineSender.hpp b/src/client/HTTPEngineSender.hpp
index 944079de..79271852 100644
--- a/src/client/HTTPEngineSender.hpp
+++ b/src/client/HTTPEngineSender.hpp
@@ -43,7 +43,7 @@ class HTTPClientReceiver;
class HTTPEngineSender : public Shared::EngineInterface
{
public:
- HTTPEngineSender(const Shared::World* world, const Raul::URI& engine_url);
+ HTTPEngineSender(Shared::World* world, const Raul::URI& engine_url);
~HTTPEngineSender();
Raul::URI uri() const { return _engine_url; }
diff --git a/src/client/NodeModel.cpp b/src/client/NodeModel.cpp
index bed43e7a..8be906d9 100644
--- a/src/client/NodeModel.cpp
+++ b/src/client/NodeModel.cpp
@@ -30,8 +30,8 @@ namespace Ingen {
namespace Client {
-NodeModel::NodeModel(SharedPtr<PluginModel> plugin, const Path& path)
- : ObjectModel(path)
+NodeModel::NodeModel(Shared::LV2URIMap& uris, SharedPtr<PluginModel> plugin, const Path& path)
+ : ObjectModel(uris, path)
, _plugin_uri(plugin->uri())
, _plugin(plugin)
, _num_values(0)
@@ -40,8 +40,8 @@ NodeModel::NodeModel(SharedPtr<PluginModel> plugin, const Path& path)
{
}
-NodeModel::NodeModel(const URI& plugin_uri, const Path& path)
- : ObjectModel(path)
+NodeModel::NodeModel(Shared::LV2URIMap& uris, const URI& plugin_uri, const Path& path)
+ : ObjectModel(uris, path)
, _plugin_uri(plugin_uri)
, _num_values(0)
, _min_values(0)
@@ -206,14 +206,13 @@ NodeModel::default_port_value_range(SharedPtr<PortModel> port, float& min, float
void
NodeModel::port_value_range(SharedPtr<PortModel> port, float& min, float& max) const
{
- const Shared::LV2URIMap& uris = Shared::LV2URIMap::instance();
assert(port->parent().get() == this);
default_port_value_range(port, min, max);
// Possibly overriden
- const Atom& min_atom = port->get_property(uris.lv2_minimum);
- const Atom& max_atom = port->get_property(uris.lv2_maximum);
+ const Atom& min_atom = port->get_property(_uris.lv2_minimum);
+ const Atom& max_atom = port->get_property(_uris.lv2_maximum);
if (min_atom.type() == Atom::FLOAT)
min = min_atom.get_float();
if (max_atom.type() == Atom::FLOAT)
diff --git a/src/client/NodeModel.hpp b/src/client/NodeModel.hpp
index c1eb91e7..d13caf88 100644
--- a/src/client/NodeModel.hpp
+++ b/src/client/NodeModel.hpp
@@ -32,6 +32,9 @@
namespace Raul { class Path; }
namespace Ingen {
+
+namespace Shared { class LV2URIMap; }
+
namespace Client {
class PluginModel;
@@ -71,8 +74,8 @@ public:
protected:
friend class ClientStore;
- NodeModel(const Raul::URI& plugin_uri, const Raul::Path& path);
- NodeModel(SharedPtr<PluginModel> plugin, const Raul::Path& path);
+ NodeModel(Shared::LV2URIMap& uris, const Raul::URI& plugin_uri, const Raul::Path& path);
+ NodeModel(Shared::LV2URIMap& uris, SharedPtr<PluginModel> plugin, const Raul::Path& path);
NodeModel(const Raul::Path& path);
void add_child(SharedPtr<ObjectModel> c);
@@ -86,14 +89,14 @@ protected:
virtual void clear();
- Ports _ports; ///< Vector of ports (not a Table to preserve order)
- Raul::URI _plugin_uri; ///< Plugin URI (if PluginModel is unknown)
- SharedPtr<PluginModel> _plugin; ///< The plugin this node is an instance of
+ Ports _ports; ///< Vector of ports (not a Table to preserve order)
+ Raul::URI _plugin_uri; ///< Plugin URI (if PluginModel is unknown)
+ SharedPtr<PluginModel> _plugin; ///< The plugin this node is an instance of
private:
- mutable uint32_t _num_values; ///< Size of _min_values and _max_values
- mutable float* _min_values; ///< Port min values (cached for LV2)
- mutable float* _max_values; ///< Port max values (cached for LV2)
+ mutable uint32_t _num_values; ///< Size of _min_values and _max_values
+ mutable float* _min_values; ///< Port min values (cached for LV2)
+ mutable float* _max_values; ///< Port max values (cached for LV2)
};
diff --git a/src/client/ObjectModel.cpp b/src/client/ObjectModel.cpp
index a2423ab8..c449bf12 100644
--- a/src/client/ObjectModel.cpp
+++ b/src/client/ObjectModel.cpp
@@ -27,9 +27,9 @@ namespace Ingen {
namespace Client {
-ObjectModel::ObjectModel(const Path& path)
- : ResourceImpl(path)
- , _meta(ResourceImpl::meta_uri(path))
+ObjectModel::ObjectModel(Shared::LV2URIMap& uris, const Raul::Path& path)
+ : ResourceImpl(uris, path)
+ , _meta(uris, ResourceImpl::meta_uri(path))
, _path(path)
, _symbol((path == Path::root()) ? "root" : path.symbol())
{
@@ -76,7 +76,7 @@ ObjectModel::get_property(const Raul::URI& key) const
bool
ObjectModel::polyphonic() const
{
- const Raul::Atom& polyphonic = get_property(Shared::LV2URIMap::instance().ingen_polyphonic);
+ const Raul::Atom& polyphonic = get_property(_uris.ingen_polyphonic);
return (polyphonic.is_valid() && polyphonic.get_bool());
}
diff --git a/src/client/ObjectModel.hpp b/src/client/ObjectModel.hpp
index 2c1fd23e..0a108cb9 100644
--- a/src/client/ObjectModel.hpp
+++ b/src/client/ObjectModel.hpp
@@ -31,6 +31,9 @@
#include "shared/ResourceImpl.hpp"
namespace Ingen {
+
+namespace Shared { class LV2URIMap; }
+
namespace Client {
class ClientStore;
@@ -79,7 +82,7 @@ public:
protected:
friend class ClientStore;
- ObjectModel(const Raul::Path& path);
+ ObjectModel(Shared::LV2URIMap& uris, const Raul::Path& path);
virtual void set_path(const Raul::Path& p);
virtual void set_parent(SharedPtr<ObjectModel> p);
@@ -89,12 +92,11 @@ protected:
virtual void set(SharedPtr<ObjectModel> model);
ResourceImpl _meta;
-
SharedPtr<ObjectModel> _parent;
private:
- Raul::Path _path;
- Raul::Symbol _symbol;
+ Raul::Path _path;
+ Raul::Symbol _symbol;
};
diff --git a/src/client/PatchModel.cpp b/src/client/PatchModel.cpp
index 94557bd0..e7d30665 100644
--- a/src/client/PatchModel.cpp
+++ b/src/client/PatchModel.cpp
@@ -160,7 +160,7 @@ PatchModel::remove_connection(const Shared::Port* src_port, const Shared::Port*
bool
PatchModel::enabled() const
{
- const Raul::Atom& enabled = get_property(Shared::LV2URIMap::instance().ingen_enabled);
+ const Raul::Atom& enabled = get_property(_uris.ingen_enabled);
return (enabled.is_valid() && enabled.get_bool());
}
@@ -168,7 +168,7 @@ PatchModel::enabled() const
uint32_t
PatchModel::internal_poly() const
{
- const Raul::Atom& poly = get_property(Shared::LV2URIMap::instance().ingen_polyphony);
+ const Raul::Atom& poly = get_property(_uris.ingen_polyphony);
return poly.is_valid() ? poly.get_int32() : 1;
}
@@ -176,7 +176,7 @@ PatchModel::internal_poly() const
bool
PatchModel::polyphonic() const
{
- const Raul::Atom& poly = get_property(Shared::LV2URIMap::instance().ingen_polyphonic);
+ const Raul::Atom& poly = get_property(_uris.ingen_polyphonic);
return poly.is_valid() && poly.get_bool();
}
diff --git a/src/client/PatchModel.hpp b/src/client/PatchModel.hpp
index e3baa3eb..d4c564d2 100644
--- a/src/client/PatchModel.hpp
+++ b/src/client/PatchModel.hpp
@@ -76,8 +76,8 @@ public:
private:
friend class ClientStore;
- PatchModel(const Raul::Path& patch_path)
- : NodeModel("http://drobilla.net/ns/ingen#Patch", patch_path)
+ PatchModel(Shared::LV2URIMap& uris, const Raul::Path& patch_path)
+ : NodeModel(uris, "http://drobilla.net/ns/ingen#Patch", patch_path)
, _connections(new Connections())
, _editable(true)
{
diff --git a/src/client/PluginModel.cpp b/src/client/PluginModel.cpp
index b50513ce..4805c2bc 100644
--- a/src/client/PluginModel.cpp
+++ b/src/client/PluginModel.cpp
@@ -40,8 +40,9 @@ SLV2Plugins PluginModel::_slv2_plugins = NULL;
Redland::World* PluginModel::_rdf_world = NULL;
-PluginModel::PluginModel(const URI& uri, const URI& type_uri, const Resource::Properties& properties)
- : ResourceImpl(uri)
+PluginModel::PluginModel(Shared::LV2URIMap& uris,
+ const URI& uri, const URI& type_uri, const Resource::Properties& properties)
+ : ResourceImpl(uris, uri)
, _type(type_from_uri(type_uri.str()))
{
add_properties(properties);
@@ -69,7 +70,7 @@ PluginModel::get_property(const URI& key) const
return val;
// No lv2:symbol from data or engine, invent one
- if (key == Shared::LV2URIMap::instance().lv2_symbol) {
+ if (key == _uris.lv2_symbol) {
const URI& uri = this->uri();
size_t last_slash = uri.find_last_of('/');
size_t last_hash = uri.find_last_of('#');
diff --git a/src/client/PluginModel.hpp b/src/client/PluginModel.hpp
index 4d54cd53..82397550 100644
--- a/src/client/PluginModel.hpp
+++ b/src/client/PluginModel.hpp
@@ -30,6 +30,9 @@
#include "shared/ResourceImpl.hpp"
namespace Ingen {
+
+namespace Shared { class LV2URIMap; }
+
namespace Client {
class PatchModel;
@@ -46,6 +49,7 @@ class PluginModel : public Ingen::Shared::Plugin
{
public:
PluginModel(
+ Shared::LV2URIMap& uris,
const Raul::URI& uri,
const Raul::URI& type_uri,
const Shared::Resource::Properties& properties);
diff --git a/src/client/PluginUI.cpp b/src/client/PluginUI.cpp
index f943e54f..b19211e6 100644
--- a/src/client/PluginUI.cpp
+++ b/src/client/PluginUI.cpp
@@ -55,7 +55,7 @@ lv2_ui_write(LV2UI_Controller controller,
SharedPtr<PortModel> port = ui->node()->ports()[port_index];
- SharedPtr<Shared::LV2URIMap> map = ui->world()->uris;
+ const Shared::LV2URIMap& uris = *ui->world()->uris().get();
// float (special case, always 0)
if (format == 0) {
@@ -63,18 +63,18 @@ lv2_ui_write(LV2UI_Controller controller,
if (*(float*)buffer == port->value().get_float())
return; // do nothing (handle stupid plugin UIs that feed back)
- ui->world()->engine->set_property(port->path(), map->ingen_value, Atom(*(float*)buffer));
+ ui->world()->engine()->set_property(port->path(), uris.ingen_value, Atom(*(float*)buffer));
- } else if (format == map->ui_format_events.id) {
+ } else if (format == uris.ui_format_events.id) {
LV2_Event_Buffer* buf = (LV2_Event_Buffer*)buffer;
LV2_Event_Iterator iter;
uint8_t* data;
lv2_event_begin(&iter, buf);
while (lv2_event_is_valid(&iter)) {
LV2_Event* const ev = lv2_event_get(&iter, &data);
- if (ev->type == map->midi_event.id) {
+ if (ev->type == uris.midi_event.id) {
// FIXME: bundle multiple events by writing an entire buffer here
- ui->world()->engine->set_property(port->path(), map->ingen_value,
+ ui->world()->engine()->set_property(port->path(), uris.ingen_value,
Atom("http://lv2plug.in/ns/ext/midi#MidiEvent", ev->size, data));
} else {
warn << "Unable to send event type " << ev->type <<
@@ -84,11 +84,11 @@ lv2_ui_write(LV2UI_Controller controller,
lv2_event_increment(&iter);
}
- } else if (format == map->object_transfer.id) {
+ } else if (format == uris.object_transfer.id) {
LV2_Object* buf = (LV2_Object*)buffer;
Raul::Atom val;
- Shared::LV2Object::to_atom(buf, val);
- ui->world()->engine->set_property(port->path(), map->ingen_value, val);
+ Shared::LV2Object::to_atom(uris, buf, val);
+ ui->world()->engine()->set_property(port->path(), uris.ingen_value, val);
} else {
warn << "Unknown value format " << format
@@ -122,7 +122,7 @@ PluginUI::create(Ingen::Shared::World* world,
Glib::Mutex::Lock lock(PluginModel::rdf_world()->mutex());
SharedPtr<PluginUI> ret;
- SLV2Value gtk_gui_uri = slv2_value_new_uri(world->slv2_world,
+ SLV2Value gtk_gui_uri = slv2_value_new_uri(world->slv2_world(),
"http://lv2plug.in/ns/extensions/ui#GtkUI");
SLV2UIs uis = slv2_plugin_get_uis(plugin);
@@ -141,7 +141,7 @@ PluginUI::create(Ingen::Shared::World* world,
if (ui) {
info << "Found GTK Plugin UI: " << slv2_ui_get_uri(ui) << endl;
ret = SharedPtr<PluginUI>(new PluginUI(world, node));
- ret->_features = world->lv2_features->lv2_features(node.get());
+ ret->_features = world->lv2_features()->lv2_features(node.get());
SLV2UIInstance inst = slv2_ui_instantiate(
plugin, ui, lv2_ui_write, ret.get(), ret->_features->array());
diff --git a/src/client/PortModel.cpp b/src/client/PortModel.cpp
index e23a0e1a..80934cad 100644
--- a/src/client/PortModel.cpp
+++ b/src/client/PortModel.cpp
@@ -28,7 +28,7 @@ PortModel::set_property(const Raul::URI& uri,
const Raul::Atom& value)
{
Raul::Atom& ret = ObjectModel::set_property(uri, value);
- if (uri == Shared::LV2URIMap::instance().ingen_value)
+ if (uri == _uris.ingen_value)
this->value(value);
return ret;
}
@@ -37,14 +37,14 @@ PortModel::set_property(const Raul::URI& uri,
bool
PortModel::supports(const Raul::URI& value_type) const
{
- return has_property(Shared::LV2URIMap::instance().obj_supports, value_type);
+ return has_property(_uris.obj_supports, value_type);
}
bool
PortModel::port_property(const std::string& uri) const
{
- return has_property(Shared::LV2URIMap::instance().lv2_portProperty, Raul::URI(uri));
+ return has_property(_uris.lv2_portProperty, Raul::URI(uri));
}
@@ -65,5 +65,16 @@ PortModel::set(SharedPtr<ObjectModel> model)
}
+bool
+PortModel::has_context(const Raul::URI& uri)
+{
+ const Raul::Atom& context = get_property(_uris.ctx_context);
+ if (uri == _uris.ctx_AudioContext && !context.is_valid())
+ return true;
+ else
+ return context == uri;
+}
+
+
} // namespace Client
} // namespace Ingen
diff --git a/src/client/PortModel.hpp b/src/client/PortModel.hpp
index 02305e1a..dc864ffe 100644
--- a/src/client/PortModel.hpp
+++ b/src/client/PortModel.hpp
@@ -58,6 +58,8 @@ public:
bool is_integer() const { return port_property("http://lv2plug.in/ns/lv2core#integer"); }
bool is_toggle() const { return port_property("http://lv2plug.in/ns/lv2core#toggled"); }
+ bool has_context(const Raul::URI& context);
+
inline bool operator==(const PortModel& pm) const { return (path() == pm.path()); }
Raul::Atom& set_property(const Raul::URI& uri, const Raul::Atom& value);
@@ -84,8 +86,9 @@ public:
private:
friend class ClientStore;
- PortModel(const Raul::Path& path, uint32_t index, Shared::PortType type, Direction dir)
- : ObjectModel(path)
+ PortModel(Shared::LV2URIMap& uris,
+ const Raul::Path& path, uint32_t index, Shared::PortType type, Direction dir)
+ : ObjectModel(uris, path)
, _index(index)
, _direction(dir)
, _current_val(0.0f)
diff --git a/src/common/interface/Node.hpp b/src/common/interface/Node.hpp
index 7a1a6280..4a700a12 100644
--- a/src/common/interface/Node.hpp
+++ b/src/common/interface/Node.hpp
@@ -21,7 +21,6 @@
#include <stdint.h>
#include "GraphObject.hpp"
-#include <iostream>
namespace Ingen {
namespace Shared {
diff --git a/src/engine/BufferFactory.cpp b/src/engine/BufferFactory.cpp
index 83030c70..318a1422 100644
--- a/src/engine/BufferFactory.cpp
+++ b/src/engine/BufferFactory.cpp
@@ -32,11 +32,31 @@ namespace Ingen {
using namespace Shared;
-BufferFactory::BufferFactory(Engine& engine, SharedPtr<Shared::LV2URIMap> map)
+BufferFactory::BufferFactory(Engine& engine, SharedPtr<Shared::LV2URIMap> a_uris)
: _engine(engine)
- , _map(map)
+ , _uris(a_uris)
, _silent_buffer(NULL)
{
+ assert(_uris);
+}
+
+
+BufferFactory::~BufferFactory()
+{
+ free_list(_free_audio.get());
+ free_list(_free_control.get());
+ free_list(_free_event.get());
+ free_list(_free_object.get());
+}
+
+
+void
+BufferFactory::free_list(Buffer* head)
+{
+ Buffer* next = head->_next;
+ delete head;
+ if (next)
+ free_list(next);
}
@@ -87,7 +107,7 @@ BufferFactory::get(Shared::PortType type, size_t size, bool force_create)
}
if (!try_head) {
- if (ThreadManager::current_thread_id() != THREAD_PROCESS) {
+ if (!ThreadManager::thread_is(THREAD_PROCESS)) {
return create(type, size);
} else {
assert(false);
@@ -113,12 +133,12 @@ BufferFactory::create(Shared::PortType type, size_t size)
if (type.is_control()) {
AudioBuffer* ret = new AudioBuffer(*this, type, size);
- ret->object()->type = _map->object_class_vector.id;
- ((LV2_Vector_Body*)ret->object()->body)->elem_type = _map->object_class_float32.id;
+ ret->object()->type = _uris->object_class_vector.id;
+ ((LV2_Vector_Body*)ret->object()->body)->elem_type = _uris->object_class_float32.id;
buffer = ret;
} else if (type.is_audio()) {
AudioBuffer* ret = new AudioBuffer(*this, type, size);
- ret->object()->type = _map->object_class_float32.id;
+ ret->object()->type = _uris->object_class_float32.id;
buffer = ret;
} else if (type.is_events()) {
buffer = new EventBuffer(*this, size);
diff --git a/src/engine/BufferFactory.hpp b/src/engine/BufferFactory.hpp
index 44213c52..344b946d 100644
--- a/src/engine/BufferFactory.hpp
+++ b/src/engine/BufferFactory.hpp
@@ -37,7 +37,8 @@ namespace Shared { class LV2URIMap; }
class BufferFactory {
public:
- BufferFactory(Engine& engine, SharedPtr<Shared::LV2URIMap> map);
+ BufferFactory(Engine& engine, SharedPtr<Shared::LV2URIMap> uris);
+ ~BufferFactory();
typedef boost::intrusive_ptr<Buffer> Ref;
@@ -50,6 +51,8 @@ public:
void set_block_length(SampleCount block_length);
+ Shared::LV2URIMap& uris() { assert(_uris); return *_uris.get(); }
+
private:
friend class Buffer;
void recycle(Buffer* buf);
@@ -67,6 +70,8 @@ private:
}
}
+ void free_list(Buffer* head);
+
Raul::AtomicPtr<Buffer> _free_audio;
Raul::AtomicPtr<Buffer> _free_control;
Raul::AtomicPtr<Buffer> _free_event;
@@ -74,7 +79,7 @@ private:
Glib::Mutex _mutex;
Engine& _engine;
- SharedPtr<Shared::LV2URIMap> _map;
+ SharedPtr<Shared::LV2URIMap> _uris;
Ref _silent_buffer;
};
diff --git a/src/engine/ClientBroadcaster.hpp b/src/engine/ClientBroadcaster.hpp
index c72fef74..02a7fe41 100644
--- a/src/engine/ClientBroadcaster.hpp
+++ b/src/engine/ClientBroadcaster.hpp
@@ -26,7 +26,6 @@
#include "interface/ClientInterface.hpp"
#include "NodeFactory.hpp"
-#include <iostream>
using namespace std;
namespace Ingen {
diff --git a/src/engine/ConnectionImpl.cpp b/src/engine/ConnectionImpl.cpp
index 8fa770f7..495a97c2 100644
--- a/src/engine/ConnectionImpl.cpp
+++ b/src/engine/ConnectionImpl.cpp
@@ -127,7 +127,7 @@ ConnectionImpl::queue(Context& context)
bool
ConnectionImpl::can_connect(const OutputPort* src, const InputPort* dst)
{
- const LV2URIMap& uris = Shared::LV2URIMap::instance();
+ const LV2URIMap& uris = src->bufs().uris();
return (
( (src->is_a(PortType::CONTROL) || src->is_a(PortType::AUDIO))
&& (dst->is_a(PortType::CONTROL) || dst->is_a(PortType::AUDIO)))
diff --git a/src/engine/Context.hpp b/src/engine/Context.hpp
index 2a3bd7ca..6ef24346 100644
--- a/src/engine/Context.hpp
+++ b/src/engine/Context.hpp
@@ -20,6 +20,7 @@
#include "EventSink.hpp"
#include "tuning.hpp"
+#include "types.hpp"
namespace Ingen {
diff --git a/src/engine/ControlBindings.cpp b/src/engine/ControlBindings.cpp
index ead1e6ea..e861d2ed 100644
--- a/src/engine/ControlBindings.cpp
+++ b/src/engine/ControlBindings.cpp
@@ -18,6 +18,8 @@
#include <math.h>
#include "raul/log.hpp"
#include "raul/midi_events.h"
+#include "shared/LV2URIMap.hpp"
+#include "module/World.hpp"
#include "events/SendPortValue.hpp"
#include "events/SendBinding.hpp"
#include "AudioBuffer.hpp"
@@ -36,9 +38,8 @@ using namespace Raul;
namespace Ingen {
-ControlBindings::ControlBindings(Engine& engine, SharedPtr<Shared::LV2URIMap> map)
+ControlBindings::ControlBindings(Engine& engine)
: _engine(engine)
- , _map(map)
, _learn_port(NULL)
, _bindings(new Bindings())
, _feedback(new EventBuffer(*_engine.buffer_factory(), 1024)) // FIXME: size
@@ -55,8 +56,8 @@ ControlBindings::~ControlBindings()
ControlBindings::Key
ControlBindings::port_binding(PortImpl* port)
{
- const Shared::LV2URIMap& uris = Shared::LV2URIMap::instance();
- const Raul::Atom& binding = port->get_property(uris.ingen_controlBinding);
+ const Shared::LV2URIMap& uris = *_engine.world()->uris().get();
+ const Raul::Atom& binding = port->get_property(uris.ingen_controlBinding);
Key key;
if (binding.type() == Atom::DICT) {
const Atom::DictValue& dict = binding.get_dict();
@@ -114,6 +115,7 @@ ControlBindings::port_binding_changed(ProcessContext& context, PortImpl* port)
void
ControlBindings::port_value_changed(ProcessContext& context, PortImpl* port)
{
+ const Shared::LV2URIMap& uris = *_engine.world()->uris().get();
Key key = port_binding(port);
if (key) {
int16_t value = port_value_to_control(port, key.type);
@@ -150,7 +152,7 @@ ControlBindings::port_value_changed(ProcessContext& context, PortImpl* port)
break;
}
if (size > 0)
- _feedback->append(0, 0, _map->midi_event.id, size, buf);
+ _feedback->append(0, 0, uris.midi_event.id, size, buf);
}
}
@@ -166,7 +168,7 @@ ControlBindings::learn(PortImpl* port)
Raul::Atom
ControlBindings::control_to_port_value(PortImpl* port, Type type, int16_t value)
{
- const Shared::LV2URIMap& uris = Shared::LV2URIMap::instance();
+ const Shared::LV2URIMap& uris = *_engine.world()->uris().get();
// TODO: cache these to avoid the lookup
float min = port->get_property(uris.lv2_minimum).get_float();
@@ -203,7 +205,7 @@ ControlBindings::port_value_to_control(PortImpl* port, Type type)
if (port->value().type() != Atom::FLOAT)
return 0;
- const Shared::LV2URIMap& uris = Shared::LV2URIMap::instance();
+ const Shared::LV2URIMap& uris = *_engine.world()->uris().get();
// TODO: cache these to avoid the lookup
float min = port->get_property(uris.lv2_minimum).get_float();
@@ -259,7 +261,7 @@ ControlBindings::set_port_value(ProcessContext& context, PortImpl* port, Type ty
bool
ControlBindings::bind(ProcessContext& context, Key key)
{
- const Shared::LV2URIMap& uris = Shared::LV2URIMap::instance();
+ const Shared::LV2URIMap& uris = *context.engine().world()->uris().get();
assert(_learn_port);
if (key.type == MIDI_NOTE) {
bool toggled = _learn_port->has_property(uris.lv2_portProperty, uris.lv2_toggled);
@@ -336,12 +338,14 @@ ControlBindings::pre_process(ProcessContext& context, EventBuffer* buffer)
SharedPtr<Bindings> bindings = _bindings;
_feedback->clear();
+ const Shared::LV2URIMap& uris = *context.engine().world()->uris().get();
+
// Learn from input if necessary
if (_learn_port) {
for (buffer->rewind();
buffer->get_event(&frames, &subframes, &type, &size, &buf);
buffer->increment()) {
- if (type != _map->midi_event.id)
+ if (type != uris.midi_event.id)
continue;
const Key key = midi_event_key(size, buf, value);
@@ -358,7 +362,7 @@ ControlBindings::pre_process(ProcessContext& context, EventBuffer* buffer)
for (buffer->rewind();
buffer->get_event(&frames, &subframes, &type, &size, &buf);
buffer->increment()) {
- if (type != _map->midi_event.id)
+ if (type != uris.midi_event.id)
continue;
const Key key = midi_event_key(size, buf, value);
diff --git a/src/engine/ControlBindings.hpp b/src/engine/ControlBindings.hpp
index 1b684b9a..f5878908 100644
--- a/src/engine/ControlBindings.hpp
+++ b/src/engine/ControlBindings.hpp
@@ -56,7 +56,7 @@ public:
typedef std::map<Key, PortImpl*> Bindings;
- ControlBindings(Engine& engine, SharedPtr<Shared::LV2URIMap> map);
+ ControlBindings(Engine& engine);
~ControlBindings();
void learn(PortImpl* port);
@@ -88,9 +88,8 @@ private:
Raul::Atom control_to_port_value(PortImpl* port, Type type, int16_t value);
int16_t port_value_to_control(PortImpl* port, Type type);
- Engine& _engine;
- SharedPtr<Shared::LV2URIMap> _map;
- PortImpl* _learn_port;
+ Engine& _engine;
+ PortImpl* _learn_port;
SharedPtr<Bindings> _bindings;
EventBuffer* _feedback;
diff --git a/src/engine/Driver.hpp b/src/engine/Driver.hpp
index 3712b93b..35fb4997 100644
--- a/src/engine/Driver.hpp
+++ b/src/engine/Driver.hpp
@@ -77,13 +77,13 @@ public:
virtual ~Driver() {}
/** Activate driver (begin processing graph and events). */
- virtual void activate() = 0;
+ virtual void activate() {}
/** Deactivate driver (stop processing graph and events). */
- virtual void deactivate() = 0;
+ virtual void deactivate() {}
/** Return true iff driver is activated (processing graph and events). */
- virtual bool is_activated() const = 0;
+ virtual bool is_activated() const { return true; }
/** Create a port ready to be inserted with add_input (non realtime).
* May return NULL if the Driver can not create the port for some reason.
@@ -97,7 +97,7 @@ public:
virtual void add_port(DriverPort* port) = 0;
/** Remove a system visible port. */
- virtual Raul::List<DriverPort*>::Node* remove_port(const Raul::Path& path) = 0;
+ virtual Raul::Deletable* remove_port(const Raul::Path& path, Ingen::DriverPort** port=NULL) = 0;
/** Return true iff this driver supports the given type of I/O */
virtual bool supports(Shared::PortType port_type, Shared::EventType event_type) = 0;
diff --git a/src/engine/DuplexPort.cpp b/src/engine/DuplexPort.cpp
index a78da58a..da7dabf1 100644
--- a/src/engine/DuplexPort.cpp
+++ b/src/engine/DuplexPort.cpp
@@ -50,7 +50,7 @@ DuplexPort::DuplexPort(
, _is_output(is_output)
{
assert(PortImpl::_parent == parent);
- set_property(Shared::LV2URIMap::instance().ingen_polyphonic, polyphonic);
+ set_property(bufs.uris().ingen_polyphonic, polyphonic);
}
diff --git a/src/engine/Engine.cpp b/src/engine/Engine.cpp
index dd25485a..a17a58c0 100644
--- a/src/engine/Engine.cpp
+++ b/src/engine/Engine.cpp
@@ -58,22 +58,23 @@ using namespace Shared;
bool ThreadManager::single_threaded = true;
-Engine::Engine(Ingen::Shared::World* world)
- : _world(world)
+Engine::Engine(Ingen::Shared::World* a_world)
+ : _world(a_world)
, _maid(new Raul::Maid(maid_queue_size))
, _post_processor(new PostProcessor(*this, post_processor_queue_size))
, _broadcaster(new ClientBroadcaster())
- , _node_factory(new NodeFactory(world))
+ , _node_factory(new NodeFactory(a_world))
, _message_context(new MessageContext(*this))
- , _buffer_factory(new BufferFactory(*this, world->uris))
- , _control_bindings(new ControlBindings(*this, world->uris))
+ , _buffer_factory(new BufferFactory(*this, a_world->uris()))
+ //, _buffer_factory(NULL)
+ , _control_bindings(new ControlBindings(*this))
, _quit_flag(false)
, _activated(false)
{
- if (world->store) {
- assert(PtrCast<EngineStore>(world->store));
+ if (a_world->store()) {
+ assert(PtrCast<EngineStore>(a_world->store()));
} else {
- world->store = SharedPtr<Shared::Store>(new EngineStore());
+ a_world->set_store(SharedPtr<Shared::Store>(new EngineStore()));
}
}
@@ -101,7 +102,7 @@ Engine::~Engine()
SharedPtr<EngineStore>
Engine::engine_store() const
{
- return PtrCast<EngineStore>(_world->store);
+ return PtrCast<EngineStore>(_world->store());
}
@@ -137,13 +138,6 @@ Engine::main_iteration()
}
-Ingen::QueuedEngineInterface*
-Engine::new_local_interface()
-{
- return new Ingen::QueuedEngineInterface(*this, Ingen::event_queue_size);
-}
-
-
void
Engine::add_event_source(SharedPtr<EventSource> source)
{
@@ -164,18 +158,23 @@ execute_and_delete_event(ProcessContext& context, QueuedEvent* ev)
bool
Engine::activate()
{
+ if (_activated)
+ return true;
+
assert(_driver);
+ //assert(ThreadManager::single_threaded == true);
+ ThreadManager::single_threaded = true;
_buffer_factory->set_block_length(_driver->block_length());
_message_context->Thread::start();
- uint32_t parallelism = _world->conf->option("parallelism").get_int32();
+ uint32_t parallelism = _world->conf()->option("parallelism").get_int32();
for (EventSources::iterator i = _event_sources.begin(); i != _event_sources.end(); ++i)
(*i)->activate_source();
- const LV2URIMap& uris = *world()->uris;
+ const LV2URIMap& uris = *world()->uris().get();
// Create root patch
PatchImpl* root_patch = _driver->root_patch();
@@ -185,7 +184,7 @@ Engine::activate()
root_patch->meta().set_property(uris.ingen_polyphony, Raul::Atom(int32_t(1)));
root_patch->set_property(uris.rdf_type, uris.ingen_Node);
root_patch->activate(*_buffer_factory);
- _world->store->add(root_patch);
+ _world->store()->add(root_patch);
root_patch->compiled_patch(root_patch->compile());
_driver->set_root_patch(root_patch);
diff --git a/src/engine/Engine.hpp b/src/engine/Engine.hpp
index e575db50..fe5f34e6 100644
--- a/src/engine/Engine.hpp
+++ b/src/engine/Engine.hpp
@@ -61,7 +61,7 @@ class QueuedEvent;
*
* \ingroup engine
*/
-class Engine : boost::noncopyable
+class Engine : public boost::noncopyable
{
public:
Engine(Ingen::Shared::World* world);
@@ -78,32 +78,30 @@ public:
virtual bool activate();
virtual void deactivate();
- void process_events(ProcessContext& context);
+ virtual void process_events(ProcessContext& context);
virtual bool activated() { return _activated; }
- BufferFactory* buffer_factory() const { return _buffer_factory; }
- ClientBroadcaster* broadcaster() const { return _broadcaster; }
- ControlBindings* control_bindings() const { return _control_bindings; }
- Driver* driver() const { return _driver.get(); }
- MessageContext* message_context() const { return _message_context; }
- NodeFactory* node_factory() const { return _node_factory; }
- PostProcessor* post_processor() const { return _post_processor; }
- Raul::Maid* maid() const { return _maid; }
+ virtual BufferFactory* buffer_factory() const { return _buffer_factory; }
+ virtual ClientBroadcaster* broadcaster() const { return _broadcaster; }
+ virtual ControlBindings* control_bindings() const { return _control_bindings; }
+ virtual Driver* driver() const { return _driver.get(); }
+ virtual MessageContext* message_context() const { return _message_context; }
+ virtual NodeFactory* node_factory() const { return _node_factory; }
+ virtual PostProcessor* post_processor() const { return _post_processor; }
+ virtual Raul::Maid* maid() const { return _maid; }
- SharedPtr<EngineStore> engine_store() const;
+ virtual SharedPtr<EngineStore> engine_store() const;
virtual void set_driver(SharedPtr<Driver> driver) { _driver = driver; }
virtual void add_event_source(SharedPtr<EventSource> source);
- Ingen::QueuedEngineInterface* new_local_interface();
-
- Ingen::Shared::World* world() { return _world; }
+ virtual Ingen::Shared::World* world() { return _world; }
typedef std::vector<ProcessSlave*> ProcessSlaves;
- inline const ProcessSlaves& process_slaves() const { return _process_slaves; }
- inline ProcessSlaves& process_slaves() { return _process_slaves; }
+ virtual const ProcessSlaves& process_slaves() const { return _process_slaves; }
+ virtual ProcessSlaves& process_slaves() { return _process_slaves; }
private:
typedef std::set< SharedPtr<EventSource> > EventSources;
diff --git a/src/engine/EventSource.cpp b/src/engine/EventSource.cpp
index c51b580a..9e1f2741 100644
--- a/src/engine/EventSource.cpp
+++ b/src/engine/EventSource.cpp
@@ -31,7 +31,6 @@ EventSource::EventSource(size_t queue_size)
: _blocking_semaphore(0)
{
Thread::set_context(THREAD_PRE_PROCESS);
- assert(context() == THREAD_PRE_PROCESS);
set_name("EventSource");
}
diff --git a/src/engine/GraphObjectImpl.cpp b/src/engine/GraphObjectImpl.cpp
index d67755b5..3db53ba7 100644
--- a/src/engine/GraphObjectImpl.cpp
+++ b/src/engine/GraphObjectImpl.cpp
@@ -28,12 +28,13 @@ namespace Ingen {
using namespace Shared;
-GraphObjectImpl::GraphObjectImpl(GraphObjectImpl* parent, const Symbol& symbol)
- : ResourceImpl(parent ? parent->path().child(symbol) : Raul::Path::root())
+GraphObjectImpl::GraphObjectImpl(Shared::LV2URIMap& uris,
+ GraphObjectImpl* parent, const Symbol& symbol)
+ : ResourceImpl(uris, parent ? parent->path().child(symbol) : Raul::Path::root())
, _parent(parent)
, _path(parent ? parent->path().child(symbol) : "/")
, _symbol(symbol)
- , _meta(ResourceImpl::meta_uri(uri()))
+ , _meta(uris, ResourceImpl::meta_uri(uri()))
{
}
diff --git a/src/engine/GraphObjectImpl.hpp b/src/engine/GraphObjectImpl.hpp
index 854fdab1..9a9a9b73 100644
--- a/src/engine/GraphObjectImpl.hpp
+++ b/src/engine/GraphObjectImpl.hpp
@@ -32,6 +32,8 @@ namespace Raul { class Maid; }
namespace Ingen {
+namespace Shared { class LV2URIMap; }
+
class PatchImpl;
class Context;
class ProcessContext;
@@ -98,7 +100,8 @@ public:
virtual bool apply_poly(Raul::Maid& maid, uint32_t poly) = 0;
protected:
- GraphObjectImpl(GraphObjectImpl* parent, const Raul::Symbol& symbol);
+ GraphObjectImpl(Shared::LV2URIMap& uris,
+ GraphObjectImpl* parent, const Raul::Symbol& symbol);
GraphObjectImpl* _parent;
Raul::Path _path;
diff --git a/src/engine/HTTPClientSender.cpp b/src/engine/HTTPClientSender.cpp
index 20bc8ee2..338b4394 100644
--- a/src/engine/HTTPClientSender.cpp
+++ b/src/engine/HTTPClientSender.cpp
@@ -59,10 +59,10 @@ HTTPClientSender::put(const URI& uri,
const string path = (uri.substr(0, 6) == "path:/") ? uri.substr(6) : uri.str();
const string full_uri = _url + "/" + path;
- Redland::Model model(*_engine.world()->rdf_world);
+ Redland::Model model(*_engine.world()->rdf_world());
for (Resource::Properties::const_iterator i = properties.begin(); i != properties.end(); ++i)
model.add_statement(
- Redland::Resource(*_engine.world()->rdf_world, path),
+ Redland::Resource(*_engine.world()->rdf_world(), path),
i->first.str(),
AtomRDF::atom_to_node(model, i->second));
@@ -111,7 +111,7 @@ void
HTTPClientSender::set_property(const URI& subject, const URI& key, const Atom& value)
{
#if 0
- Redland::Node node = AtomRDF::atom_to_node(*_engine.world()->rdf_world, value);
+ Redland::Node node = AtomRDF::atom_to_node(*_engine.world()->rdf_world(), value);
const string msg = string(
"@prefix rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#> .\n"
"@prefix ingen: <http://drobilla.net/ns/ingen#> .\n"
diff --git a/src/engine/HTTPEngineReceiver.cpp b/src/engine/HTTPEngineReceiver.cpp
index 662b23eb..e24b9076 100644
--- a/src/engine/HTTPEngineReceiver.cpp
+++ b/src/engine/HTTPEngineReceiver.cpp
@@ -55,7 +55,7 @@ HTTPEngineReceiver::HTTPEngineReceiver(Engine& engine, uint16_t port)
LOG(info) << "Started HTTP server on port " << soup_server_get_port(_server) << endl;
- if (!engine.world()->parser || !engine.world()->serialiser)
+ if (!engine.world()->parser() || !engine.world()->serialiser())
engine.world()->load("ingen_serialisation");
Thread::set_name("HTTPEngineReceiver");
@@ -99,7 +99,7 @@ HTTPEngineReceiver::message_callback(SoupServer* server, SoupMessage* msg, const
{
HTTPEngineReceiver* me = (HTTPEngineReceiver*)data;
- SharedPtr<Store> store = me->_engine.world()->store;
+ SharedPtr<Store> store = me->_engine.world()->store();
if (!store) {
soup_message_set_status (msg, SOUP_STATUS_INTERNAL_SERVER_ERROR);
return;
@@ -110,7 +110,7 @@ HTTPEngineReceiver::message_callback(SoupServer* server, SoupMessage* msg, const
path = path.substr(0, path.length()-1);
}
- SharedPtr<Serialiser> serialiser = me->_engine.world()->serialiser;
+ SharedPtr<Serialiser> serialiser = me->_engine.world()->serialiser();
const string base_uri = "path:/";
const char* mime_type = "text/plain";
@@ -180,7 +180,7 @@ HTTPEngineReceiver::message_callback(SoupServer* server, SoupMessage* msg, const
}
// Get serialiser
- SharedPtr<Serialiser> serialiser = me->_engine.world()->serialiser;
+ SharedPtr<Serialiser> serialiser = me->_engine.world()->serialiser();
if (!serialiser) {
soup_message_set_status(msg, SOUP_STATUS_INTERNAL_SERVER_ERROR);
soup_message_set_response(msg, "text/plain", SOUP_MEMORY_STATIC,
@@ -200,7 +200,7 @@ HTTPEngineReceiver::message_callback(SoupServer* server, SoupMessage* msg, const
Glib::RWLock::WriterLock lock(store->lock());
// Get parser
- SharedPtr<Parser> parser = me->_engine.world()->parser;
+ SharedPtr<Parser> parser = me->_engine.world()->parser();
if (!parser) {
soup_message_set_status(msg, SOUP_STATUS_INTERNAL_SERVER_ERROR);
return;
diff --git a/src/engine/InputPort.cpp b/src/engine/InputPort.cpp
index 95af5725..dae9b43c 100644
--- a/src/engine/InputPort.cpp
+++ b/src/engine/InputPort.cpp
@@ -49,7 +49,7 @@ InputPort::InputPort(BufferFactory& bufs,
: PortImpl(bufs, parent, symbol, index, poly, type, value, buffer_size)
, _num_connections(0)
{
- const LV2URIMap& uris = Shared::LV2URIMap::instance();
+ const LV2URIMap& uris = bufs.uris();
if (!dynamic_cast<Patch*>(parent))
add_property(uris.rdf_type, uris.lv2_InputPort);
@@ -81,7 +81,7 @@ InputPort::apply_poly(Maid& maid, uint32_t poly)
bool
InputPort::get_buffers(BufferFactory& bufs, Raul::Array<BufferFactory::Ref>* buffers, uint32_t poly)
{
- size_t num_connections = (ThreadManager::current_thread_id() == THREAD_PROCESS)
+ size_t num_connections = (ThreadManager::thread_is(THREAD_PROCESS))
? _connections.size() : _num_connections;
if (buffer_type() == PortType::AUDIO && num_connections == 0) {
@@ -91,7 +91,7 @@ InputPort::get_buffers(BufferFactory& bufs, Raul::Array<BufferFactory::Ref>* buf
return false;
} else if (num_connections == 1) {
- if (ThreadManager::current_thread_id() == THREAD_PROCESS) {
+ if (ThreadManager::thread_is(THREAD_PROCESS)) {
if (!_connections.front()->must_mix() && !_connections.front()->must_queue()) {
// Single non-mixing conneciton, use buffers directly
for (uint32_t v = 0; v < poly; ++v)
diff --git a/src/engine/InternalPlugin.cpp b/src/engine/InternalPlugin.cpp
index 802ec955..fdb0cd96 100644
--- a/src/engine/InternalPlugin.cpp
+++ b/src/engine/InternalPlugin.cpp
@@ -32,11 +32,11 @@ namespace Ingen {
using namespace Internals;
-InternalPlugin::InternalPlugin(const std::string& uri, const std::string& symbol)
- : PluginImpl(Plugin::Internal, uri)
+InternalPlugin::InternalPlugin(Shared::LV2URIMap& uris,
+ const std::string& uri, const std::string& symbol)
+ : PluginImpl(uris, Plugin::Internal, uri)
, _symbol(symbol)
{
- const LV2URIMap& uris = Shared::LV2URIMap::instance();
set_property(uris.rdf_type, uris.ingen_Internal);
}
@@ -53,14 +53,15 @@ InternalPlugin::instantiate(BufferFactory& bufs,
const SampleCount srate = engine.driver()->sample_rate();
const string uri_str = uri().str();
+
if (uri_str == NS_INTERNALS "Controller") {
- return new ControllerNode(bufs, name, polyphonic, parent, srate);
+ return new ControllerNode(this, bufs, name, polyphonic, parent, srate);
} else if (uri_str == NS_INTERNALS "Delay") {
- return new DelayNode(bufs, name, polyphonic, parent, srate);
+ return new DelayNode(this, bufs, name, polyphonic, parent, srate);
} else if (uri_str == NS_INTERNALS "Note") {
- return new NoteNode(bufs, name, polyphonic, parent, srate);
+ return new NoteNode(this, bufs, name, polyphonic, parent, srate);
} else if (uri_str == NS_INTERNALS "Trigger") {
- return new TriggerNode(bufs, name, polyphonic, parent, srate);
+ return new TriggerNode(this, bufs, name, polyphonic, parent, srate);
} else {
return NULL;
}
diff --git a/src/engine/InternalPlugin.hpp b/src/engine/InternalPlugin.hpp
index d1c0e76e..cd2dff2d 100644
--- a/src/engine/InternalPlugin.hpp
+++ b/src/engine/InternalPlugin.hpp
@@ -20,10 +20,6 @@
#include "ingen-config.h"
-#ifndef HAVE_SLV2
-#error "This file requires SLV2, but HAVE_SLV2 is not defined. Please report."
-#endif
-
#include <cstdlib>
#include <glibmm/module.h>
#include <boost/utility.hpp>
@@ -44,7 +40,8 @@ class BufferFactory;
class InternalPlugin : public PluginImpl
{
public:
- InternalPlugin(const std::string& uri, const std::string& symbol);
+ InternalPlugin(Shared::LV2URIMap& uris,
+ const std::string& uri, const std::string& symbol);
NodeImpl* instantiate(BufferFactory& bufs,
const std::string& name,
diff --git a/src/engine/JackDriver.cpp b/src/engine/JackDriver.cpp
index 6c66cba3..6e973e1f 100644
--- a/src/engine/JackDriver.cpp
+++ b/src/engine/JackDriver.cpp
@@ -192,7 +192,7 @@ JackDriver::JackDriver(Engine& engine)
, _process_context(engine)
, _root_patch(NULL)
{
- _midi_event_type = _engine.world()->uris->uri_to_id(
+ _midi_event_type = _engine.world()->uris()->uri_to_id(
NULL, "http://lv2plug.in/ns/ext/midi#MidiEvent");
}
@@ -274,8 +274,8 @@ JackDriver::activate()
}
if (!_client)
- attach(_engine.world()->conf->option("jack-server").get_string(),
- _engine.world()->conf->option("jack-client").get_string(), NULL);
+ attach(_engine.world()->conf()->option("jack-server").get_string(),
+ _engine.world()->conf()->option("jack-client").get_string(), NULL);
jack_set_process_callback(_client, process_cb, this);
@@ -338,14 +338,19 @@ JackDriver::add_port(DriverPort* port)
*
* It is the callers responsibility to delete the returned port.
*/
-Raul::List<DriverPort*>::Node*
-JackDriver::remove_port(const Path& path)
+Raul::Deletable*
+JackDriver::remove_port(const Path& path, DriverPort** port)
{
ThreadManager::assert_thread(THREAD_PROCESS);
- for (Raul::List<JackPort*>::iterator i = _ports.begin(); i != _ports.end(); ++i)
- if ((*i)->patch_port()->path() == path)
- return (Raul::List<DriverPort*>::Node*)(_ports.erase(i));
+ for (Raul::List<JackPort*>::iterator i = _ports.begin(); i != _ports.end(); ++i) {
+ if ((*i)->patch_port()->path() == path) {
+ Raul::List<Ingen::JackPort*>::Node* node = _ports.erase(i);
+ if (port)
+ *port = node->elem();
+ return node;
+ }
+ }
LOG(warn) << "Unable to find port " << path << endl;
return NULL;
diff --git a/src/engine/JackDriver.hpp b/src/engine/JackDriver.hpp
index e2450d06..5ecdbfaf 100644
--- a/src/engine/JackDriver.hpp
+++ b/src/engine/JackDriver.hpp
@@ -97,7 +97,7 @@ public:
void add_port(DriverPort* port);
DriverPort* driver_port(const Raul::Path& path);
- Raul::List<DriverPort*>::Node* remove_port(const Raul::Path& path);
+ Raul::Deletable* remove_port(const Raul::Path& path, DriverPort** port=NULL);
PatchImpl* root_patch() { return _root_patch; }
void set_root_patch(PatchImpl* patch) { _root_patch = patch; }
diff --git a/src/engine/LADSPANode.cpp b/src/engine/LADSPANode.cpp
index ddcb774f..dd1f9370 100644
--- a/src/engine/LADSPANode.cpp
+++ b/src/engine/LADSPANode.cpp
@@ -133,7 +133,7 @@ LADSPANode::apply_poly(Raul::Maid& maid, uint32_t poly)
bool
LADSPANode::instantiate(BufferFactory& bufs)
{
- const LV2URIMap& uris = Shared::LV2URIMap::instance();
+ const LV2URIMap& uris = bufs.uris();
if (!_ports)
_ports = new Raul::Array<PortImpl*>(_descriptor->PortCount);
diff --git a/src/engine/LADSPAPlugin.cpp b/src/engine/LADSPAPlugin.cpp
index 94ff36d2..59774bb9 100644
--- a/src/engine/LADSPAPlugin.cpp
+++ b/src/engine/LADSPAPlugin.cpp
@@ -31,17 +31,17 @@ namespace Ingen {
LADSPAPlugin::LADSPAPlugin(
+ Shared::LV2URIMap& uris,
const std::string& library_path,
const std::string& uri,
unsigned long id,
const std::string& label,
const std::string& name)
- : PluginImpl(Plugin::LADSPA, uri, library_path)
+ : PluginImpl(uris, Plugin::LADSPA, uri, library_path)
, _id(id)
, _label(label)
, _name(name)
{
- const LV2URIMap& uris = Shared::LV2URIMap::instance();
set_property(uris.rdf_type, uris.ingen_LADSPAPlugin);
set_property(uris.lv2_symbol, Symbol::symbolify(label));
set_property(uris.doap_name, name);
@@ -51,7 +51,7 @@ LADSPAPlugin::LADSPAPlugin(
const Raul::Atom&
LADSPAPlugin::get_property(const Raul::URI& uri) const
{
- if (uri == Shared::LV2URIMap::instance().doap_name)
+ if (uri == _uris.doap_name)
return _name;
else
return ResourceImpl::get_property(uri);
diff --git a/src/engine/LADSPAPlugin.hpp b/src/engine/LADSPAPlugin.hpp
index 0d0b91ce..f5ae672a 100644
--- a/src/engine/LADSPAPlugin.hpp
+++ b/src/engine/LADSPAPlugin.hpp
@@ -37,11 +37,13 @@ class NodeImpl;
class LADSPAPlugin : public PluginImpl
{
public:
- LADSPAPlugin(const std::string& library_path,
- const std::string& uri,
- unsigned long id,
- const std::string& label,
- const std::string& name);
+ LADSPAPlugin(
+ Shared::LV2URIMap& uris,
+ const std::string& library_path,
+ const std::string& uri,
+ unsigned long id,
+ const std::string& label,
+ const std::string& name);
NodeImpl* instantiate(BufferFactory& bufs,
const std::string& name,
diff --git a/src/engine/LV2Info.cpp b/src/engine/LV2Info.cpp
index 774828dd..2e57e9a2 100644
--- a/src/engine/LV2Info.cpp
+++ b/src/engine/LV2Info.cpp
@@ -31,22 +31,22 @@ using namespace std;
namespace Ingen {
LV2Info::LV2Info(Ingen::Shared::World* world)
- : input_class(slv2_value_new_uri(world->slv2_world, SLV2_PORT_CLASS_INPUT))
- , output_class(slv2_value_new_uri(world->slv2_world, SLV2_PORT_CLASS_OUTPUT))
- , control_class(slv2_value_new_uri(world->slv2_world, SLV2_PORT_CLASS_CONTROL))
- , audio_class(slv2_value_new_uri(world->slv2_world, SLV2_PORT_CLASS_AUDIO))
- , event_class(slv2_value_new_uri(world->slv2_world, SLV2_PORT_CLASS_EVENT))
- , value_port_class(slv2_value_new_uri(world->slv2_world, LV2_OBJECT_URI "#ValuePort"))
- , message_port_class(slv2_value_new_uri(world->slv2_world, LV2_OBJECT_URI "#MessagePort"))
+ : input_class(slv2_value_new_uri(world->slv2_world(), SLV2_PORT_CLASS_INPUT))
+ , output_class(slv2_value_new_uri(world->slv2_world(), SLV2_PORT_CLASS_OUTPUT))
+ , control_class(slv2_value_new_uri(world->slv2_world(), SLV2_PORT_CLASS_CONTROL))
+ , audio_class(slv2_value_new_uri(world->slv2_world(), SLV2_PORT_CLASS_AUDIO))
+ , event_class(slv2_value_new_uri(world->slv2_world(), SLV2_PORT_CLASS_EVENT))
+ , value_port_class(slv2_value_new_uri(world->slv2_world(), LV2_OBJECT_URI "#ValuePort"))
+ , message_port_class(slv2_value_new_uri(world->slv2_world(), LV2_OBJECT_URI "#MessagePort"))
, _world(world)
{
assert(world);
- world->lv2_features->add_feature(LV2_EVENT_URI,
+ world->lv2_features()->add_feature(LV2_EVENT_URI,
SharedPtr<Shared::LV2Features::Feature>(new EventFeature()));
- world->lv2_features->add_feature(LV2_BLOB_SUPPORT_URI,
+ world->lv2_features()->add_feature(LV2_BLOB_SUPPORT_URI,
SharedPtr<Shared::LV2Features::Feature>(new BlobFeature()));
- world->lv2_features->add_feature(LV2_RESIZE_PORT_URI,
+ world->lv2_features()->add_feature(LV2_RESIZE_PORT_URI,
SharedPtr<Shared::LV2Features::Feature>(new ResizeFeature()));
}
diff --git a/src/engine/LV2Info.hpp b/src/engine/LV2Info.hpp
index 1044098a..2ba0ef20 100644
--- a/src/engine/LV2Info.hpp
+++ b/src/engine/LV2Info.hpp
@@ -54,7 +54,7 @@ public:
SLV2Value message_port_class;
Ingen::Shared::World& world() { return *_world; }
- SLV2World lv2_world() { return _world->slv2_world; }
+ SLV2World lv2_world() { return _world->slv2_world(); }
private:
Ingen::Shared::World* _world;
diff --git a/src/engine/LV2Node.cpp b/src/engine/LV2Node.cpp
index be16e76d..cc3e3ca0 100644
--- a/src/engine/LV2Node.cpp
+++ b/src/engine/LV2Node.cpp
@@ -138,7 +138,7 @@ LV2Node::apply_poly(Raul::Maid& maid, uint32_t poly)
bool
LV2Node::instantiate(BufferFactory& bufs)
{
- const LV2URIMap& uris = Shared::LV2URIMap::instance();
+ const LV2URIMap& uris = bufs.uris();
SharedPtr<LV2Info> info = _lv2_plugin->lv2_info();
SLV2Plugin plug = _lv2_plugin->slv2_plugin();
@@ -148,7 +148,7 @@ 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(this);
uint32_t port_buffer_size = 0;
SLV2Value ctx_ext_uri = slv2_value_new_uri(info->lv2_world(), LV2_CONTEXT_MESSAGE);
@@ -309,8 +309,8 @@ LV2Node::instantiate(BufferFactory& bufs)
SLV2Values types = slv2_port_get_value(plug, id, supports_pred);
for (uint32_t i = 0; i < slv2_values_size(types); ++i) {
SLV2Value type = slv2_values_get_at(types, i);
- std::cout << path() << " port " << id << " supports " <<
- slv2_value_as_uri(type) << std::endl;
+ Raul::info << path() << " port " << id << " supports " <<
+ slv2_value_as_uri(type) << std::endl;
if (slv2_value_is_uri(type)) {
port->add_property(uris.obj_supports, Raul::URI(slv2_value_as_uri(type)));
}
diff --git a/src/engine/LV2Plugin.cpp b/src/engine/LV2Plugin.cpp
index 76c2290d..a49818f5 100644
--- a/src/engine/LV2Plugin.cpp
+++ b/src/engine/LV2Plugin.cpp
@@ -32,12 +32,11 @@ namespace Ingen {
LV2Plugin::LV2Plugin(SharedPtr<LV2Info> lv2_info, const std::string& uri)
- : PluginImpl(Plugin::LV2, uri)
+ : PluginImpl(*lv2_info->world().uris().get(), Plugin::LV2, uri)
, _slv2_plugin(NULL)
, _lv2_info(lv2_info)
{
- const LV2URIMap& uris = Shared::LV2URIMap::instance();
- set_property(uris.rdf_type, uris.lv2_Plugin);
+ set_property(_uris.rdf_type, _uris.lv2_Plugin);
}
@@ -73,7 +72,7 @@ LV2Plugin::instantiate(BufferFactory& bufs,
load(); // FIXME: unload at some point
- Glib::Mutex::Lock lock(engine.world()->rdf_world->mutex());
+ Glib::Mutex::Lock lock(engine.world()->rdf_world()->mutex());
LV2Node* n = new LV2Node(this, name, polyphonic, parent, srate);
if ( ! n->instantiate(bufs) ) {
diff --git a/src/engine/MessageContext.cpp b/src/engine/MessageContext.cpp
index ec0fedbf..2e37f69a 100644
--- a/src/engine/MessageContext.cpp
+++ b/src/engine/MessageContext.cpp
@@ -37,17 +37,17 @@ namespace Ingen {
void
MessageContext::run(PortImpl* port, FrameTime time)
{
- if (ThreadManager::current_thread_id() == THREAD_PRE_PROCESS) {
+ 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::current_thread_id() == THREAD_PROCESS) {
+ } else if (ThreadManager::thread_is(THREAD_PROCESS)) {
Request r(time, port);
_requests.write(sizeof(Request), &r);
// signal() will be called at the end of this process cycle
- } else if (ThreadManager::current_thread_id() == THREAD_MESSAGE) {
+ } else if (ThreadManager::thread_is(THREAD_MESSAGE)) {
warn << "Message context recursion at " << port->path() << endl;
} else {
error << "Run requested from unknown thread" << endl;
diff --git a/src/engine/NodeFactory.cpp b/src/engine/NodeFactory.cpp
index 5ff21c04..c20afed8 100644
--- a/src/engine/NodeFactory.cpp
+++ b/src/engine/NodeFactory.cpp
@@ -66,8 +66,7 @@ NodeFactory::NodeFactory(Ingen::Shared::World* world)
NodeFactory::~NodeFactory()
{
for (Plugins::iterator i = _plugins.begin(); i != _plugins.end(); ++i)
- if (i->second->type() != Shared::Plugin::Internal)
- delete i->second;
+ delete i->second;
_plugins.clear();
}
@@ -111,7 +110,7 @@ NodeFactory::load_plugins()
{
ThreadManager::assert_thread(THREAD_PRE_PROCESS);
- _world->rdf_world->mutex().lock();
+ _world->rdf_world()->mutex().lock();
// 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
@@ -132,24 +131,25 @@ NodeFactory::load_plugins()
_has_loaded = true;
}
- _world->rdf_world->mutex().unlock();
+ _world->rdf_world()->mutex().unlock();
}
void
NodeFactory::load_internal_plugins()
{
- InternalPlugin& controller_plug = ControllerNode::internal_plugin();
- _plugins.insert(make_pair(controller_plug.uri(), &controller_plug));
+ Shared::LV2URIMap& uris = *_world->uris().get();
+ InternalPlugin* controller_plug = ControllerNode::internal_plugin(uris);
+ _plugins.insert(make_pair(controller_plug->uri(), controller_plug));
- InternalPlugin& delay_plug = DelayNode::internal_plugin();
- _plugins.insert(make_pair(delay_plug.uri(), &delay_plug));
+ InternalPlugin* delay_plug = DelayNode::internal_plugin(uris);
+ _plugins.insert(make_pair(delay_plug->uri(), delay_plug));
- InternalPlugin& note_plug = NoteNode::internal_plugin();
- _plugins.insert(make_pair(note_plug.uri(), &note_plug));
+ InternalPlugin* note_plug = NoteNode::internal_plugin(uris);
+ _plugins.insert(make_pair(note_plug->uri(), note_plug));
- InternalPlugin& trigger_plug = TriggerNode::internal_plugin();
- _plugins.insert(make_pair(trigger_plug.uri(), &trigger_plug));
+ InternalPlugin* trigger_plug = TriggerNode::internal_plugin(uris);
+ _plugins.insert(make_pair(trigger_plug->uri(), trigger_plug));
}
@@ -159,7 +159,7 @@ NodeFactory::load_internal_plugins()
void
NodeFactory::load_lv2_plugins()
{
- SLV2Plugins plugins = slv2_world_get_all_plugins(_world->slv2_world);
+ SLV2Plugins plugins = slv2_world_get_all_plugins(_world->slv2_world());
for (unsigned i=0; i < slv2_plugins_size(plugins); ++i) {
@@ -177,7 +177,7 @@ NodeFactory::load_lv2_plugins()
_plugins.insert(make_pair(uri, plugin));
}
- slv2_plugins_free(_world->slv2_world, plugins);
+ slv2_plugins_free(_world->slv2_world(), plugins);
}
#endif // HAVE_SLV2
@@ -254,10 +254,11 @@ NodeFactory::load_ladspa_plugins()
const Plugins::const_iterator i = _plugins.find(uri);
if (i == _plugins.end()) {
- LADSPAPlugin* plugin = new LADSPAPlugin(lib_path, uri,
- descriptor->UniqueID,
- descriptor->Label,
- descriptor->Name);
+ LADSPAPlugin* plugin = new LADSPAPlugin(*_world->uris().get(),
+ lib_path, uri,
+ descriptor->UniqueID,
+ descriptor->Label,
+ descriptor->Name);
_plugins.insert(make_pair(uri, plugin));
diff --git a/src/engine/NodeImpl.cpp b/src/engine/NodeImpl.cpp
index 332b69b2..d3639634 100644
--- a/src/engine/NodeImpl.cpp
+++ b/src/engine/NodeImpl.cpp
@@ -36,7 +36,7 @@ namespace Ingen {
NodeImpl::NodeImpl(PluginImpl* plugin, const Raul::Symbol& symbol, bool polyphonic, PatchImpl* parent, SampleRate srate)
- : GraphObjectImpl(parent, symbol)
+ : GraphObjectImpl(plugin->uris(), parent, symbol)
, _plugin(plugin)
, _polyphonic(polyphonic)
, _polyphony((polyphonic && parent) ? parent->internal_poly() : 1)
diff --git a/src/engine/ObjectSender.cpp b/src/engine/ObjectSender.cpp
index 0055dff1..d2f00bba 100644
--- a/src/engine/ObjectSender.cpp
+++ b/src/engine/ObjectSender.cpp
@@ -136,13 +136,11 @@ ObjectSender::send_port(ClientInterface* client, const PortImpl* port, bool bund
if (graph_parent)
client->put(port->meta_uri(), port->meta().properties());
- const Shared::LV2URIMap& map = Shared::LV2URIMap::instance();
-
client->put(port->path(), port->properties());
// Send control value
if (port->is_a(PortType::CONTROL))
- client->set_property(port->path(), map.ingen_value, port->value());
+ client->set_property(port->path(), port->bufs().uris().ingen_value, port->value());
if (bundle)
client->bundle_end();
diff --git a/src/engine/OutputPort.cpp b/src/engine/OutputPort.cpp
index 5509b655..8faefb3e 100644
--- a/src/engine/OutputPort.cpp
+++ b/src/engine/OutputPort.cpp
@@ -39,10 +39,8 @@ OutputPort::OutputPort(BufferFactory& bufs,
size_t buffer_size)
: PortImpl(bufs, parent, symbol, index, poly, type, value, buffer_size)
{
- const LV2URIMap& uris = Shared::LV2URIMap::instance();
-
if (!dynamic_cast<Patch*>(parent))
- add_property(uris.rdf_type, uris.lv2_OutputPort);
+ add_property(bufs.uris().rdf_type, bufs.uris().lv2_OutputPort);
if (type == PortType::CONTROL)
_broadcast = true;
diff --git a/src/engine/PatchImpl.cpp b/src/engine/PatchImpl.cpp
index 5d3b07a5..bce74b6b 100644
--- a/src/engine/PatchImpl.cpp
+++ b/src/engine/PatchImpl.cpp
@@ -18,6 +18,8 @@
#include <cassert>
#include <cmath>
#include "raul/log.hpp"
+#include "module/World.hpp"
+#include "shared/LV2URIMap.hpp"
#include "ThreadManager.hpp"
#include "NodeImpl.hpp"
#include "PatchImpl.hpp"
@@ -39,7 +41,8 @@ using namespace Shared;
PatchImpl::PatchImpl(Engine& engine, const Raul::Symbol& symbol, uint32_t poly, PatchImpl* parent, SampleRate srate, uint32_t internal_poly)
- : NodeImpl(new PatchPlugin("http://example.org/FIXME", "patch", "Ingen Patch"),
+ : NodeImpl(new PatchPlugin(*engine.world()->uris().get(),
+ engine.world()->uris()->ingen_Patch.c_str(), "patch", "Ingen Patch"),
symbol, poly, parent, srate)
, _engine(engine)
, _internal_poly(internal_poly)
@@ -338,9 +341,7 @@ PatchImpl::has_connection(const PortImpl* src_port, const PortImpl* dst_port) co
uint32_t
PatchImpl::num_ports() const
{
- ThreadID context = ThreadManager::current_thread_id();
-
- if (context == THREAD_PROCESS)
+ if (ThreadManager::thread_is(THREAD_PROCESS))
return NodeImpl::num_ports();
else
return _input_ports.size() + _output_ports.size();
diff --git a/src/engine/PatchPlugin.hpp b/src/engine/PatchPlugin.hpp
index e4feb992..7f0ebe82 100644
--- a/src/engine/PatchPlugin.hpp
+++ b/src/engine/PatchPlugin.hpp
@@ -35,10 +35,12 @@ class NodeImpl;
class PatchPlugin : public PluginImpl
{
public:
- PatchPlugin(const std::string& uri,
- const std::string& symbol,
- const std::string& name)
- : PluginImpl(Plugin::Patch, uri)
+ PatchPlugin(
+ Shared::LV2URIMap& uris,
+ const std::string& uri,
+ const std::string& symbol,
+ const std::string& name)
+ : PluginImpl(uris, Plugin::Patch, uri)
{}
NodeImpl* instantiate(BufferFactory& bufs,
diff --git a/src/engine/PluginImpl.hpp b/src/engine/PluginImpl.hpp
index 5aea4f68..ee33eff7 100644
--- a/src/engine/PluginImpl.hpp
+++ b/src/engine/PluginImpl.hpp
@@ -28,6 +28,8 @@
namespace Ingen {
+namespace Shared { class LV2URIMap; }
+
class PatchImpl;
class NodeImpl;
class Engine;
@@ -43,8 +45,9 @@ class PluginImpl : public Ingen::Shared::Plugin
, public boost::noncopyable
{
public:
- PluginImpl(Type type, const std::string& uri, const std::string library_path="")
- : ResourceImpl(uri)
+ PluginImpl(Shared::LV2URIMap& uris,
+ Type type, const std::string& uri, const std::string library_path="")
+ : ResourceImpl(uris, uri)
, _type(type)
, _library_path(library_path)
, _module(NULL)
diff --git a/src/engine/PortImpl.cpp b/src/engine/PortImpl.cpp
index 7abfb90d..0a8de1de 100644
--- a/src/engine/PortImpl.cpp
+++ b/src/engine/PortImpl.cpp
@@ -48,7 +48,7 @@ PortImpl::PortImpl(BufferFactory& bufs,
PortType type,
const Atom& value,
size_t buffer_size)
- : GraphObjectImpl(node, name)
+ : GraphObjectImpl(bufs.uris(), node, name)
, _bufs(bufs)
, _index(index)
, _poly(poly)
@@ -69,7 +69,7 @@ PortImpl::PortImpl(BufferFactory& bufs,
if (_buffer_size == 0)
_buffer_size = bufs.default_buffer_size(type);
- const LV2URIMap& uris = Shared::LV2URIMap::instance();
+ const LV2URIMap& uris = bufs.uris();
add_property(uris.rdf_type, type.uri());
set_property(uris.lv2_index, Atom((int32_t)index));
set_context(_context);
@@ -88,7 +88,7 @@ PortImpl::~PortImpl()
bool
PortImpl::supports(const Raul::URI& value_type) const
{
- return has_property(Shared::LV2URIMap::instance().obj_supports, value_type);
+ return has_property(_bufs.uris().obj_supports, value_type);
}
@@ -227,7 +227,7 @@ PortImpl::broadcast_value(Context& context, bool force)
break;
case PortType::VALUE:
case PortType::MESSAGE:
- LV2Object::to_atom(((ObjectBuffer*)buffer(0).get())->object(), val);
+ LV2Object::to_atom(_bufs.uris(), ((ObjectBuffer*)buffer(0).get())->object(), val);
break;
}
@@ -242,11 +242,11 @@ PortImpl::broadcast_value(Context& context, bool force)
void
PortImpl::set_context(Context::ID c)
{
- const LV2URIMap& uris = Shared::LV2URIMap::instance();
+ const LV2URIMap& uris = _bufs.uris();
_context = c;
switch (c) {
case Context::AUDIO:
- set_property(uris.ctx_context, uris.ctx_AudioContext);
+ remove_property(uris.ctx_context, uris.wildcard);
break;
case Context::MESSAGE:
set_property(uris.ctx_context, uris.ctx_MessageContext);
diff --git a/src/engine/PortImpl.hpp b/src/engine/PortImpl.hpp
index cb458d01..efc5e92d 100644
--- a/src/engine/PortImpl.hpp
+++ b/src/engine/PortImpl.hpp
@@ -136,6 +136,8 @@ public:
Context::ID context() const { return _context; }
void set_context(Context::ID c);
+ BufferFactory& bufs() const { return _bufs; }
+
protected:
PortImpl(BufferFactory& bufs,
NodeImpl* node,
diff --git a/src/engine/QueuedEngineInterface.cpp b/src/engine/QueuedEngineInterface.cpp
index d07bfe10..53bec047 100644
--- a/src/engine/QueuedEngineInterface.cpp
+++ b/src/engine/QueuedEngineInterface.cpp
@@ -225,7 +225,7 @@ QueuedEngineInterface::set_property(const URI& uri,
bool meta = (hash != string::npos);
Path path = meta ? (string("/") + path.chop_start("/")) : uri.str();
Resource::Properties remove;
- remove.insert(make_pair(predicate, Shared::LV2URIMap::instance().wildcard));
+ remove.insert(make_pair(predicate, _engine.world()->uris()->wildcard));
Resource::Properties add;
add.insert(make_pair(predicate, value));
push_queued(new Events::SetMetadata(_engine, _request, now(), false, meta, path, add, remove));
diff --git a/src/engine/ThreadManager.hpp b/src/engine/ThreadManager.hpp
index 3f86ba83..2dc7d4d5 100644
--- a/src/engine/ThreadManager.hpp
+++ b/src/engine/ThreadManager.hpp
@@ -34,16 +34,16 @@ enum ThreadID {
class ThreadManager {
public:
- inline static ThreadID current_thread_id() {
- return (ThreadID)Raul::Thread::get().context();
+ inline static bool thread_is(ThreadID id) {
+ return Raul::Thread::get().is_context(id);
}
inline static void assert_thread(ThreadID id) {
- assert(single_threaded || current_thread_id() == id);
+ assert(single_threaded || Raul::Thread::get().is_context(id));
}
inline static void assert_not_thread(ThreadID id) {
- assert(single_threaded || current_thread_id() != id);
+ assert(single_threaded || !Raul::Thread::get().is_context(id));
}
/** Set to true during initialisation so ensure_thread doesn't fail.
diff --git a/src/engine/events/CreateNode.cpp b/src/engine/events/CreateNode.cpp
index dc3f4469..1e428fdc 100644
--- a/src/engine/events/CreateNode.cpp
+++ b/src/engine/events/CreateNode.cpp
@@ -81,8 +81,8 @@ CreateNode::CreateNode(
_plugin_label = uri;
}
- const LV2URIMap& uris = Shared::LV2URIMap::instance();
- const Resource::Properties::const_iterator p = properties.find(uris.ingen_polyphonic);
+ const Resource::Properties::const_iterator p = properties.find(
+ engine.world()->uris()->ingen_polyphonic);
if (p != properties.end() && p->second.type() == Raul::Atom::BOOL
&& p->second.get_bool())
_polyphonic = true;
diff --git a/src/engine/events/CreatePatch.cpp b/src/engine/events/CreatePatch.cpp
index 5f87d605..17a27d11 100644
--- a/src/engine/events/CreatePatch.cpp
+++ b/src/engine/events/CreatePatch.cpp
@@ -83,7 +83,7 @@ CreatePatch::pre_process()
if (_parent != NULL && _poly > 1 && _poly == static_cast<int>(_parent->internal_poly()))
poly = _poly;
- const LV2URIMap& uris = *_engine.world()->uris.get();
+ const LV2URIMap& uris = *_engine.world()->uris().get();
_patch = new PatchImpl(_engine, path.symbol(), poly, _parent,
_engine.driver()->sample_rate(), _poly);
diff --git a/src/engine/events/CreatePort.cpp b/src/engine/events/CreatePort.cpp
index 33477400..cb76e9a2 100644
--- a/src/engine/events/CreatePort.cpp
+++ b/src/engine/events/CreatePort.cpp
@@ -84,7 +84,7 @@ CreatePort::pre_process()
_patch = _engine.engine_store()->find_patch(_path.parent());
- const LV2URIMap& uris = *_engine.world()->uris.get();
+ const LV2URIMap& uris = *_engine.world()->uris().get();
if (_patch != NULL) {
assert(_patch->path() == _path.parent());
diff --git a/src/engine/events/Delete.cpp b/src/engine/events/Delete.cpp
index 9e4548ac..45c54260 100644
--- a/src/engine/events/Delete.cpp
+++ b/src/engine/events/Delete.cpp
@@ -42,6 +42,7 @@ Delete::Delete(Engine& engine, SharedPtr<Request> request, FrameTime time, const
: QueuedEvent(engine, request, time, true)
, _path(path)
, _store_iterator(engine.engine_store()->end())
+ , _garbage(NULL)
, _driver_port(NULL)
, _patch_node_listnode(NULL)
, _patch_port_listnode(NULL)
@@ -153,9 +154,8 @@ Delete::execute(ProcessContext& context)
_engine.maid()->push(_port->parent_patch()->external_ports());
_port->parent_patch()->external_ports(_ports_array);
- if ( ! _port->parent_patch()->parent()) {
- _driver_port = _engine.driver()->remove_port(_port->path());
- }
+ if ( ! _port->parent_patch()->parent())
+ _garbage = _engine.driver()->remove_port(_port->path(), &_driver_port);
}
if (parent_patch) {
@@ -201,10 +201,10 @@ Delete::post_process()
_request->respond_error("Unable to delete object " + _path.chop_scheme());
}
- if (_driver_port) {
- _driver_port->elem()->destroy();
- _engine.maid()->push(_driver_port);
- }
+ if (_driver_port)
+ _driver_port->destroy();
+
+ _engine.maid()->push(_garbage);
}
diff --git a/src/engine/events/Delete.hpp b/src/engine/events/Delete.hpp
index be786c56..54a02d9f 100644
--- a/src/engine/events/Delete.hpp
+++ b/src/engine/events/Delete.hpp
@@ -75,7 +75,8 @@ private:
EngineStore::iterator _store_iterator;
SharedPtr<NodeImpl> _node; ///< Non-NULL iff a node
SharedPtr<PortImpl> _port; ///< Non-NULL iff a port
- Raul::List<DriverPort*>::Node* _driver_port;
+ Raul::Deletable* _garbage;
+ DriverPort* _driver_port;
PatchImpl::Nodes::Node* _patch_node_listnode;
Raul::List<PortImpl*>::Node* _patch_port_listnode;
Raul::Array<PortImpl*>* _ports_array; ///< New (external) ports for Patch
diff --git a/src/engine/events/RequestMetadata.cpp b/src/engine/events/RequestMetadata.cpp
index 69c5b271..5efc7072 100644
--- a/src/engine/events/RequestMetadata.cpp
+++ b/src/engine/events/RequestMetadata.cpp
@@ -74,7 +74,7 @@ RequestMetadata::pre_process()
GraphObjectImpl* obj = dynamic_cast<GraphObjectImpl*>(_resource);
if (obj) {
- if (_key == _engine.world()->uris->ingen_value)
+ if (_key == _engine.world()->uris()->ingen_value)
_special_type = PORT_VALUE;
else if (_is_meta)
_value = obj->meta().get_property(_key);
@@ -101,7 +101,7 @@ RequestMetadata::execute(ProcessContext& context)
} else {
IntrusivePtr<ObjectBuffer> obuf = PtrCast<ObjectBuffer>(port->buffer(0));
if (obuf) {
- LV2Object::to_atom(obuf->object(), _value);
+ LV2Object::to_atom(*_engine.world()->uris().get(), obuf->object(), _value);
}
}
} else {
@@ -119,7 +119,7 @@ RequestMetadata::post_process()
if (_resource) {
_request->respond_ok();
_request->client()->set_property(_uri.str(),
- _engine.world()->uris->ingen_value, _value);
+ _engine.world()->uris()->ingen_value, _value);
} else {
const string msg = "Get value for non-port " + _uri.str();
_request->respond_error(msg);
diff --git a/src/engine/events/SendBinding.cpp b/src/engine/events/SendBinding.cpp
index c3c83ea4..82736f53 100644
--- a/src/engine/events/SendBinding.cpp
+++ b/src/engine/events/SendBinding.cpp
@@ -31,7 +31,7 @@ namespace Events {
void
SendBinding::post_process()
{
- const LV2URIMap& uris = *_engine.world()->uris.get();
+ const LV2URIMap& uris = *_engine.world()->uris().get();
Raul::Atom::DictValue dict;
if (_type == ControlBindings::MIDI_CC) {
dict[uris.rdf_type] = uris.midi_Controller;
diff --git a/src/engine/events/SendPortValue.cpp b/src/engine/events/SendPortValue.cpp
index e6bf7ad9..394decad 100644
--- a/src/engine/events/SendPortValue.cpp
+++ b/src/engine/events/SendPortValue.cpp
@@ -33,7 +33,7 @@ SendPortValue::post_process()
{
_engine.broadcaster()->set_property(
_port->path(),
- _engine.world()->uris->ingen_value, _value);
+ _engine.world()->uris()->ingen_value, _value);
}
diff --git a/src/engine/events/SetMetadata.cpp b/src/engine/events/SetMetadata.cpp
index 6b0e5832..8066a4e9 100644
--- a/src/engine/events/SetMetadata.cpp
+++ b/src/engine/events/SetMetadata.cpp
@@ -111,13 +111,13 @@ SetMetadata::pre_process()
return;
}
- const LV2URIMap& uris = *_engine.world()->uris.get();
+ const LV2URIMap& uris = *_engine.world()->uris().get();
if (is_graph_object && !_object) {
Path path(_subject.str());
bool is_patch = false, is_node = false, is_port = false, is_output = false;
PortType data_type(PortType::UNKNOWN);
- ResourceImpl::type(_properties, is_patch, is_node, is_port, is_output, data_type);
+ ResourceImpl::type(uris, _properties, is_patch, is_node, is_port, is_output, data_type);
// Create a separate request without a source so EventSource isn't unblocked twice
SharedPtr<Request> sub_request(new Request(NULL, _request->client(), _request->id()));
diff --git a/src/engine/events/SetPortValue.cpp b/src/engine/events/SetPortValue.cpp
index b93783c2..1a41938d 100644
--- a/src/engine/events/SetPortValue.cpp
+++ b/src/engine/events/SetPortValue.cpp
@@ -102,7 +102,7 @@ SetPortValue::pre_process()
if (_port) {
_port->set_value(_value);
- _port->set_property(_engine.world()->uris->ingen_value, _value);
+ _port->set_property(_engine.world()->uris()->ingen_value, _value);
}
QueuedEvent::pre_process();
@@ -151,7 +151,7 @@ SetPortValue::apply(Context& context)
return;
}
- SharedPtr<LV2URIMap> uris = _engine.world()->uris;
+ LV2URIMap& uris = *_engine.world()->uris().get();
EventBuffer* const ebuf = dynamic_cast<EventBuffer*>(buf);
if (ebuf) {
@@ -159,14 +159,14 @@ SetPortValue::apply(Context& context)
// Size 0 event, pass it along to the plugin as a typed but empty event
if (_value.data_size() == 0) {
- const uint32_t type_id = uris->uri_to_id(NULL, _value.get_blob_type());
+ const uint32_t type_id = uris.uri_to_id(NULL, _value.get_blob_type());
ebuf->append(frames, 0, type_id, 0, NULL);
_port->raise_set_by_user_flag();
return;
} else if (!strcmp(_value.get_blob_type(), "http://lv2plug.in/ns/ext/midi#MidiEvent")) {
ebuf->prepare_write(context);
- ebuf->append(frames, 0, uris->midi_event.id, _value.data_size(),
+ ebuf->append(frames, 0, uris.midi_event.id, _value.data_size(),
(const uint8_t*)_value.get_blob());
_port->raise_set_by_user_flag();
return;
@@ -176,7 +176,7 @@ SetPortValue::apply(Context& context)
ObjectBuffer* const obuf = dynamic_cast<ObjectBuffer*>(buf);
if (obuf) {
obuf->object()->size = obuf->size() - sizeof(LV2_Object);
- if (LV2Object::from_atom(_value, obuf->object())) {
+ if (LV2Object::from_atom(uris, _value, obuf->object())) {
debug << "Converted atom " << _value << " :: " << obuf->object()->type
<< " * " << obuf->object()->size << " @ " << obuf->object() << endl;
return;
@@ -200,7 +200,7 @@ SetPortValue::post_process()
assert(_port != NULL);
_request->respond_ok();
_engine.broadcaster()->set_property(_port_path,
- _engine.world()->uris->ingen_value, _value);
+ _engine.world()->uris()->ingen_value, _value);
break;
case TYPE_MISMATCH:
ss << "Illegal value type " << _value.type()
diff --git a/src/engine/ingen_engine.cpp b/src/engine/ingen_engine.cpp
index b2f626c7..d25bcf46 100644
--- a/src/engine/ingen_engine.cpp
+++ b/src/engine/ingen_engine.cpp
@@ -25,13 +25,15 @@
using namespace Ingen;
struct IngenEngineModule : public Ingen::Shared::Module {
- void load(Ingen::Shared::World* world) {
+ virtual void load(Ingen::Shared::World* world) {
set_denormal_flags();
- world->local_engine = SharedPtr<Engine>(new Engine(world));
+ SharedPtr<Engine> engine(new Ingen::Engine(world));
+ world->set_local_engine(engine);
SharedPtr<QueuedEngineInterface> interface(
- new Ingen::QueuedEngineInterface(*world->local_engine, event_queue_size));
- world->engine = interface;
- world->local_engine->add_event_source(interface);
+ new Ingen::QueuedEngineInterface(*engine.get(), event_queue_size));
+ world->set_engine(interface);
+ engine->add_event_source(interface);
+ assert(world->local_engine() == engine);
}
};
diff --git a/src/engine/ingen_http.cpp b/src/engine/ingen_http.cpp
index 86ac481a..ffd26f2a 100644
--- a/src/engine/ingen_http.cpp
+++ b/src/engine/ingen_http.cpp
@@ -27,9 +27,9 @@ using namespace Ingen;
struct IngenHTTPModule : public Ingen::Shared::Module {
void load(Ingen::Shared::World* world) {
SharedPtr<HTTPEngineReceiver> interface(
- new Ingen::HTTPEngineReceiver(*world->local_engine.get(),
- world->conf->option("engine-port").get_int32()));
- world->local_engine->add_event_source(interface);
+ new Ingen::HTTPEngineReceiver(*world->local_engine().get(),
+ world->conf()->option("engine-port").get_int32()));
+ world->local_engine()->add_event_source(interface);
}
};
diff --git a/src/engine/ingen_jack.cpp b/src/engine/ingen_jack.cpp
index cdf9199e..cb4aff89 100644
--- a/src/engine/ingen_jack.cpp
+++ b/src/engine/ingen_jack.cpp
@@ -25,10 +25,10 @@ using namespace Ingen;
struct IngenJackModule : public Ingen::Shared::Module {
void load(Ingen::Shared::World* world) {
- Ingen::JackDriver* driver = new Ingen::JackDriver(*world->local_engine.get());
- driver->attach(world->conf->option("jack-server").get_string(),
- world->conf->option("jack-client").get_string(), NULL);
- world->local_engine->set_driver(SharedPtr<Driver>(driver));
+ Ingen::JackDriver* driver = new Ingen::JackDriver(*world->local_engine().get());
+ driver->attach(world->conf()->option("jack-server").get_string(),
+ world->conf()->option("jack-client").get_string(), NULL);
+ world->local_engine()->set_driver(SharedPtr<Driver>(driver));
}
};
diff --git a/src/engine/ingen_lv2.cpp b/src/engine/ingen_lv2.cpp
index 424df46c..8d14cba7 100644
--- a/src/engine/ingen_lv2.cpp
+++ b/src/engine/ingen_lv2.cpp
@@ -16,55 +16,177 @@
* 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*/
-#ifndef PLUGIN_URI
-#error "This file requires PLUGIN_URI to be defined"
-#endif
-
#include <stdlib.h>
+#include <glibmm/miscutils.h>
+#include <glibmm/convert.h>
+#include <glib.h>
#include "lv2.h"
+#include "ingen-config.h"
+#include "raul/log.hpp"
+#include "raul/Thread.hpp"
+#include "raul/SharedPtr.hpp"
+#include "engine/AudioBuffer.hpp"
#include "engine/Engine.hpp"
+#include "engine/ThreadManager.hpp"
#include "engine/Driver.hpp"
#include "engine/ProcessContext.hpp"
#include "engine/PatchImpl.hpp"
+#include "engine/QueuedEngineInterface.hpp"
#include "module/World.hpp"
-
-extern "C" {
+#include "module/ingen_module.hpp"
+#include "shared/runtime_paths.hpp"
+#include "shared/Configuration.hpp"
+#include "serialisation/Parser.hpp"
+#include "interface/EngineInterface.hpp"
using namespace Ingen;
-/* Plugin */
+namespace Ingen {
+namespace LV2 {
+
+/** Record of a patch found in this LV2 bundle */
+struct LV2Patch {
+ LV2Patch(const std::string& u, const std::string& f);
+
+ const std::string uri;
+ const std::string filename;
+ LV2_Descriptor descriptor;
+};
+
+
+/* Static library data */
+typedef std::vector< SharedPtr<const LV2Patch> > LV2Patches;
+static bool initialised = false;
+static LV2Patches patches;
+static Configuration conf;
+static int argc = 0;
+static char** argv = NULL;
+static Shared::World* world = NULL;
+
+
+struct LV2Driver;
+
+class LV2Port : public DriverPort
+{
+public:
+ LV2Port(LV2Driver* driver, DuplexPort* patch_port)
+ : DriverPort(patch_port)
+ , _driver(driver)
+ , _buffer(NULL)
+ {}
+
+ // TODO: LV2 dynamic ports
+ void create() {}
+ void destroy() {}
+ void move(const Raul::Path& path) {}
+
+ void pre_process(ProcessContext& context) {
+ if (!is_input() || !_buffer)
+ return;
+
+ if (_patch_port->buffer_type() == PortType::AUDIO) {
+ AudioBuffer* patch_buf = (AudioBuffer*)_patch_port->buffer(0).get();
+ patch_buf->copy((Sample*)_buffer, 0, context.nframes() - 1);
+ } else if (_patch_port->buffer_type() == PortType::EVENTS) {
+ //Raul::warn << "TODO: LV2 event I/O" << std::endl;
+ }
+ }
+
+ void post_process(ProcessContext& context) {
+ if (is_input() || !_buffer)
+ return;
-struct IngenLV2Driver : public Ingen::Driver {
- IngenLV2Driver(Engine& engine, SampleCount buffer_size, SampleCount sample_rate)
+ if (_patch_port->buffer_type() == PortType::AUDIO) {
+ AudioBuffer* patch_buf = (AudioBuffer*)_patch_port->buffer(0).get();
+ memcpy((Sample*)_buffer, patch_buf->data(), context.nframes() * sizeof(Sample));
+ } else if (_patch_port->buffer_type() == PortType::EVENTS) {
+ //Raul::warn << "TODO: LV2 event I/O" << std::endl;
+ }
+ }
+
+ void* buffer() const { return _buffer; }
+ void set_buffer(void* buf) { _buffer = buf; }
+
+private:
+ LV2Driver* _driver;
+ void* _buffer;
+};
+
+
+struct LV2Driver : public Driver {
+private:
+ typedef std::vector<LV2Port*> Ports;
+
+public:
+ LV2Driver(Engine& engine, SampleCount buffer_size, SampleCount sample_rate)
: _context(engine)
+ , _root_patch(NULL)
, _buffer_size(buffer_size)
, _sample_rate(sample_rate)
, _frame_time(0)
- , _root_patch(NULL)
{}
- void activate() {}
- void deactivate() {}
- bool is_activated() const { return true; }
-
void run(uint32_t nframes) {
_context.locate(_frame_time, nframes, 0);
+
+ for (Ports::iterator i = _ports.begin(); i != _ports.end(); ++i)
+ (*i)->pre_process(_context);
+
if (_root_patch)
_root_patch->process(_context);
+
+ for (Ports::iterator i = _ports.begin(); i != _ports.end(); ++i)
+ (*i)->post_process(_context);
+
_frame_time += nframes;
}
- virtual void set_root_patch(PatchImpl* patch) {}
- virtual PatchImpl* root_patch() { return NULL; }
+ virtual void set_root_patch(PatchImpl* patch) { _root_patch = patch; }
+ virtual PatchImpl* root_patch() { return _root_patch; }
+
+ virtual void add_port(DriverPort* port) {
+ // Note this doesn't have to be realtime safe since there's no dynamic LV2 ports
+ ThreadManager::assert_thread(THREAD_PROCESS);
+ assert(dynamic_cast<LV2Port*>(port));
+ assert(port->patch_port()->index() == _ports.size());
+ _ports.push_back((LV2Port*)port);
+ }
+
+ virtual Raul::Deletable* remove_port(const Raul::Path& path, Ingen::DriverPort** port=NULL) {
+ // Note this doesn't have to be realtime safe since there's no dynamic LV2 ports
+ ThreadManager::assert_thread(THREAD_PROCESS);
+
+ for (Ports::iterator i = _ports.begin(); i != _ports.end(); ++i) {
+ if ((*i)->patch_port()->path() == path) {
+ _ports.erase(i);
+ return NULL;
+ }
+ }
+
+ Raul::warn << "Unable to find port " << path << std::endl;
+ return NULL;
+ }
+
+
+ virtual bool supports(Shared::PortType port_type, Shared::EventType event_type) {
+ return true;
+ }
+
+ virtual DriverPort* create_port(DuplexPort* patch_port) {
+ return new LV2Port(this, patch_port);
+ }
- virtual void add_port(DriverPort* port) {}
- virtual DriverPort* remove_port(const Raul::Path& path) { return NULL; }
+ virtual DriverPort* driver_port(const Raul::Path& path) {
+ ThreadManager::assert_thread(THREAD_PROCESS);
- virtual DriverPort* create_port(DuplexPort* patch_port) { return NULL; }
+ for (Ports::iterator i = _ports.begin(); i != _ports.end(); ++i)
+ if ((*i)->patch_port()->path() == path)
+ return (*i);
- virtual DriverPort* driver_port(const Raul::Path& path) { return NULL; }
+ return NULL;
+ }
- virtual SampleCount buffer_size() const { return _buffer_size; }
+ virtual SampleCount block_length() const { return _buffer_size; }
virtual SampleCount sample_rate() const { return _sample_rate; }
virtual SampleCount frame_time() const { return _frame_time;}
@@ -77,30 +199,84 @@ private:
SampleCount _buffer_size;
SampleCount _sample_rate;
SampleCount _frame_time;
+ Ports _ports;
};
+} // namespace LV2
+} // namespace Ingen
+
+
+/* LV2 Plugin Interface */
+
+extern "C" {
+
struct IngenPlugin {
- Ingen::Shared::World* world;
- SharedPtr<Ingen::Engine> engine;
+ Ingen::Shared::World* world;
};
-static void
-ingen_activate(LV2_Handle instance)
+static LV2_Handle
+ingen_instantiate(const LV2_Descriptor* descriptor,
+ double rate,
+ const char* bundle_path,
+ const LV2_Feature*const* features)
{
- IngenPlugin* plugin = (IngenPlugin*)instance;
- plugin->engine->activate(1);
-}
+ Shared::set_bundle_path(bundle_path);
+ using namespace LV2;
-static void
-ingen_cleanup(LV2_Handle instance)
-{
- IngenPlugin* plugin = (IngenPlugin*)instance;
- plugin->engine.reset();
- ingen_destroy_world();
- free(instance);
+ const LV2Patch* patch = NULL;
+ for (LV2Patches::iterator i = patches.begin(); i != patches.end(); ++i) {
+ if (&(*i)->descriptor == descriptor) {
+ patch = (*i).get();
+ break;
+ }
+ }
+
+ if (!patch) {
+ Raul::error << "Could not find patch " << descriptor->URI << std::endl;
+ return NULL;
+ }
+
+ IngenPlugin* plugin = (IngenPlugin*)malloc(sizeof(IngenPlugin));
+ //plugin->world = ingen_world_new(&conf, argc, argv);
+ plugin->world = LV2::world;
+
+ SharedPtr<Engine> engine(new Engine(plugin->world));
+ plugin->world->set_local_engine(engine);
+
+ SharedPtr<QueuedEngineInterface> interface(
+ new Ingen::QueuedEngineInterface(*plugin->world->local_engine(), event_queue_size));
+ plugin->world->set_engine(interface);
+ plugin->world->local_engine()->add_event_source(interface);
+
+ Raul::Thread::get().set_context(THREAD_PRE_PROCESS);
+ ThreadManager::single_threaded = true;
+
+ ProcessContext context(*engine.get());
+
+ // FIXME: fixed (or at least maximum) buffer size
+ engine->set_driver(SharedPtr<Driver>(new LV2Driver(*engine.get(), rate, 4096)));
+
+ engine->activate();
+ ThreadManager::single_threaded = true;
+
+ // FIXME: don't load all plugins, only necessary ones
+ plugin->world->engine()->load_plugins();
+ engine->process_events(context);
+
+ plugin->world->parser()->parse_document(plugin->world,
+ plugin->world->engine().get(), patch->filename);
+ engine->process_events(context);
+
+ engine->deactivate();
+
+ // Activate and deactivate to create root patch, allocate buffers, etc
+ //engine->activate();
+ //engine->deactivate();
+
+ return (LV2_Handle)plugin;
}
@@ -110,33 +286,40 @@ ingen_connect_port(LV2_Handle instance, uint32_t port, void* data)
}
-static LV2_Handle
-ingen_instantiate(const LV2_Descriptor* descriptor,
- double rate,
- const char* bundle_path,
- const LV2_Feature*const* features)
+static void
+ingen_activate(LV2_Handle instance)
{
- IngenPlugin* plugin = (IngenPlugin*)malloc(sizeof(IngenPlugin));
+ IngenPlugin* me = (IngenPlugin*)instance;
+ me->world->local_engine()->activate();
+}
- Shared::bundle_path = bundle_path;
- plugin->world = ingen_get_world();
- plugin->engine = SharedPtr<Engine>(new Engine(plugin->world));
- plugin->world->local_engine = plugin->engine;
+static void
+ingen_run(LV2_Handle instance, uint32_t sample_count)
+{
+ IngenPlugin* me = (IngenPlugin*)instance;
+ // FIXME: don't do this every call
+ Raul::Thread::get().set_context(THREAD_PROCESS);
+ ((LV2::LV2Driver*)me->world->local_engine()->driver())->run(sample_count);
+}
- // FIXME: fixed buffer size
- plugin->engine->set_driver(PortType::AUDIO,
- SharedPtr<Driver>(new IngenLV2Driver(*plugin->engine, rate, 4096)));
- return (LV2_Handle)plugin;
+static void
+ingen_deactivate(LV2_Handle instance)
+{
+ IngenPlugin* me = (IngenPlugin*)instance;
+ me->world->local_engine()->deactivate();
}
static void
-ingen_run(LV2_Handle instance, uint32_t sample_count)
+ingen_cleanup(LV2_Handle instance)
{
- IngenPlugin* plugin = (IngenPlugin*)instance;
- ((IngenLV2Driver*)plugin->engine->driver())->run(sample_count);
+ IngenPlugin* me = (IngenPlugin*)instance;
+ me->world->set_local_engine(SharedPtr<Engine>());
+ me->world->set_engine(SharedPtr<EngineInterface>());
+ //ingen_world_free(me->world);
+ free(instance);
}
@@ -147,47 +330,79 @@ ingen_extension_data(const char* uri)
}
-static void
-ingen_deactivate(LV2_Handle instance)
+/* Library Code */
+
+namespace Ingen {
+namespace LV2 {
+
+LV2Patch::LV2Patch(const std::string& u, const std::string& f)
+ : uri(u), filename(f)
{
- IngenPlugin* plugin = (IngenPlugin*)instance;
- plugin->engine->deactivate();
+ descriptor.URI = uri.c_str();
+ descriptor.instantiate = ingen_instantiate;
+ descriptor.connect_port = ingen_connect_port;
+ descriptor.activate = ingen_activate;
+ descriptor.run = ingen_run;
+ descriptor.deactivate = ingen_deactivate;
+ descriptor.cleanup = ingen_cleanup;
+ descriptor.extension_data = ingen_extension_data;
}
+} // namespace LV2
+} // namespace Ingen
-/* Library */
-
-static LV2_Descriptor *ingen_descriptor = NULL;
static void
-init_descriptor()
+init()
{
- ingen_descriptor = (LV2_Descriptor*)malloc(sizeof(LV2_Descriptor));
-
- ingen_descriptor->URI = PLUGIN_URI;
- ingen_descriptor->instantiate = ingen_instantiate;
- ingen_descriptor->connect_port = ingen_connect_port;
- ingen_descriptor->activate = ingen_activate;
- ingen_descriptor->run = ingen_run;
- ingen_descriptor->deactivate = ingen_deactivate;
- ingen_descriptor->cleanup = ingen_cleanup;
- ingen_descriptor->extension_data = ingen_extension_data;
+ Shared::set_bundle_path_from_code((void*)&init);
+
+ using namespace LV2;
+
+ //Shared::World* world = ingen_world_new(&conf, argc, argv);
+
+ world = ingen_world_new(&conf, argc, argv);
+ if (!world->load("ingen_serialisation")) {
+ Raul::error << "Unable to load serialisation module" << std::endl;
+ //ingen_world_free(world);
+ return;
+ }
+
+
+ Serialisation::Parser::PatchRecords records(
+ world->parser()->find_patches(world,
+ Glib::filename_to_uri(Shared::bundle_file_path("manifest.ttl"))));
+
+ for (Serialisation::Parser::PatchRecords::iterator i = records.begin();
+ i != records.end(); ++i) {
+ patches.push_back(SharedPtr<const LV2Patch>(
+ new LV2Patch(i->uri.str(), i->filename)));
+ }
+
+
+ //ingen_world_free(world);
+
+ initialised = true;
}
+/* LV2 Library Interface */
+
+extern "C" {
+
LV2_SYMBOL_EXPORT
const LV2_Descriptor*
lv2_descriptor(uint32_t index)
{
- if (!ingen_descriptor)
- init_descriptor();
+ if (!LV2::initialised)
+ init();
- switch (index) {
- case 0:
- return ingen_descriptor;
- default:
+ if (index >= LV2::patches.size())
return NULL;
- }
+ else
+ return &LV2::patches[index]->descriptor;
+}
+
}
diff --git a/src/engine/ingen_osc.cpp b/src/engine/ingen_osc.cpp
index 69c8b279..b4549080 100644
--- a/src/engine/ingen_osc.cpp
+++ b/src/engine/ingen_osc.cpp
@@ -27,10 +27,10 @@ using namespace Ingen;
struct IngenOSCModule : public Ingen::Shared::Module {
void load(Ingen::Shared::World* world) {
SharedPtr<OSCEngineReceiver> interface(
- new Ingen::OSCEngineReceiver(*world->local_engine.get(),
+ new Ingen::OSCEngineReceiver(*world->local_engine().get(),
event_queue_size,
- world->conf->option("engine-port").get_int32()));
- world->local_engine->add_event_source(interface);
+ world->conf()->option("engine-port").get_int32()));
+ world->local_engine()->add_event_source(interface);
}
};
diff --git a/src/engine/internals/Controller.cpp b/src/engine/internals/Controller.cpp
index aeeb1cd1..b65b80d5 100644
--- a/src/engine/internals/Controller.cpp
+++ b/src/engine/internals/Controller.cpp
@@ -36,19 +36,20 @@ namespace Internals {
using namespace Shared;
-static InternalPlugin controller_plugin(NS_INTERNALS "Controller", "controller");
-
-InternalPlugin& ControllerNode::internal_plugin() { return controller_plugin; }
+InternalPlugin* ControllerNode::internal_plugin(Shared::LV2URIMap& uris) {
+ return new InternalPlugin(uris, NS_INTERNALS "Controller", "controller");
+}
-ControllerNode::ControllerNode(BufferFactory& bufs,
- const string& path,
- bool polyphonic,
- PatchImpl* parent,
- SampleRate srate)
- : NodeImpl(&controller_plugin, path, false, parent, srate)
+ControllerNode::ControllerNode(InternalPlugin* plugin,
+ BufferFactory& bufs,
+ const string& path,
+ bool polyphonic,
+ PatchImpl* parent,
+ SampleRate srate)
+ : NodeImpl(plugin, path, false, parent, srate)
, _learning(false)
{
- const LV2URIMap& uris = Shared::LV2URIMap::instance();
+ const LV2URIMap& uris = bufs.uris();
_ports = new Raul::Array<PortImpl*>(6);
_midi_in_port = new InputPort(bufs, this, "input", 0, 1, PortType::EVENTS, Raul::Atom());
diff --git a/src/engine/internals/Controller.hpp b/src/engine/internals/Controller.hpp
index b3363665..a8c90a2a 100644
--- a/src/engine/internals/Controller.hpp
+++ b/src/engine/internals/Controller.hpp
@@ -40,7 +40,13 @@ namespace Internals {
class ControllerNode : public NodeImpl
{
public:
- ControllerNode(BufferFactory& bufs, const std::string& path, bool polyphonic, PatchImpl* parent, SampleRate srate);
+ ControllerNode(
+ InternalPlugin* plugin,
+ BufferFactory& bufs,
+ const std::string& path,
+ bool polyphonic,
+ PatchImpl* parent,
+ SampleRate srate);
void process(ProcessContext& context);
@@ -48,7 +54,7 @@ public:
void learn() { _learning = true; }
- static InternalPlugin& internal_plugin();
+ static InternalPlugin* internal_plugin(Shared::LV2URIMap& uris);
private:
bool _learning;
diff --git a/src/engine/internals/Delay.cpp b/src/engine/internals/Delay.cpp
index 7910713f..1316c567 100644
--- a/src/engine/internals/Delay.cpp
+++ b/src/engine/internals/Delay.cpp
@@ -49,18 +49,24 @@ using namespace Shared;
static const float MAX_DELAY_SECONDS = 8.0f;
-static InternalPlugin note_plugin(NS_INTERNALS "Delay", "delay");
-
-InternalPlugin& DelayNode::internal_plugin() { return note_plugin; }
+InternalPlugin* DelayNode::internal_plugin(Shared::LV2URIMap& uris) {
+ return new InternalPlugin(uris, NS_INTERNALS "Delay", "delay");
+}
-DelayNode::DelayNode(BufferFactory& bufs, const string& path, bool polyphonic, PatchImpl* parent, SampleRate srate)
- : NodeImpl(&note_plugin, path, polyphonic, parent, srate)
+DelayNode::DelayNode(
+ InternalPlugin* plugin,
+ BufferFactory& bufs,
+ const std::string& path,
+ bool polyphonic,
+ PatchImpl* parent,
+ SampleRate srate)
+ : NodeImpl(plugin, path, polyphonic, parent, srate)
, _buffer(0)
, _buffer_length(0)
, _buffer_mask(0)
, _write_phase(0)
{
- const LV2URIMap& uris = Shared::LV2URIMap::instance();
+ const LV2URIMap& uris = bufs.uris();
_ports = new Raul::Array<PortImpl*>(3);
const float default_delay = 1.0f;
diff --git a/src/engine/internals/Delay.hpp b/src/engine/internals/Delay.hpp
index 758d32e7..f07a3f4c 100644
--- a/src/engine/internals/Delay.hpp
+++ b/src/engine/internals/Delay.hpp
@@ -44,14 +44,21 @@ namespace Internals {
class DelayNode : public NodeImpl
{
public:
- DelayNode(BufferFactory& bufs, const std::string& path, bool polyphonic, PatchImpl* parent, SampleRate srate);
+ DelayNode(
+ InternalPlugin* plugin,
+ BufferFactory& bufs,
+ const std::string& path,
+ bool polyphonic,
+ PatchImpl* parent,
+ SampleRate srate);
+
~DelayNode();
void activate(BufferFactory& bufs);
void process(ProcessContext& context);
- static InternalPlugin& internal_plugin();
+ static InternalPlugin* internal_plugin(Shared::LV2URIMap& uris);
float delay_samples() const { return _delay_samples; }
diff --git a/src/engine/internals/Note.cpp b/src/engine/internals/Note.cpp
index 298af84a..7bdcd6ec 100644
--- a/src/engine/internals/Note.cpp
+++ b/src/engine/internals/Note.cpp
@@ -43,19 +43,28 @@ namespace Internals {
using namespace Shared;
-static InternalPlugin note_plugin(NS_INTERNALS "Note", "note");
-
-InternalPlugin& NoteNode::internal_plugin() { return note_plugin; }
+InternalPlugin* NoteNode::internal_plugin(Shared::LV2URIMap& uris) {
+ return new InternalPlugin(uris, NS_INTERNALS "Note", "note");
+}
-NoteNode::NoteNode(BufferFactory& bufs, const string& path, bool polyphonic, PatchImpl* parent, SampleRate srate)
- : NodeImpl(&note_plugin, path, polyphonic, parent, srate)
+NoteNode::NoteNode(
+ InternalPlugin* plugin,
+ BufferFactory& bufs,
+ const std::string& path,
+ bool polyphonic,
+ PatchImpl* parent,
+ SampleRate srate)
+ : NodeImpl(plugin, path, polyphonic, parent, srate)
, _voices(new Raul::Array<Voice>(_polyphony))
, _prepared_voices(NULL)
, _sustain(false)
{
- const LV2URIMap& uris = Shared::LV2URIMap::instance();
+ const LV2URIMap& uris = bufs.uris();
_ports = new Raul::Array<PortImpl*>(5);
+
+ std::cout << "NEW NOTE NODE" << std::endl;
+
_midi_in_port = new InputPort(bufs, this, "input", 0, 1, PortType::EVENTS, Raul::Atom());
_midi_in_port->set_property(uris.lv2_name, "Input");
_ports->at(0) = _midi_in_port;
diff --git a/src/engine/internals/Note.hpp b/src/engine/internals/Note.hpp
index 2866fb01..58b83782 100644
--- a/src/engine/internals/Note.hpp
+++ b/src/engine/internals/Note.hpp
@@ -40,7 +40,14 @@ namespace Internals {
class NoteNode : public NodeImpl
{
public:
- NoteNode(BufferFactory& bufs, const std::string& path, bool polyphonic, PatchImpl* parent, SampleRate srate);
+ NoteNode(
+ InternalPlugin* plugin,
+ BufferFactory& bufs,
+ const std::string& path,
+ bool polyphonic,
+ PatchImpl* parent,
+ SampleRate srate);
+
~NoteNode();
bool prepare_poly(BufferFactory& bufs, uint32_t poly);
@@ -55,7 +62,7 @@ public:
void sustain_on(ProcessContext& context, FrameTime time);
void sustain_off(ProcessContext& context, FrameTime time);
- static InternalPlugin& internal_plugin();
+ static InternalPlugin* internal_plugin(Shared::LV2URIMap& uris);
private:
/** Key, one for each key on the keyboard */
diff --git a/src/engine/internals/Trigger.cpp b/src/engine/internals/Trigger.cpp
index ed3b2d90..5fa78774 100644
--- a/src/engine/internals/Trigger.cpp
+++ b/src/engine/internals/Trigger.cpp
@@ -39,15 +39,21 @@ namespace Internals {
using namespace Shared;
-static InternalPlugin trigger_plugin(NS_INTERNALS "Trigger", "trigger");
-
-InternalPlugin& TriggerNode::internal_plugin() { return trigger_plugin; }
+InternalPlugin* TriggerNode::internal_plugin(Shared::LV2URIMap& uris) {
+ return new InternalPlugin(uris, NS_INTERNALS "Trigger", "trigger");
+}
-TriggerNode::TriggerNode(BufferFactory& bufs, const string& path, bool polyphonic, PatchImpl* parent, SampleRate srate)
- : NodeImpl(&trigger_plugin, path, false, parent, srate)
+TriggerNode::TriggerNode(
+ InternalPlugin* plugin,
+ BufferFactory& bufs,
+ const std::string& path,
+ bool polyphonic,
+ PatchImpl* parent,
+ SampleRate srate)
+ : NodeImpl(plugin, path, false, parent, srate)
, _learning(false)
{
- const LV2URIMap& uris = LV2URIMap::instance();
+ const LV2URIMap& uris = bufs.uris();
_ports = new Raul::Array<PortImpl*>(5);
_midi_in_port = new InputPort(bufs, this, "input", 0, 1, PortType::EVENTS, Raul::Atom());
diff --git a/src/engine/internals/Trigger.hpp b/src/engine/internals/Trigger.hpp
index 5513f6d8..a9c55deb 100644
--- a/src/engine/internals/Trigger.hpp
+++ b/src/engine/internals/Trigger.hpp
@@ -43,7 +43,13 @@ namespace Internals {
class TriggerNode : public NodeImpl
{
public:
- TriggerNode(BufferFactory& bufs, const std::string& path, bool polyphonic, PatchImpl* parent, SampleRate srate);
+ TriggerNode(
+ InternalPlugin* plugin,
+ BufferFactory& bufs,
+ const std::string& path,
+ bool polyphonic,
+ PatchImpl* parent,
+ SampleRate srate);
void process(ProcessContext& context);
@@ -52,7 +58,7 @@ public:
void learn() { _learning = true; }
- static InternalPlugin& internal_plugin();
+ static InternalPlugin* internal_plugin(Shared::LV2URIMap& uris);
private:
bool _learning;
diff --git a/src/engine/wscript b/src/engine/wscript
index 6e7e72d0..25270a7d 100644
--- a/src/engine/wscript
+++ b/src/engine/wscript
@@ -58,13 +58,14 @@ def build(bld):
internals/Note.cpp
internals/Trigger.cpp
'''
-
- obj = bld.new_task_gen('cxx', 'shlib')
- obj.source = core_source
+
if bld.env['HAVE_LADSPA_H'] == 1:
- obj.source += ' LADSPAPlugin.cpp LADSPANode.cpp '
+ core_source += ' LADSPAPlugin.cpp LADSPANode.cpp '
if bld.env['HAVE_SLV2'] == 1:
- obj.source += ' LV2Info.cpp LV2Plugin.cpp LV2Node.cpp '
+ core_source += ' LV2Info.cpp LV2Plugin.cpp LV2Node.cpp '
+
+ obj = bld.new_task_gen('cxx', 'shlib')
+ obj.source = core_source
obj.export_incdirs = ['.']
obj.includes = ['.', '..', '../..', '../common']
obj.name = 'libingen_engine'
@@ -115,19 +116,14 @@ def build(bld):
obj.install_path = '${LIBDIR}/ingen'
autowaf.use_lib(bld, obj, core_libs + ' JACK')
- # Lightweight ingen/lv2 wrapper
- #obj = bld.new_task_gen('cxx', 'shlib')
- #obj.source = core_source
- #if bld.env['HAVE_LADSPA_H'] == 1:
- # obj.source += ' LADSPAPlugin.cpp LADSPANode.cpp '
- #if bld.env['HAVE_SLV2'] == 1:
- # obj.source += ' LV2Plugin.cpp LV2Node.cpp '
- #obj.export_incdirs = ['.']
- #obj.includes = ['.', '..', '../common', './events']
- #obj.name = 'ingen_lv2'
- #obj.target = 'ingen.lv2/ingen_lv2'
- #obj.install_path = ''
- #core_libs = 'GLIBMM GTHREAD LV2CORE SLV2 RAUL REDLANDMM'
- #autowaf.use_lib(bld, obj, core_libs)
-
-
+ # Ingen LV2 wrapper
+ obj = bld.new_task_gen('cxx', 'shlib')
+ obj.source = ' ingen_lv2.cpp '
+ obj.export_incdirs = ['.']
+ obj.includes = ['.', '..', '../..', '../common']
+ obj.name = 'libingen_lv2'
+ obj.target = 'ingen_lv2'
+ obj.install_path = '${LIBDIR}/ingen'
+ obj.uselib_local = 'libingen_shared libingen_module'
+ obj.add_objects = 'libingen_engine'
+ autowaf.use_lib(bld, obj, core_libs)
diff --git a/src/gui/App.cpp b/src/gui/App.cpp
index be15d4cb..ca59852a 100644
--- a/src/gui/App.cpp
+++ b/src/gui/App.cpp
@@ -90,10 +90,10 @@ App::App(Ingen::Shared::World* world)
_about_dialog->property_program_name() = "Ingen";
_about_dialog->property_logo_icon_name() = "ingen";
- PluginModel::set_rdf_world(*world->rdf_world);
+ PluginModel::set_rdf_world(*world->rdf_world());
#ifdef HAVE_SLV2
- PluginModel::set_slv2_world(world->slv2_world);
+ PluginModel::set_slv2_world(world->slv2_world());
#endif
}
@@ -109,7 +109,7 @@ void
App::init(Ingen::Shared::World* world)
{
Gnome::Canvas::init();
- _main = new Gtk::Main(world->argc, world->argv);
+ _main = new Gtk::Main(&world->argc(), &world->argv());
if (!_instance)
_instance = new App(world);
@@ -169,12 +169,12 @@ App::attach(SharedPtr<SigClientInterface> client,
assert( ! _store);
assert( ! _loader);
- _world->engine->register_client(client.get());
+ _world->engine()->register_client(client.get());
_client = client;
_handle = handle;
- _store = SharedPtr<ClientStore>(new ClientStore(_world->engine, client));
- _loader = SharedPtr<ThreadedLoader>(new ThreadedLoader(_world->engine));
+ _store = SharedPtr<ClientStore>(new ClientStore(_world->uris(), _world->engine(), client));
+ _loader = SharedPtr<ThreadedLoader>(new ThreadedLoader(_world->uris(), _world->engine()));
_patch_tree_window->init(*_store);
@@ -186,7 +186,7 @@ App::attach(SharedPtr<SigClientInterface> client,
void
App::detach()
{
- if (_world->engine) {
+ if (_world->engine()) {
_window_factory->clear();
_store->clear();
@@ -194,18 +194,18 @@ App::detach()
_store.reset();
_client.reset();
_handle.reset();
- _world->engine.reset();
+ _world->set_engine(SharedPtr<EngineInterface>());
}
}
-const SharedPtr<Serialiser>&
+SharedPtr<Serialiser>
App::serialiser()
{
- if (!_world->serialiser)
+ if (!_world->serialiser())
_world->load("ingen_serialisation");
- return _world->serialiser;
+ return _world->serialiser();
}
@@ -299,8 +299,8 @@ App::gtk_main_iteration()
if (!_client)
return false;
- if (_world->local_engine) {
- _world->local_engine->main_iteration();
+ if (_world->local_engine()) {
+ _world->local_engine()->main_iteration();
} else {
_enable_signal = false;
_client->emit_signals();
@@ -326,7 +326,7 @@ bool
App::quit(Gtk::Window& dialog_parent)
{
bool quit = true;
- if (App::instance().world()->local_engine) {
+ if (App::instance().world()->local_engine()) {
Gtk::MessageDialog d(dialog_parent,
"The engine is running in this process. Quitting will terminate Ingen."
"\n\n" "Are you sure you want to quit?",
diff --git a/src/gui/App.hpp b/src/gui/App.hpp
index 3ac881f6..a793b968 100644
--- a/src/gui/App.hpp
+++ b/src/gui/App.hpp
@@ -105,12 +105,12 @@ public:
Glib::RefPtr<Gdk::Pixbuf> icon_from_path(const std::string& path, int size);
- const SharedPtr<Shared::EngineInterface>& engine() const { return _world->engine; }
- const SharedPtr<Client::SigClientInterface>& client() const { return _client; }
- const SharedPtr<Client::ClientStore>& store() const { return _store; }
- const SharedPtr<ThreadedLoader>& loader() const { return _loader; }
+ SharedPtr<Shared::EngineInterface> engine() const { return _world->engine(); }
+ SharedPtr<Client::SigClientInterface> client() const { return _client; }
+ SharedPtr<Client::ClientStore> store() const { return _store; }
+ SharedPtr<ThreadedLoader> loader() const { return _loader; }
- const SharedPtr<Serialisation::Serialiser>& serialiser();
+ SharedPtr<Serialisation::Serialiser> serialiser();
static inline App& instance() { assert(_instance); return *_instance; }
@@ -118,7 +118,7 @@ public:
static void run();
inline Ingen::Shared::World* world() const { return _world; }
- inline Ingen::Shared::LV2URIMap& uris() const { return *_world->uris; }
+ inline Ingen::Shared::LV2URIMap& uris() const { return *_world->uris(); }
protected:
diff --git a/src/gui/ConnectWindow.cpp b/src/gui/ConnectWindow.cpp
index aae826e4..ec440501 100644
--- a/src/gui/ConnectWindow.cpp
+++ b/src/gui/ConnectWindow.cpp
@@ -74,13 +74,13 @@ ConnectWindow::ConnectWindow(BaseObjectType* cobject, const Glib::RefPtr<Gnome::
void
ConnectWindow::start(Ingen::Shared::World* world)
{
- if (world->local_engine) {
+ if (world->local_engine()) {
_mode = INTERNAL;
if (_widgets_loaded)
_internal_radio->set_active(true);
}
- set_connected_to(world->engine);
+ set_connected_to(world->engine());
connect(true);
}
@@ -89,7 +89,7 @@ ConnectWindow::start(Ingen::Shared::World* world)
void
ConnectWindow::set_connected_to(SharedPtr<Shared::EngineInterface> engine)
{
- App::instance().world()->engine = engine;
+ App::instance().world()->set_engine(engine);
if (!_widgets_loaded)
return;
@@ -111,7 +111,7 @@ ConnectWindow::set_connected_to(SharedPtr<Shared::EngineInterface> engine)
_connect_button->set_sensitive(true);
_disconnect_button->set_sensitive(false);
- if (App::instance().world()->local_engine)
+ if (App::instance().world()->local_engine())
_internal_radio->set_sensitive(true);
else
_internal_radio->set_sensitive(false);
@@ -178,7 +178,7 @@ ConnectWindow::connect(bool existing)
}
if (existing)
- uri = world->engine->uri().str();
+ uri = world->engine()->uri().str();
// Create client-side listener
SharedPtr<ThreadedSigClientInterface> tsci(new ThreadedSigClientInterface(1024));
@@ -198,14 +198,14 @@ ConnectWindow::connect(bool existing)
if (!existing) {
#ifdef HAVE_LIBLO
if (scheme == "osc.udp" || scheme == "osc.tcp")
- world->engine = SharedPtr<EngineInterface>(new OSCEngineSender(uri));
+ world->set_engine(SharedPtr<EngineInterface>(new OSCEngineSender(uri)));
#endif
#ifdef HAVE_SOUP
if (scheme == "http")
- world->engine = SharedPtr<EngineInterface>(new HTTPEngineSender(world, uri));
+ world->set_engine(SharedPtr<EngineInterface>(new HTTPEngineSender(world, uri)));
#endif
} else {
- uri = world->engine->uri().str();
+ uri = world->engine()->uri().str();
scheme = uri.substr(0, uri.find(":"));
}
@@ -223,8 +223,8 @@ ConnectWindow::connect(bool existing)
const string cmd = string("ingen -e --engine-port=").append(port_str);
if (Raul::Process::launch(cmd)) {
- world->engine = SharedPtr<EngineInterface>(
- new OSCEngineSender(string("osc.udp://localhost:").append(port_str)));
+ world->set_engine(SharedPtr<EngineInterface>(
+ new OSCEngineSender(string("osc.udp://localhost:").append(port_str))));
// FIXME: static args
SharedPtr<ThreadedSigClientInterface> tsci(new ThreadedSigClientInterface(1024));
@@ -246,15 +246,15 @@ ConnectWindow::connect(bool existing)
} else
#endif // defined(HAVE_LIBLO) || defined(HAVE_SOUP)
if (_mode == INTERNAL) {
- if (!world->local_engine)
+ if (!world->local_engine())
world->load("ingen_engine");
SharedPtr<SigClientInterface> client(new SigClientInterface());
- if (!world->local_engine->driver())
+ if (!world->local_engine()->driver())
world->load("ingen_jack");
- world->local_engine->activate();
+ world->local_engine()->activate();
App::instance().attach(client);
App::instance().register_callbacks();
diff --git a/src/gui/LoadRemotePatchWindow.cpp b/src/gui/LoadRemotePatchWindow.cpp
index 0359b34c..a7725571 100644
--- a/src/gui/LoadRemotePatchWindow.cpp
+++ b/src/gui/LoadRemotePatchWindow.cpp
@@ -66,17 +66,17 @@ LoadRemotePatchWindow::present(SharedPtr<PatchModel> patch, GraphObject::Propert
set_patch(patch);
_initial_data = data;
- Redland::Model model(*App::instance().world()->rdf_world,
+ Redland::Model model(*App::instance().world()->rdf_world(),
"http://rdf.drobilla.net/ingen_patches/index.ttl",
"http://rdf.drobilla.net/ingen_patches/");
- Redland::Query query(*App::instance().world()->rdf_world, Glib::ustring(
+ Redland::Query query(*App::instance().world()->rdf_world(), Glib::ustring(
"SELECT DISTINCT ?name ?uri WHERE {"
" ?uri a ingen:Patch ;"
" doap:name ?name ."
"}"));
- Redland::Query::Results results = query.run(*App::instance().world()->rdf_world, model);
+ Redland::Query::Results results = query.run(*App::instance().world()->rdf_world(), model);
for (Redland::Query::Results::iterator i = results.begin(); i != results.end(); ++i) {
Gtk::TreeModel::iterator iter = _liststore->append();
diff --git a/src/gui/NodeModule.cpp b/src/gui/NodeModule.cpp
index 30762f99..a2db6f83 100644
--- a/src/gui/NodeModule.cpp
+++ b/src/gui/NodeModule.cpp
@@ -120,7 +120,7 @@ NodeModule::show_human_names(bool b)
const LV2URIMap& uris = App::instance().uris();
if (b && node()->plugin()) {
- Glib::Mutex::Lock lock(App::instance().world()->rdf_world->mutex());
+ Glib::Mutex::Lock lock(App::instance().world()->rdf_world()->mutex());
const Raul::Atom& name_property = node()->get_property(uris.lv2_name);
if (name_property.type() == Atom::STRING)
set_name(name_property.get_string());
diff --git a/src/gui/PatchCanvas.cpp b/src/gui/PatchCanvas.cpp
index 4981bf6e..a1617993 100644
--- a/src/gui/PatchCanvas.cpp
+++ b/src/gui/PatchCanvas.cpp
@@ -661,11 +661,12 @@ PatchCanvas::paste()
clear_selection();
++_paste_count;
- Builder builder(*App::instance().engine());
- ClientStore clipboard;
+ const LV2URIMap& uris = App::instance().uris();
+
+ Builder builder(App::instance().world()->uris(), *App::instance().engine());
+ ClientStore clipboard(App::instance().world()->uris());
clipboard.set_plugins(App::instance().store()->plugins());
- const LV2URIMap& uris = App::instance().uris();
// mkdir -p
string to_create = _patch->path().chop_scheme().substr(1);
diff --git a/src/gui/Port.cpp b/src/gui/Port.cpp
index 4e1a5460..0ef9f634 100644
--- a/src/gui/Port.cpp
+++ b/src/gui/Port.cpp
@@ -192,7 +192,7 @@ Port::set_control(float value, bool signal)
App& app = App::instance();
Ingen::Shared::World* const world = app.world();
app.engine()->set_property(model()->path(),
- world->uris->ingen_value, Atom(value));
+ world->uris()->ingen_value, Atom(value));
PatchWindow* pw = app.window_factory()->patch_window(
PtrCast<PatchModel>(model()->parent()));
if (!pw)
@@ -241,8 +241,7 @@ Port::dash()
if (!pm)
return NULL;
- const Raul::Atom& context = pm->get_property(uris.ctx_context);
- if (!context.is_valid() || context.type() != Atom::URI || context == uris.ctx_AudioContext)
+ if (pm->has_context(uris.ctx_AudioContext))
return NULL;
if (!_dash) {
diff --git a/src/gui/PropertiesWindow.cpp b/src/gui/PropertiesWindow.cpp
index 44c1c774..5f7e3d15 100644
--- a/src/gui/PropertiesWindow.cpp
+++ b/src/gui/PropertiesWindow.cpp
@@ -18,7 +18,6 @@
#include <cassert>
#include <string>
#include "raul/log.hpp"
-#include "module/ingen_module.hpp"
#include "module/World.hpp"
#include "client/NodeModel.hpp"
#include "client/PluginModel.hpp"
@@ -89,7 +88,7 @@ PropertiesWindow::set_object(SharedPtr<ObjectModel> model)
set_title(model->path().chop_scheme() + " Properties - Ingen");
- Shared::World* world = ingen_get_world();
+ Shared::World* world = App::instance().world();
ostringstream ss;
unsigned n_rows = 0;
@@ -100,7 +99,7 @@ PropertiesWindow::set_object(SharedPtr<ObjectModel> model)
const Raul::Atom& value = i->second;
// Column 0: Property
- Gtk::Label* lab = manage(new Gtk::Label(world->rdf_world->qualify(i->first.str()), 0.0, 0.5));
+ Gtk::Label* lab = manage(new Gtk::Label(world->rdf_world()->qualify(i->first.str()), 0.0, 0.5));
_table->attach(*lab, 0, 1, n_rows, n_rows + 1, Gtk::FILL|Gtk::SHRINK, Gtk::SHRINK);
// Column 1: Type
diff --git a/src/gui/ThreadedLoader.cpp b/src/gui/ThreadedLoader.cpp
index 9b991555..eae032f4 100644
--- a/src/gui/ThreadedLoader.cpp
+++ b/src/gui/ThreadedLoader.cpp
@@ -31,9 +31,9 @@ namespace Ingen {
namespace GUI {
-ThreadedLoader::ThreadedLoader(SharedPtr<EngineInterface> engine)
+ThreadedLoader::ThreadedLoader(SharedPtr<Shared::LV2URIMap> uris, SharedPtr<EngineInterface> engine)
: _engine(engine)
- , _deprecated_loader(engine)
+ , _deprecated_loader(uris, engine)
{
set_name("Loader");
@@ -47,12 +47,12 @@ ThreadedLoader::ThreadedLoader(SharedPtr<EngineInterface> engine)
SharedPtr<Parser>
ThreadedLoader::parser()
{
- Ingen::Shared::World* world = ingen_get_world();
+ Ingen::Shared::World* world = App::instance().world();
- if (!world->parser)
+ if (!world->parser())
world->load("ingen_serialisation");
- return world->parser;
+ return world->parser();
}
@@ -79,7 +79,7 @@ ThreadedLoader::load_patch(bool merge,
{
_mutex.lock();
- Ingen::Shared::World* world = ingen_get_world();
+ Ingen::Shared::World* world = App::instance().world();
Glib::ustring engine_base = "";
if (engine_parent) {
@@ -101,9 +101,9 @@ ThreadedLoader::load_patch(bool merge,
false)));
} else {
_events.push_back(sigc::hide_return(sigc::bind(
- sigc::mem_fun(world->parser.get(), &Ingen::Serialisation::Parser::parse_document),
+ sigc::mem_fun(world->parser().get(), &Ingen::Serialisation::Parser::parse_document),
App::instance().world(),
- App::instance().world()->engine.get(),
+ App::instance().world()->engine().get(),
document_uri,
data_path,
engine_parent,
diff --git a/src/gui/ThreadedLoader.hpp b/src/gui/ThreadedLoader.hpp
index f6b8d706..1c05ea22 100644
--- a/src/gui/ThreadedLoader.hpp
+++ b/src/gui/ThreadedLoader.hpp
@@ -55,7 +55,7 @@ namespace GUI {
class ThreadedLoader : public Raul::Slave
{
public:
- ThreadedLoader(SharedPtr<EngineInterface> engine);
+ ThreadedLoader(SharedPtr<Shared::LV2URIMap> uris, SharedPtr<EngineInterface> engine);
void load_patch(bool merge,
const Glib::ustring& document_uri,
diff --git a/src/ingen/main.cpp b/src/ingen/main.cpp
index cd8ad999..e269ae89 100644
--- a/src/ingen/main.cpp
+++ b/src/ingen/main.cpp
@@ -30,6 +30,7 @@
#include "raul/SharedPtr.hpp"
#include "redlandmm/World.hpp"
#include "interface/EngineInterface.hpp"
+#include "shared/Configuration.hpp"
#include "shared/runtime_paths.hpp"
#include "module/ingen_module.hpp"
#include "module/Module.hpp"
@@ -44,51 +45,30 @@ using namespace std;
using namespace Raul;
using namespace Ingen;
-SharedPtr<Ingen::Engine> engine;
+Ingen::Shared::World* world = NULL;
void
ingen_interrupt(int)
{
cout << "ingen: Interrupted" << endl;
- engine->quit();
+ if (world->local_engine())
+ world->local_engine()->quit();
+ ingen_world_free(world);
+ exit(1);
}
void
ingen_abort(const char* msg)
{
cerr << "ingen: Error: " << msg << endl;
- ingen_destroy_world();
+ ingen_world_free(world);
exit(1);
}
int
main(int argc, char** argv)
{
- Raul::Configuration conf("A realtime modular audio processor.",
- "Ingen is a flexible modular system that be used in various ways.\n"
- "The engine can run as a stand-alone server controlled via a network protocol\n"
- "(e.g. OSC), or internal to another process (e.g. the GUI). The GUI, or other\n"
- "clients, can communicate with the engine via any supported protocol, or host the\n"
- "engine in the same process. Many clients can connect to an engine at once.\n\n"
- "Examples:\n"
- " ingen -e # Run an engine, listen for OSC\n"
- " ingen -g # Run a GUI, connect via OSC\n"
- " ingen -eg # Run an engine and a GUI in one process\n"
- " ingen -egl patch.ing.ttl # Run an engine and a GUI and load a patch file\n"
- " ingen -egl patch.ing.lv2 # Run an engine and a GUI and load a patch bundle");
-
- conf.add("client-port", 'C', "Client OSC port", Atom::INT, Atom())
- .add("connect", 'c', "Connect to engine URI", Atom::STRING, "osc.udp://localhost:16180")
- .add("engine", 'e', "Run (JACK) engine", Atom::BOOL, false)
- .add("engine-port", 'E', "Engine listen port", Atom::INT, 16180)
- .add("gui", 'g', "Launch the GTK graphical interface", Atom::BOOL, false)
- .add("help", 'h', "Print this help message", Atom::BOOL, false)
- .add("jack-client", 'n', "JACK client name", Atom::STRING, "ingen")
- .add("jack-server", 's', "JACK server name", Atom::STRING, "default")
- .add("load", 'l', "Load patch", Atom::STRING, Atom())
- .add("parallelism", 'p', "Number of concurrent process threads", Atom::INT, 1)
- .add("path", 'L', "Target path for loaded patch", Atom::STRING, Atom())
- .add("run", 'r', "Run script", Atom::STRING, Atom());
+ Shared::Configuration conf;
// Parse command line options
try {
@@ -107,8 +87,10 @@ main(int argc, char** argv)
return EXIT_SUCCESS;
}
+#ifdef BUNDLE
// Set bundle path from executable location so resources/modules can be found
Shared::set_bundle_path_from_code((void*)&main);
+#endif
SharedPtr<Shared::EngineInterface> engine_interface;
@@ -117,37 +99,19 @@ main(int argc, char** argv)
g_type_init();
#endif
- Ingen::Shared::World* world = ingen_get_world();
-
- world->argc = argc;
- world->argv = argv;
- world->conf = &conf;
-
- // Set up RDF namespaces
- world->rdf_world->add_prefix("dc", "http://purl.org/dc/elements/1.1/");
- world->rdf_world->add_prefix("doap", "http://usefulinc.com/ns/doap#");
- world->rdf_world->add_prefix("ingen", "http://drobilla.net/ns/ingen#");
- world->rdf_world->add_prefix("ingenui", "http://drobilla.net/ns/ingenuity#");
- world->rdf_world->add_prefix("lv2", "http://lv2plug.in/ns/lv2core#");
- world->rdf_world->add_prefix("lv2ev", "http://lv2plug.in/ns/ext/event#");
- world->rdf_world->add_prefix("ctx", "http://lv2plug.in/ns/dev/contexts#");
- world->rdf_world->add_prefix("lv2midi", "http://lv2plug.in/ns/ext/midi#");
- world->rdf_world->add_prefix("midi", "http://drobilla.net/ns/dev/midi#");
- world->rdf_world->add_prefix("owl", "http://www.w3.org/2002/07/owl#");
- world->rdf_world->add_prefix("rdfs", "http://www.w3.org/2000/01/rdf-schema#");
- world->rdf_world->add_prefix("sp", "http://lv2plug.in/ns/dev/string-port#");
- world->rdf_world->add_prefix("xsd", "http://www.w3.org/2001/XMLSchema#");
+ Ingen::Shared::World* world = ingen_world_new(&conf, argc, argv);
+
+ assert(!world->local_engine());
// Run engine
if (conf.option("engine").get_bool()) {
if (!world->load("ingen_engine"))
ingen_abort("Unable to load engine module");
- if (!world->local_engine)
+ if (!world->local_engine())
ingen_abort("Unable to create engine");
- engine = world->local_engine;
- engine_interface = world->engine;
+ engine_interface = world->engine();
// Not loading a GUI, load network engine interfaces
if (!conf.option("gui").get_bool()) {
@@ -175,14 +139,14 @@ main(int argc, char** argv)
}
// Activate the engine, if we have one
- if (engine) {
+ if (world->local_engine()) {
if (!world->load("ingen_jack"))
ingen_abort("Unable to load jack module");
- engine->activate();
+ world->local_engine()->activate();
}
- world->engine = engine_interface;
+ world->set_engine(engine_interface);
// Load a patch
if (conf.option("load").is_valid() && engine_interface) {
@@ -206,7 +170,7 @@ main(int argc, char** argv)
if (!world->load("ingen_serialisation"))
ingen_abort("Unable to load serialisation module");
- if (world->parser) {
+ if (world->parser()) {
// Assumption: Containing ':' means URI, otherwise filename
string uri = conf.option("load").get_string();
if (uri.find(':') == string::npos) {
@@ -220,7 +184,7 @@ main(int argc, char** argv)
engine_interface->load_plugins();
if (conf.option("gui").get_bool())
engine_interface->get("ingen:plugins");
- world->parser->parse_document(
+ world->parser()->parse_document(
world, engine_interface.get(), uri, data_path, parent, symbol);
} else {
@@ -245,19 +209,17 @@ main(int argc, char** argv)
#endif
// Listen to OSC and run main loop
- } else if (engine && !conf.option("gui").get_bool()) {
+ } else if (world->local_engine() && !conf.option("gui").get_bool()) {
signal(SIGINT, ingen_interrupt);
signal(SIGTERM, ingen_interrupt);
- engine->main(); // Block here
+ world->local_engine()->main(); // Block here
}
// Shut down
- if (engine) {
- engine->deactivate();
- engine.reset();
- }
+ if (world->local_engine())
+ world->local_engine()->deactivate();
- ingen_destroy_world();
+ ingen_world_free(world);
return 0;
}
diff --git a/src/module/World.cpp b/src/module/World.cpp
index 43d89d6c..727e2dc8 100644
--- a/src/module/World.cpp
+++ b/src/module/World.cpp
@@ -15,12 +15,19 @@
* 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
+#include "ingen-config.h"
+#include <boost/utility.hpp>
#include <glibmm/module.h>
#include <glibmm/miscutils.h>
#include <glibmm/fileutils.h>
+#ifdef HAVE_SLV2
+#include "slv2/slv2.h"
+#endif
#include "raul/log.hpp"
-#include "ingen-config.h"
+#include "redlandmm/World.hpp"
#include "shared/runtime_paths.hpp"
+#include "shared/LV2Features.hpp"
+#include "shared/LV2URIMap.hpp"
#include "World.hpp"
#define LOG(s) s << "[Module] "
@@ -85,6 +92,124 @@ load_module(const string& name)
}
}
+
+struct WorldImpl : public boost::noncopyable {
+ WorldImpl(Raul::Configuration* conf, int& a_argc, char**& a_argv)
+ : argc(a_argc)
+ , argv(a_argv)
+ , conf(conf)
+ , lv2_features(NULL)
+ , rdf_world(new Redland::World())
+ , uris(new Shared::LV2URIMap())
+#ifdef HAVE_SLV2
+ , slv2_world(slv2_world_new_using_rdf_world(rdf_world->c_obj()))
+#endif
+ {
+#ifdef HAVE_SLV2
+ lv2_features = new Ingen::Shared::LV2Features();
+ lv2_features->add_feature(LV2_URI_MAP_URI, uris);
+ slv2_world_load_all(slv2_world);
+#endif
+
+ // Set up RDF namespaces
+ rdf_world->add_prefix("dc", "http://purl.org/dc/elements/1.1/");
+ rdf_world->add_prefix("doap", "http://usefulinc.com/ns/doap#");
+ rdf_world->add_prefix("ingen", "http://drobilla.net/ns/ingen#");
+ rdf_world->add_prefix("ingenui", "http://drobilla.net/ns/ingenuity#");
+ rdf_world->add_prefix("lv2", "http://lv2plug.in/ns/lv2core#");
+ rdf_world->add_prefix("lv2ev", "http://lv2plug.in/ns/ext/event#");
+ rdf_world->add_prefix("ctx", "http://lv2plug.in/ns/dev/contexts#");
+ rdf_world->add_prefix("lv2midi", "http://lv2plug.in/ns/ext/midi#");
+ rdf_world->add_prefix("midi", "http://drobilla.net/ns/dev/midi#");
+ rdf_world->add_prefix("owl", "http://www.w3.org/2002/07/owl#");
+ rdf_world->add_prefix("rdfs", "http://www.w3.org/2000/01/rdf-schema#");
+ rdf_world->add_prefix("sp", "http://lv2plug.in/ns/dev/string-port#");
+ rdf_world->add_prefix("xsd", "http://www.w3.org/2001/XMLSchema#");
+ }
+
+ virtual ~WorldImpl()
+ {
+ modules.clear();
+ interface_factories.clear();
+ script_runners.clear();
+
+ #ifdef HAVE_SLV2
+ slv2_world_free(slv2_world);
+ slv2_world = NULL;
+ #endif
+
+ delete rdf_world;
+ rdf_world = NULL;
+
+ delete lv2_features;
+ lv2_features = NULL;
+
+ uris.reset();
+ }
+
+ typedef std::map< const std::string, SharedPtr<Module> > Modules;
+ Modules modules;
+
+ typedef std::map<const std::string, World::InterfaceFactory> InterfaceFactories;
+ InterfaceFactories interface_factories;
+
+ typedef bool (*ScriptRunner)(World* world, const char* filename);
+ typedef std::map<const std::string, ScriptRunner> ScriptRunners;
+ ScriptRunners script_runners;
+
+ int& argc;
+ char**& argv;
+ Raul::Configuration* conf;
+ LV2Features* lv2_features;
+ Redland::World* rdf_world;
+ SharedPtr<LV2URIMap> uris;
+ SharedPtr<EngineInterface> engine;
+ SharedPtr<Engine> local_engine;
+ SharedPtr<Serialisation::Serialiser> serialiser;
+ SharedPtr<Serialisation::Parser> parser;
+ SharedPtr<Store> store;
+#ifdef HAVE_SLV2
+ SLV2World slv2_world;
+#endif
+};
+
+
+World::World(Raul::Configuration* conf, int& argc, char**& argv)
+ : _impl(new WorldImpl(conf, argc, argv))
+{
+}
+
+
+World::~World()
+{
+ unload_all();
+ delete _impl;
+}
+
+void World::set_local_engine(SharedPtr<Engine> e) { _impl->local_engine = e; }
+void World::set_engine(SharedPtr<EngineInterface> e) { _impl->engine = e; }
+void World::set_serialiser(SharedPtr<Serialisation::Serialiser> s) { _impl->serialiser = s; }
+void World::set_parser(SharedPtr<Serialisation::Parser> p) { _impl->parser = p; }
+void World::set_store(SharedPtr<Store> s) { _impl->store = s; }
+void World::set_conf(Raul::Configuration* c) { _impl->conf = c; }
+
+int& World::argc() { return _impl->argc; }
+char**& World::argv() { return _impl->argv; }
+SharedPtr<Engine> World::local_engine() { return _impl->local_engine; }
+SharedPtr<EngineInterface> World::engine() { return _impl->engine; }
+SharedPtr<Serialisation::Serialiser> World::serialiser() { return _impl->serialiser; }
+SharedPtr<Serialisation::Parser> World::parser() { return _impl->parser; }
+SharedPtr<Store> World::store() { return _impl->store; }
+Raul::Configuration* World::conf() { return _impl->conf; }
+LV2Features* World::lv2_features() { return _impl->lv2_features; }
+
+#ifdef HAVE_SLV2
+SLV2World World::slv2_world() { return _impl->slv2_world; }
+#endif
+Redland::World* World::rdf_world() { return _impl->rdf_world; }
+SharedPtr<LV2URIMap> World::uris() { return _impl->uris; }
+
+
/** Load an Ingen module.
* @return true on success, false on failure
*/
@@ -97,7 +222,7 @@ World::load(const char* name)
Module* module = module_load();
module->library = lib;
module->load(this);
- modules.insert(make_pair(string(name), module));
+ _impl->modules.insert(make_pair(string(name), module));
return true;
} else {
LOG(error) << "Failed to load module `" << name << "'" << endl;
@@ -111,7 +236,7 @@ World::load(const char* name)
void
World::unload_all()
{
- modules.clear();
+ _impl->modules.clear();
}
@@ -121,8 +246,8 @@ SharedPtr<Ingen::Shared::EngineInterface>
World::interface(const std::string& url)
{
const string scheme = url.substr(0, url.find(":"));
- const InterfaceFactories::const_iterator i = interface_factories.find(scheme);
- if (i == interface_factories.end()) {
+ const WorldImpl::InterfaceFactories::const_iterator i = _impl->interface_factories.find(scheme);
+ if (i == _impl->interface_factories.end()) {
warn << "Unknown URI scheme `" << scheme << "'" << endl;
return SharedPtr<Ingen::Shared::EngineInterface>();
}
@@ -135,8 +260,8 @@ World::interface(const std::string& url)
bool
World::run(const std::string& mime_type, const std::string& filename)
{
- const ScriptRunners::const_iterator i = script_runners.find(mime_type);
- if (i == script_runners.end()) {
+ const WorldImpl::ScriptRunners::const_iterator i = _impl->script_runners.find(mime_type);
+ if (i == _impl->script_runners.end()) {
warn << "Unknown script MIME type `" << mime_type << "'" << endl;
return false;
}
@@ -147,7 +272,7 @@ World::run(const std::string& mime_type, const std::string& filename)
void
World::add_interface_factory(const std::string& scheme, InterfaceFactory factory)
{
- interface_factories.insert(make_pair(scheme, factory));
+ _impl->interface_factories.insert(make_pair(scheme, factory));
}
diff --git a/src/module/World.hpp b/src/module/World.hpp
index fcb48845..a84e2454 100644
--- a/src/module/World.hpp
+++ b/src/module/World.hpp
@@ -21,11 +21,17 @@
#include <map>
#include <string>
#include <boost/shared_ptr.hpp>
+#include <boost/utility.hpp>
#include <glibmm/module.h>
+#include "ingen-config.h"
#include "raul/Configuration.hpp"
+#include "raul/SharedPtr.hpp"
#include "Module.hpp"
+#include "module/ingen_module.hpp"
+#ifdef HAVE_SLV2
typedef struct _SLV2World* SLV2World;
+#endif
namespace Redland { class World; }
@@ -41,6 +47,7 @@ class EngineInterface;
class Store;
class LV2Features;
class LV2URIMap;
+struct WorldImpl;
/** The "world" all Ingen modules may share.
@@ -52,46 +59,53 @@ class LV2URIMap;
* using World::load, e.g. loading the "ingen_serialisation" module will
* set World::serialiser and World::parser to valid objects.
*/
-struct World {
- World() : argc(0), argv(0), conf(0), rdf_world(0), slv2_world(0), lv2_features(0) {}
+class World : public boost::noncopyable {
+ friend Ingen::Shared::World* ::ingen_world_new(Raul::Configuration*, int&, char**&);
+ World(Raul::Configuration* conf, int& argc, char**& argv);
- bool load(const char* name);
- void unload_all();
+ friend void ::ingen_world_free(Ingen::Shared::World* world);
+ virtual ~World();
+
+ WorldImpl* _impl;
+
+public:
+ virtual bool load(const char* name);
+ virtual void unload_all();
typedef SharedPtr<Ingen::Shared::EngineInterface> (*InterfaceFactory)(
World* world, const std::string& engine_url);
- void add_interface_factory(const std::string& scheme, InterfaceFactory factory);
- SharedPtr<Ingen::Shared::EngineInterface> interface(const std::string& engine_url);
+ virtual void add_interface_factory(const std::string& scheme, InterfaceFactory factory);
+ virtual SharedPtr<Ingen::Shared::EngineInterface> interface(const std::string& engine_url);
- bool run(const std::string& mime_type, const std::string& filename);
+ virtual bool run(const std::string& mime_type, const std::string& filename);
- int argc;
- char** argv;
- Raul::Configuration* conf;
+ virtual void set_local_engine(SharedPtr<Engine> e);
+ virtual void set_engine(SharedPtr<EngineInterface> e);
+ virtual void set_serialiser(SharedPtr<Serialisation::Serialiser> s);
+ virtual void set_parser(SharedPtr<Serialisation::Parser> p);
+ virtual void set_store(SharedPtr<Store> s);
- Redland::World* rdf_world;
- SLV2World slv2_world;
- LV2Features* lv2_features;
+ virtual SharedPtr<Engine> local_engine();
+ virtual SharedPtr<EngineInterface> engine();
+ virtual SharedPtr<Serialisation::Serialiser> serialiser();
+ virtual SharedPtr<Serialisation::Parser> parser();
+ virtual SharedPtr<Store> store();
- boost::shared_ptr<LV2URIMap> uris;
+ virtual Redland::World* rdf_world();
+ virtual SharedPtr<LV2URIMap> uris();
- boost::shared_ptr<EngineInterface> engine;
- boost::shared_ptr<Engine> local_engine;
- boost::shared_ptr<Serialisation::Serialiser> serialiser;
- boost::shared_ptr<Serialisation::Parser> parser;
- boost::shared_ptr<Store> store;
+ virtual int& argc();
+ virtual char**& argv();
-private:
- typedef std::map< const std::string, boost::shared_ptr<Module> > Modules;
- Modules modules;
+ virtual Raul::Configuration* conf();
+ virtual void set_conf(Raul::Configuration* c);
- typedef std::map<const std::string, InterfaceFactory> InterfaceFactories;
- InterfaceFactories interface_factories;
+ virtual LV2Features* lv2_features();
- typedef bool (*ScriptRunner)(World* world, const char* filename);
- typedef std::map<const std::string, ScriptRunner> ScriptRunners;
- ScriptRunners script_runners;
+#ifdef HAVE_SLV2
+ virtual SLV2World slv2_world();
+#endif
};
diff --git a/src/module/ingen_module.cpp b/src/module/ingen_module.cpp
index 167fd0f2..140aec2e 100644
--- a/src/module/ingen_module.cpp
+++ b/src/module/ingen_module.cpp
@@ -28,46 +28,16 @@
extern "C" {
-static Ingen::Shared::World* world = NULL;
-
Ingen::Shared::World*
-ingen_get_world()
+ingen_world_new(Raul::Configuration* conf, int& argc, char**& argv)
{
- static Ingen::Shared::World* world = NULL;
-
- if (!world) {
- world = new Ingen::Shared::World();
- world->rdf_world = new Redland::World();
-#ifdef HAVE_SLV2
- world->slv2_world = slv2_world_new_using_rdf_world(world->rdf_world->world());
- world->lv2_features = new Ingen::Shared::LV2Features();
- world->uris = PtrCast<Ingen::Shared::LV2URIMap>(
- world->lv2_features->feature(LV2_URI_MAP_URI));
- slv2_world_load_all(world->slv2_world);
-#else
- world->uris = SharedPtr<Ingen::Shared::LV2URIMap>(
- new Ingen::Shared::LV2URIMap());
-#endif
- world->engine.reset();
- world->local_engine.reset();
- }
-
- return world;
+ return new Ingen::Shared::World(conf, argc, argv);
}
void
-ingen_destroy_world()
+ingen_world_free(Ingen::Shared::World* world)
{
- if (world) {
- world->unload_all();
-#ifdef HAVE_SLV2
- slv2_world_free(world->slv2_world);
- delete world->lv2_features;
-#endif
- delete world->rdf_world;
- delete world;
- world = NULL;
- }
+ delete world;
}
} // extern "C"
diff --git a/src/module/ingen_module.hpp b/src/module/ingen_module.hpp
index bb2c3adb..0fd921f7 100644
--- a/src/module/ingen_module.hpp
+++ b/src/module/ingen_module.hpp
@@ -18,12 +18,14 @@
#ifndef INGEN_MODULE_HPP
#define INGEN_MODULE_HPP
+namespace Raul { class Configuration; }
+
namespace Ingen { namespace Shared { class World; } }
extern "C" {
-Ingen::Shared::World* ingen_get_world();
-void ingen_destroy_world();
+Ingen::Shared::World* ingen_world_new(Raul::Configuration* conf, int& argc, char**& argv);
+void ingen_world_free(Ingen::Shared::World* world);
} // extern "C"
diff --git a/src/serialisation/Parser.cpp b/src/serialisation/Parser.cpp
index 9fe1d036..720134e8 100644
--- a/src/serialisation/Parser.cpp
+++ b/src/serialisation/Parser.cpp
@@ -71,6 +71,31 @@ normalise_uri(Glib::ustring& uri)
}
+Parser::PatchRecords
+Parser::find_patches(
+ Ingen::Shared::World* world,
+ const Glib::ustring& manifest_uri)
+{
+ Redland::Model model(*world->rdf_world(), manifest_uri, manifest_uri);
+ Redland::Query query(*world->rdf_world(),
+ "SELECT DISTINCT ?patch ?file WHERE {\n"
+ "?patch a ingen:Patch ;\n"
+ " rdfs:seeAlso ?file .\n"
+ "}");
+
+ std::list<PatchRecord> records;
+
+ Redland::Query::Results results(query.run(*world->rdf_world(), model, manifest_uri));
+ for (Redland::Query::Results::iterator i = results.begin(); i != results.end(); ++i) {
+ const Redland::Node& patch((*i)["patch"]);
+ const Redland::Node& file((*i)["file"]);
+ records.push_back(PatchRecord(patch.to_c_string(), file.to_c_string()));
+ }
+
+ return records;
+}
+
+
/** Parse a patch from RDF into a CommonInterface (engine or client).
* @return whether or not load was successful.
*/
@@ -96,7 +121,7 @@ Parser::parse_document(
document_uri += "/" + basename + INGEN_PATCH_FILE_EXT;
}
- Redland::Model model(*world->rdf_world, document_uri, document_uri);
+ Redland::Model model(*world->rdf_world(), document_uri, document_uri);
LOG(info) << "Parsing " << document_uri << endl;
if (data_path)
@@ -131,7 +156,7 @@ Parser::parse_string(
boost::optional<Raul::Symbol> symbol,
boost::optional<GraphObject::Properties> data)
{
- Redland::Model model(*world->rdf_world, str.c_str(), str.length(), base_uri);
+ Redland::Model model(*world->rdf_world(), str.c_str(), str.length(), base_uri);
LOG(info) << "Parsing " << (data_path ? data_path->str() : "*") << " from string";
if (!base_uri.empty())
@@ -139,7 +164,7 @@ Parser::parse_string(
info << endl;
bool ret = parse(world, target, model, base_uri, data_path, parent, symbol, data);
- Redland::Resource subject(*world->rdf_world, base_uri);
+ Redland::Resource subject(*world->rdf_world(), base_uri);
parse_connections(world, target, model, subject, parent ? *parent : "/");
return ret;
@@ -157,14 +182,12 @@ Parser::parse_update(
boost::optional<Raul::Symbol> symbol,
boost::optional<GraphObject::Properties> data)
{
- Redland::Model model(*world->rdf_world, str.c_str(), str.length(), base_uri);
-
- std::cout << "PARSE UPDATE " << str << endl;
+ Redland::Model model(*world->rdf_world(), str.c_str(), str.length(), base_uri);
// Delete anything explicitly declared to not exist
Glib::ustring query_str = Glib::ustring("SELECT DISTINCT ?o WHERE { ?o a owl:Nothing }");
- Redland::Query query(*world->rdf_world, query_str);
- Redland::Query::Results results = query.run(*world->rdf_world, model, base_uri);
+ Redland::Query query(*world->rdf_world(), query_str);
+ Redland::Query::Results results = query.run(*world->rdf_world(), model, base_uri);
for (Redland::Query::Results::iterator i = results.begin(); i != results.end(); ++i) {
const Redland::Node& object = (*i)["o"];
@@ -172,15 +195,15 @@ Parser::parse_update(
}
// Properties
- query = Redland::Query(*world->rdf_world,
+ query = Redland::Query(*world->rdf_world(),
"SELECT DISTINCT ?s ?p ?o WHERE {\n"
"?s ?p ?o .\n"
"}");
- results = Redland::Query::Results(query.run(*world->rdf_world, model, base_uri));
+ results = Redland::Query::Results(query.run(*world->rdf_world(), model, base_uri));
for (Redland::Query::Results::iterator i = results.begin(); i != results.end(); ++i) {
- Glib::Mutex::Lock lock(world->rdf_world->mutex());
+ Glib::Mutex::Lock lock(world->rdf_world()->mutex());
string obj_uri((*i)["s"].to_string());
const string key((*i)["p"].to_string());
const Redland::Node& val_node((*i)["o"]);
@@ -194,23 +217,23 @@ Parser::parse_update(
// Connections
- Redland::Resource subject(*world->rdf_world, base_uri);
+ Redland::Resource subject(*world->rdf_world(), base_uri);
parse_connections(world, target, model, subject, "/");
// Port values
- query = Redland::Query(*world->rdf_world,
+ query = Redland::Query(*world->rdf_world(),
"SELECT DISTINCT ?path ?value WHERE {\n"
"?path ingen:value ?value .\n"
"}");
- results = Redland::Query::Results(query.run(*world->rdf_world, model, base_uri));
+ results = Redland::Query::Results(query.run(*world->rdf_world(), model, base_uri));
for (Redland::Query::Results::iterator i = results.begin(); i != results.end(); ++i) {
- Glib::Mutex::Lock lock(world->rdf_world->mutex());
+ Glib::Mutex::Lock lock(world->rdf_world()->mutex());
const string obj_path = (*i)["path"].to_string();
const Redland::Node& val_node = (*i)["value"];
const Atom a(AtomRDF::node_to_atom(model, val_node));
- target->set_property(obj_path, world->uris->ingen_value, a);
+ target->set_property(obj_path, world->uris()->ingen_value, a);
}
return parse(world, target, model, base_uri, data_path, parent, symbol, data);
@@ -234,22 +257,22 @@ Parser::parse(
? Glib::ustring("SELECT DISTINCT ?t WHERE { <") + data_path->chop_start("/") + "> a ?t . }"
: Glib::ustring("SELECT DISTINCT ?s ?t WHERE { ?s a ?t . }");
- Redland::Query query(*world->rdf_world, query_str);
- Redland::Query::Results results(query.run(*world->rdf_world, model, document_uri));
+ Redland::Query query(*world->rdf_world(), query_str);
+ Redland::Query::Results results(query.run(*world->rdf_world(), model, document_uri));
#define NS_INGEN "http://drobilla.net/ns/ingen#"
#define NS_LV2 "http://lv2plug.in/ns/lv2core#"
- const Redland::Node patch_class (*world->rdf_world, res, NS_INGEN "Patch");
- const Redland::Node node_class (*world->rdf_world, res, NS_INGEN "Node");
- const Redland::Node internal_class (*world->rdf_world, res, NS_INGEN "Internal");
- const Redland::Node ladspa_class (*world->rdf_world, res, NS_INGEN "LADSPAPlugin");
- const Redland::Node in_port_class (*world->rdf_world, res, NS_LV2 "InputPort");
- const Redland::Node out_port_class (*world->rdf_world, res, NS_LV2 "OutputPort");
- const Redland::Node lv2_class (*world->rdf_world, res, NS_LV2 "Plugin");
+ const Redland::Node patch_class (*world->rdf_world(), res, NS_INGEN "Patch");
+ const Redland::Node node_class (*world->rdf_world(), res, NS_INGEN "Node");
+ const Redland::Node internal_class (*world->rdf_world(), res, NS_INGEN "Internal");
+ const Redland::Node ladspa_class (*world->rdf_world(), res, NS_INGEN "LADSPAPlugin");
+ const Redland::Node in_port_class (*world->rdf_world(), res, NS_LV2 "InputPort");
+ const Redland::Node out_port_class (*world->rdf_world(), res, NS_LV2 "OutputPort");
+ const Redland::Node lv2_class (*world->rdf_world(), res, NS_LV2 "Plugin");
const Redland::Node subject_node = (data_path && !data_path->is_root())
- ? Redland::Node(*world->rdf_world, res, data_path->chop_start("/"))
+ ? Redland::Node(*world->rdf_world(), res, data_path->chop_start("/"))
: model.base_uri();
std::string path_str;
@@ -298,6 +321,7 @@ Parser::parse(
ret = parse_node(world, target, model, subject, path, data);
} else if (rdf_class == in_port_class || rdf_class == out_port_class) {
parse_properties(world, target, model, subject, path, data);
+ ret = path;
}
if (!ret) {
@@ -333,7 +357,7 @@ Parser::parse_patch(
boost::optional<Raul::Symbol> a_symbol,
boost::optional<GraphObject::Properties> data)
{
- const LV2URIMap& uris = *world->uris.get();
+ const LV2URIMap& uris = *world->uris().get();
uint32_t patch_poly = 0;
typedef Redland::Query::Results Results;
@@ -349,10 +373,10 @@ Parser::parse_patch(
/* Load polyphony from file if necessary */
if (patch_poly == 0) {
- Redland::Query query(*world->rdf_world, Glib::ustring(
+ Redland::Query query(*world->rdf_world(), Glib::ustring(
"SELECT DISTINCT ?poly WHERE { ") + subject + " ingen:polyphony ?poly }");
- Results results = query.run(*world->rdf_world, model);
+ Results results = query.run(*world->rdf_world(), model);
if (results.size() > 0) {
const Redland::Node& poly_node = (*results.begin())["poly"];
if (poly_node.is_int())
@@ -395,14 +419,14 @@ Parser::parse_patch(
/* Find patches in document */
- Redland::Query query(*world->rdf_world, Glib::ustring(
+ Redland::Query query(*world->rdf_world(), Glib::ustring(
"SELECT DISTINCT ?patch WHERE {\n") +
"?patch a ingen:Patch .\n"
"}");
set<string> patches;
- Results results = query.run(*world->rdf_world, model, base_uri);
+ Results results = query.run(*world->rdf_world(), model, base_uri);
for (Results::iterator i = results.begin(); i != results.end(); ++i) {
- Glib::Mutex::Lock lock(world->rdf_world->mutex());
+ Glib::Mutex::Lock lock(world->rdf_world()->mutex());
patches.insert((*i)["patch"].to_string());
}
@@ -413,7 +437,7 @@ Parser::parse_patch(
/* Find nodes on this patch */
- query = Redland::Query(*world->rdf_world, Glib::ustring(
+ query = Redland::Query(*world->rdf_world(), Glib::ustring(
"SELECT DISTINCT ?node ?type WHERE {\n") +
subject + " ingen:node ?node .\n"
"?node rdf:instanceOf ?type .\n"
@@ -422,9 +446,9 @@ Parser::parse_patch(
Objects plugin_nodes;
Resources resources;
Types types;
- results = query.run(*world->rdf_world, model, base_uri);
+ results = query.run(*world->rdf_world(), model, base_uri);
for (Results::iterator i = results.begin(); i != results.end(); ++i) {
- Glib::Mutex::Lock lock(world->rdf_world->mutex());
+ Glib::Mutex::Lock lock(world->rdf_world()->mutex());
Redland::Node& node = (*i)["node"];
Redland::Node& type = (*i)["type"];
if (node.type() == Redland::Node::RESOURCE && type.type() == Redland::Node::RESOURCE) {
@@ -440,14 +464,14 @@ Parser::parse_patch(
/* Load nodes on this patch */
- query = Redland::Query(*world->rdf_world, Glib::ustring(
+ query = Redland::Query(*world->rdf_world(), Glib::ustring(
"SELECT DISTINCT ?node ?predicate ?object WHERE {\n") +
subject + " ingen:node ?node .\n"
"?node ?predicate ?object .\n"
"}");
- results = query.run(*world->rdf_world, model, base_uri);
+ results = query.run(*world->rdf_world(), model, base_uri);
for (Results::iterator i = results.begin(); i != results.end(); ++i) {
- Glib::Mutex::Lock lock(world->rdf_world->mutex());
+ Glib::Mutex::Lock lock(world->rdf_world()->mutex());
Redland::Node& node = (*i)["node"];
Redland::Node& predicate = (*i)["predicate"];
Redland::Node& object = (*i)["object"];
@@ -478,7 +502,7 @@ Parser::parse_patch(
if (res_i == resources.end())
continue;
parse_patch(world, target, model, res_i->second, patch_path, Symbol(node_path.symbol()));
- Glib::Mutex::Lock lock(world->rdf_world->mutex());
+ Glib::Mutex::Lock lock(world->rdf_world()->mutex());
target->put(node_path, i->second);
}
@@ -497,16 +521,16 @@ Parser::parse_patch(
/* Load node ports */
- query = Redland::Query(*world->rdf_world, Glib::ustring(
+ query = Redland::Query(*world->rdf_world(), Glib::ustring(
"SELECT DISTINCT ?node ?port ?key ?val WHERE {\n") +
subject + " ingen:node ?node .\n"
"?node lv2:port ?port .\n"
"?port ?key ?val .\n"
"}");
Objects node_ports;
- results = query.run(*world->rdf_world, model, base_uri);
+ results = query.run(*world->rdf_world(), model, base_uri);
for (Results::iterator i = results.begin(); i != results.end(); ++i) {
- Glib::Mutex::Lock lock(world->rdf_world->mutex());
+ Glib::Mutex::Lock lock(world->rdf_world()->mutex());
const string node_uri = (*i)["node"].to_string();
const string port_uri = (*i)["port"].to_string();
if (port_uri.length() <= node_uri.length()) {
@@ -531,15 +555,15 @@ Parser::parse_patch(
/* Find ports on this patch */
- query = Redland::Query(*world->rdf_world, Glib::ustring(
+ query = Redland::Query(*world->rdf_world(), Glib::ustring(
"SELECT DISTINCT ?port ?type WHERE {\n") +
subject + " lv2:port ?port .\n"
"?port rdf:instanceOf ?type .\n"
"}");
Objects patch_ports;
- results = query.run(*world->rdf_world, model, base_uri);
+ results = query.run(*world->rdf_world(), model, base_uri);
for (Results::iterator i = results.begin(); i != results.end(); ++i) {
- Glib::Mutex::Lock lock(world->rdf_world->mutex());
+ Glib::Mutex::Lock lock(world->rdf_world()->mutex());
Redland::Node& port = (*i)["port"];
Redland::Node& type = (*i)["type"];
if (port.type() == Redland::Node::RESOURCE && type.type() == Redland::Node::RESOURCE) {
@@ -550,14 +574,14 @@ Parser::parse_patch(
/* Load patch ports */
- query = Redland::Query(*world->rdf_world, Glib::ustring(
+ query = Redland::Query(*world->rdf_world(), Glib::ustring(
"SELECT DISTINCT ?port ?key ?val WHERE {\n") +
subject + " lv2:port ?port .\n"
"?port ?key ?val .\n"
"}");
- results = query.run(*world->rdf_world, model, base_uri);
+ results = query.run(*world->rdf_world(), model, base_uri);
for (Results::iterator i = results.begin(); i != results.end(); ++i) {
- Glib::Mutex::Lock lock(world->rdf_world->mutex());
+ Glib::Mutex::Lock lock(world->rdf_world()->mutex());
const string port_uri = (*i)["port"].to_string();
const Path port_path = patch_path.child(relative_uri(base_uri, port_uri, false));
const string key = (*i)["key"].to_string();
@@ -603,7 +627,7 @@ Parser::parse_patch(
for (uint32_t index = 0; index < patch_ports.size(); ++index) {
Objects::iterator i = ports_by_index[index];
- Glib::Mutex::Lock lock(world->rdf_world->mutex());
+ Glib::Mutex::Lock lock(world->rdf_world()->mutex());
const Path port_path = patch_path.child(relative_uri(base_uri, i->first, false));
std::pair<Properties::iterator,Properties::iterator> types_range
= i->second.equal_range(uris.rdf_type);
@@ -641,14 +665,14 @@ Parser::parse_patch(
/* Enable */
- query = Redland::Query(*world->rdf_world, Glib::ustring(
+ query = Redland::Query(*world->rdf_world(), Glib::ustring(
"SELECT DISTINCT ?enabled WHERE {\n")
+ subject + " ingen:enabled ?enabled .\n"
"}");
- results = query.run(*world->rdf_world, model, base_uri);
+ results = query.run(*world->rdf_world(), model, base_uri);
for (Results::iterator i = results.begin(); i != results.end(); ++i) {
- Glib::Mutex::Lock lock(world->rdf_world->mutex());
+ Glib::Mutex::Lock lock(world->rdf_world()->mutex());
const Redland::Node& enabled_node = (*i)["enabled"];
if (enabled_node.is_bool() && enabled_node) {
target->set_property(patch_path, uris.ingen_enabled, (bool)true);
@@ -671,15 +695,15 @@ Parser::parse_node(
const Raul::Path& path,
boost::optional<GraphObject::Properties> data)
{
- const LV2URIMap& uris = *world->uris.get();
+ const LV2URIMap& uris = *world->uris().get();
/* Get plugin */
- Redland::Query query(*world->rdf_world, Glib::ustring(
+ Redland::Query query(*world->rdf_world(), Glib::ustring(
"SELECT DISTINCT ?plug WHERE {\n")
+ subject.to_turtle_token() + " rdf:instanceOf ?plug .\n"
"}");
- Redland::Query::Results results = query.run(*world->rdf_world, model);
+ Redland::Query::Results results = query.run(*world->rdf_world(), model);
if (results.size() == 0) {
LOG(error) << "Node missing mandatory rdf:instanceOf property" << endl;
@@ -692,7 +716,7 @@ Parser::parse_node(
return boost::optional<Path>();
}
- const string plugin_uri = world->rdf_world->expand_uri(plugin_node.to_c_string());
+ const string plugin_uri = world->rdf_world()->expand_uri(plugin_node.to_c_string());
Resource::Properties props;
props.insert(make_pair(uris.rdf_type, Raul::URI(uris.ingen_Node)));
props.insert(make_pair(uris.rdf_instanceOf, Raul::Atom(Raul::Atom::URI, plugin_uri)));
@@ -711,7 +735,7 @@ Parser::parse_connections(
const Redland::Node& subject,
const Raul::Path& parent)
{
- Redland::Query query(*world->rdf_world, Glib::ustring(
+ Redland::Query query(*world->rdf_world(), Glib::ustring(
"SELECT DISTINCT ?src ?dst WHERE {\n")
+ subject.to_turtle_token() + " ingen:connection ?connection .\n"
"?connection ingen:source ?src ;\n"
@@ -720,9 +744,9 @@ Parser::parse_connections(
const Glib::ustring& base_uri = model.base_uri().to_string();
- Redland::Query::Results results = query.run(*world->rdf_world, model);
+ Redland::Query::Results results = query.run(*world->rdf_world(), model);
for (Redland::Query::Results::iterator i = results.begin(); i != results.end(); ++i) {
- Glib::Mutex::Lock lock(world->rdf_world->mutex());
+ Glib::Mutex::Lock lock(world->rdf_world()->mutex());
const Path src_path(parent.child(relative_uri(base_uri, (*i)["src"].to_string(), false)));
const Path dst_path(parent.child(relative_uri(base_uri, (*i)["dst"].to_string(), false)));
target->connect(src_path, dst_path);
@@ -743,15 +767,15 @@ Parser::parse_properties(
{
const Glib::ustring& subject = subject_node.to_turtle_token();
- Redland::Query query(*world->rdf_world, Glib::ustring(
+ Redland::Query query(*world->rdf_world(), Glib::ustring(
"SELECT DISTINCT ?key ?val WHERE {\n") +
subject + " ?key ?val .\n"
"}");
Resource::Properties properties;
- Redland::Query::Results results = query.run(*world->rdf_world, model);
+ Redland::Query::Results results = query.run(*world->rdf_world(), model);
for (Redland::Query::Results::iterator i = results.begin(); i != results.end(); ++i) {
- Glib::Mutex::Lock lock(world->rdf_world->mutex());
+ Glib::Mutex::Lock lock(world->rdf_world()->mutex());
const string key = string((*i)["key"]);
const Redland::Node& val = (*i)["val"];
if (skip_property((*i)["key"]))
diff --git a/src/serialisation/Parser.hpp b/src/serialisation/Parser.hpp
index cd96bd0b..aeda022f 100644
--- a/src/serialisation/Parser.hpp
+++ b/src/serialisation/Parser.hpp
@@ -19,6 +19,7 @@
#define INGEN_SERIALISATION_LOADER_HPP
#include <string>
+#include <list>
#include <glibmm/ustring.h>
#include <boost/optional.hpp>
#include "interface/GraphObject.hpp"
@@ -69,6 +70,18 @@ public:
boost::optional<Raul::Symbol> symbol=boost::optional<Raul::Symbol>(),
boost::optional<Properties> data=boost::optional<Properties>());
+ struct PatchRecord {
+ PatchRecord(const Raul::URI& u, const Glib::ustring& f) : uri(u), filename(f) {}
+ const Raul::URI uri;
+ const Glib::ustring filename;
+ };
+
+ typedef std::list<PatchRecord> PatchRecords;
+
+ virtual PatchRecords find_patches(
+ Ingen::Shared::World* world,
+ const Glib::ustring& manifest_uri);
+
private:
boost::optional<Raul::Path> parse(
Ingen::Shared::World* world,
diff --git a/src/serialisation/Serialiser.cpp b/src/serialisation/Serialiser.cpp
index 735f9788..5f02d9cc 100644
--- a/src/serialisation/Serialiser.cpp
+++ b/src/serialisation/Serialiser.cpp
@@ -29,6 +29,8 @@
#include <glib.h>
#include <glib/gstdio.h>
#include <glibmm/convert.h>
+#include <glibmm/miscutils.h>
+#include <glibmm/fileutils.h>
#include "raul/log.hpp"
#include "raul/Atom.hpp"
#include "raul/AtomRDF.hpp"
@@ -101,19 +103,26 @@ void
Serialiser::write_manifest(const std::string& bundle_uri,
const Records& records)
{
- const string filename = Glib::filename_from_uri(bundle_uri) + "manifest.ttl";
+ const string bundle_path(Glib::filename_from_uri(bundle_uri));
+ const string filename(Glib::build_filename(bundle_path, "manifest.ttl"));
start_to_filename(filename);
_model->set_base_uri(bundle_uri);
for (Records::const_iterator i = records.begin(); i != records.end(); ++i) {
SharedPtr<Patch> patch = PtrCast<Patch>(i->object);
if (patch) {
- const Redland::Resource subject(_model->world(), uri_to_symbol(i->uri));
+ const std::string filename = uri_to_symbol(i->uri) + INGEN_PATCH_FILE_EXT;
+ const Redland::Resource subject(_model->world(), filename);
_model->add_statement(subject, "rdf:type",
Redland::Resource(_model->world(), "ingen:Patch"));
_model->add_statement(subject, "rdf:type",
Redland::Resource(_model->world(), "lv2:Plugin"));
_model->add_statement(subject, "rdfs:seeAlso",
- Redland::Resource(_model->world(), i->uri));
+ Redland::Resource(_model->world(), filename));
+ _model->add_statement(subject, "lv2:binary",
+ Redland::Resource(_model->world(),
+ Glib::Module::build_path("", "ingen_lv2")));
+ symlink(Glib::Module::build_path(INGEN_MODULE_DIR, "ingen_lv2").c_str(),
+ Glib::Module::build_path(bundle_path, "ingen_lv2").c_str());
}
}
finish();
@@ -178,7 +187,7 @@ Serialiser::start_to_filename(const string& filename)
_base_uri = "file://" + filename;
else
_base_uri = filename;
- _model = new Redland::Model(*_world.rdf_world);
+ _model = new Redland::Model(*_world.rdf_world());
_model->set_base_uri(_base_uri);
_mode = TO_FILE;
}
@@ -201,7 +210,7 @@ Serialiser::start_to_string(const Raul::Path& root, const string& base_uri)
_root_path = root;
_base_uri = base_uri;
- _model = new Redland::Model(*_world.rdf_world);
+ _model = new Redland::Model(*_world.rdf_world());
_model->set_base_uri(base_uri);
_mode = TO_STRING;
}
@@ -310,19 +319,27 @@ Serialiser::serialise_patch(SharedPtr<Shared::Patch> patch, const Redland::Node&
_model->add_statement(patch_id, "rdf:type",
Redland::Resource(_model->world(), "lv2:Plugin"));
- GraphObject::Properties::const_iterator s = patch->properties().find("lv2:symbol");
- // If symbol is stored as a property, write that
- if (s != patch->properties().end() && s->second.is_valid()) {
- _model->add_statement(patch_id, "lv2:symbol",
- Redland::Literal(_model->world(), s->second.get_string()));
- // Otherwise take the one from our path (if possible)
- } else if (!patch->path().is_root()) {
- _model->add_statement(patch_id, "lv2:symbol",
- Redland::Literal(_model->world(), patch->path().symbol()));
+ const LV2URIMap& uris = *_world.uris().get();
+
+ // Always write a symbol (required by Ingen)
+ string symbol;
+ GraphObject::Properties::const_iterator s = patch->properties().find(uris.lv2_symbol);
+ if (s == patch->properties().end()
+ || !s->second.type() == Atom::STRING
+ || !Symbol::is_valid(s->second.get_string())) {
+ symbol = Glib::path_get_basename(Glib::filename_from_uri(_model->base_uri().to_c_string()));
+ symbol = Symbol::symbolify(symbol.substr(0, symbol.find('.')));
+ _model->add_statement(patch_id, uris.lv2_symbol.c_str(),
+ Redland::Literal(_model->world(), symbol));
} else {
- LOG(warn) << "Patch has no lv2:symbol" << endl;
+ symbol = s->second.get_string();
}
+ // If the patch has no doap:name (required by LV2), use the symbol
+ if (patch->meta().properties().find(uris.doap_name) == patch->meta().properties().end())
+ _model->add_statement(patch_id, uris.doap_name.c_str(),
+ Redland::Literal(_model->world(), symbol));
+
serialise_properties(patch_id, NULL, patch->meta().properties());
for (Store::const_iterator n = _store->children_begin(patch);
@@ -427,6 +444,9 @@ Serialiser::serialise_port(const Port* port, const Redland::Node& port_id)
_model->add_statement(port_id, "rdf:instanceOf",
class_rdf_node(port->path()));
+ _model->add_statement(port_id, "lv2:symbol",
+ Redland::Literal(_model->world(), port->path().symbol()));
+
serialise_properties(port_id, &port->meta(), port->properties());
}
@@ -450,6 +470,9 @@ Serialiser::serialise_port_meta(const Port* port, const Redland::Node& port_id)
_model->add_statement(port_id, "lv2:index",
AtomRDF::atom_to_node(*_model, Atom((int)port->index())));
+ _model->add_statement(port_id, "lv2:symbol",
+ Redland::Literal(_model->world(), port->path().symbol()));
+
if (!port->get_property("http://lv2plug.in/ns/lv2core#default").is_valid()) {
if (port->is_input()) {
if (port->value().is_valid()) {
@@ -480,7 +503,7 @@ Serialiser::serialise_connection(SharedPtr<GraphObject> parent,
? instance_rdf_node(connection->dst_port_path())
: class_rdf_node(connection->dst_port_path());
- const Redland::Node connection_node = _world.rdf_world->blank_id();
+ const Redland::Node connection_node = _world.rdf_world()->blank_id();
_model->add_statement(connection_node, "ingen:source", src_node);
_model->add_statement(connection_node, "ingen:destination", dst_node);
if (parent) {
diff --git a/src/serialisation/serialisation.cpp b/src/serialisation/serialisation.cpp
index a453f000..b9a21670 100644
--- a/src/serialisation/serialisation.cpp
+++ b/src/serialisation/serialisation.cpp
@@ -25,10 +25,10 @@ using namespace Ingen;
struct IngenModule : public Shared::Module {
void load(Shared::World* world) {
- world->parser = SharedPtr<Serialisation::Parser>(
- new Serialisation::Parser());
- world->serialiser = SharedPtr<Serialisation::Serialiser>(
- new Serialisation::Serialiser(*world, world->store));
+ world->set_parser(SharedPtr<Serialisation::Parser>(
+ new Serialisation::Parser()));
+ world->set_serialiser(SharedPtr<Serialisation::Serialiser>(
+ new Serialisation::Serialiser(*world, world->store())));
}
};
diff --git a/src/shared/Builder.cpp b/src/shared/Builder.cpp
index 0cc4e980..72e90ad1 100644
--- a/src/shared/Builder.cpp
+++ b/src/shared/Builder.cpp
@@ -32,8 +32,9 @@ namespace Ingen {
namespace Shared {
-Builder::Builder(CommonInterface& interface)
- : _interface(interface)
+Builder::Builder(SharedPtr<Shared::LV2URIMap> uris, CommonInterface& interface)
+ : _uris(uris)
+ , _interface(interface)
{
}
@@ -41,7 +42,7 @@ Builder::Builder(CommonInterface& interface)
void
Builder::build(SharedPtr<const GraphObject> object)
{
- const LV2URIMap& uris = Shared::LV2URIMap::instance();
+ const LV2URIMap& uris = *_uris.get();
SharedPtr<const Patch> patch = PtrCast<const Patch>(object);
if (patch) {
if (!object->path().is_root()) {
diff --git a/src/shared/Builder.hpp b/src/shared/Builder.hpp
index ec953d41..b77201dd 100644
--- a/src/shared/Builder.hpp
+++ b/src/shared/Builder.hpp
@@ -25,8 +25,9 @@ namespace Raul { class Path; }
namespace Ingen {
namespace Shared {
-class GraphObject;
class CommonInterface;
+class GraphObject;
+class LV2URIMap;
/** Wrapper for CommonInterface to create existing objects/models.
@@ -36,7 +37,7 @@ class CommonInterface;
class Builder
{
public:
- Builder(CommonInterface& interface);
+ Builder(SharedPtr<Shared::LV2URIMap> uris, CommonInterface& interface);
virtual ~Builder() {}
void build(SharedPtr<const GraphObject> object);
@@ -45,7 +46,8 @@ public:
private:
void build_object(SharedPtr<const GraphObject> object);
- CommonInterface& _interface;
+ SharedPtr<Shared::LV2URIMap> _uris;
+ CommonInterface& _interface;
};
diff --git a/src/shared/LV2Features.cpp b/src/shared/LV2Features.cpp
index 5088d6e0..21d6039e 100644
--- a/src/shared/LV2Features.cpp
+++ b/src/shared/LV2Features.cpp
@@ -28,7 +28,6 @@ namespace Shared {
LV2Features::LV2Features()
{
- add_feature(LV2_URI_MAP_URI, SharedPtr<Feature>(new LV2URIMap()));
}
diff --git a/src/shared/LV2Object.cpp b/src/shared/LV2Object.cpp
index 252972ff..4388ede8 100644
--- a/src/shared/LV2Object.cpp
+++ b/src/shared/LV2Object.cpp
@@ -32,10 +32,8 @@ namespace LV2Object {
bool
-to_atom(const LV2_Object* object, Raul::Atom& atom)
+to_atom(const Shared::LV2URIMap& uris, const LV2_Object* object, Raul::Atom& atom)
{
- const LV2URIMap& uris = Shared::LV2URIMap::instance();
-
if (object->type == uris.object_class_string.id) {
atom = Raul::Atom((char*)(object + 1));
return true;
@@ -57,10 +55,8 @@ to_atom(const LV2_Object* object, Raul::Atom& atom)
* object->size should be the capacity of the object (not including header)
*/
bool
-from_atom(const Raul::Atom& atom, LV2_Object* object)
+from_atom(const Shared::LV2URIMap& uris, const Raul::Atom& atom, LV2_Object* object)
{
- const LV2URIMap& uris = Shared::LV2URIMap::instance();
-
char* str;
switch (atom.type()) {
case Raul::Atom::FLOAT:
diff --git a/src/shared/LV2Object.hpp b/src/shared/LV2Object.hpp
index 794422a0..bec2ff89 100644
--- a/src/shared/LV2Object.hpp
+++ b/src/shared/LV2Object.hpp
@@ -25,11 +25,12 @@ namespace Ingen {
namespace Shared {
class World;
+class LV2URIMap;
namespace LV2Object {
- bool to_atom(const LV2_Object* object, Raul::Atom& atom);
- bool from_atom(const Raul::Atom& atom, LV2_Object* object);
+ bool to_atom(const Shared::LV2URIMap& uris, const LV2_Object* object, Raul::Atom& atom);
+ bool from_atom(const Shared::LV2URIMap& uris, const Raul::Atom& atom, LV2_Object* object);
} // namespace LV2Object
diff --git a/src/shared/LV2URIMap.cpp b/src/shared/LV2URIMap.cpp
index d8114014..e069a644 100644
--- a/src/shared/LV2URIMap.cpp
+++ b/src/shared/LV2URIMap.cpp
@@ -19,11 +19,10 @@
#include <cassert>
#include <stdint.h>
#include <glib.h>
+#include <boost/shared_ptr.hpp>
#include "raul/log.hpp"
#include "object.lv2/object.h"
#include "LV2URIMap.hpp"
-#include "module/ingen_module.hpp"
-#include "module/World.hpp"
using namespace std;
using namespace Raul;
@@ -38,6 +37,12 @@ LV2URIMap::Quark::Quark(const char* c_str)
{
}
+const char*
+LV2URIMap::Quark::c_str() const
+{
+ return g_quark_to_string(id);
+}
+
#define NS_CTX "http://lv2plug.in/ns/dev/contexts#"
#define NS_INGEN "http://drobilla.net/ns/ingen#"
#define NS_INGENUI "http://drobilla.net/ns/ingenuity#"
@@ -114,23 +119,14 @@ LV2URIMap::LV2URIMap()
}
-const LV2URIMap&
-LV2URIMap::instance()
-{
- return *ingen_get_world()->uris;
-}
+struct null_deleter { void operator()(void const *) const {} };
uint32_t
LV2URIMap::uri_to_id(const char* map,
const char* uri)
{
- const uint32_t ret = static_cast<uint32_t>(g_quark_from_string(uri));
- debug << "[LV2URIMap] ";
- if (map)
- debug << map << " : ";
- debug << uri << " => " << ret << endl;
- return ret;
+ return static_cast<uint32_t>(g_quark_from_string(uri));
}
diff --git a/src/shared/LV2URIMap.hpp b/src/shared/LV2URIMap.hpp
index 2c5bdef2..30203de7 100644
--- a/src/shared/LV2URIMap.hpp
+++ b/src/shared/LV2URIMap.hpp
@@ -38,9 +38,7 @@ public:
return SharedPtr<LV2_Feature>(&uri_map_feature, NullDeleter<LV2_Feature>);
}
- uint32_t uri_to_id(const char* map, const char* uri);
-
- static const LV2URIMap& instance();
+ virtual uint32_t uri_to_id(const char* map, const char* uri);
private:
static uint32_t uri_map_uri_to_id(LV2_URI_Map_Callback_Data callback_data,
@@ -53,6 +51,7 @@ private:
public:
struct Quark : public Raul::URI {
Quark(const char* str);
+ const char* c_str() const;
uint32_t id;
};
diff --git a/src/shared/ResourceImpl.cpp b/src/shared/ResourceImpl.cpp
index b542ff2d..db44f0f7 100644
--- a/src/shared/ResourceImpl.cpp
+++ b/src/shared/ResourceImpl.cpp
@@ -67,8 +67,7 @@ ResourceImpl::set_property(const Raul::URI& uri, const Raul::Atom& value)
void
ResourceImpl::remove_property(const Raul::URI& uri, const Raul::Atom& value)
{
- const LV2URIMap& uris = Shared::LV2URIMap::instance();
- if (value == uris.wildcard) {
+ if (value == _uris.wildcard) {
_properties.erase(uri);
} else {
Properties::iterator i = _properties.find(uri);
@@ -113,13 +112,13 @@ ResourceImpl::get_property(const Raul::URI& uri) const
bool
ResourceImpl::type(
+ const LV2URIMap& uris,
const Properties& properties,
bool& patch,
bool& node,
bool& port, bool& is_output, PortType& data_type)
{
typedef Resource::Properties::const_iterator iterator;
- const LV2URIMap& uris = Shared::LV2URIMap::instance();
const std::pair<iterator,iterator> types_range = properties.equal_range(uris.rdf_type);
patch = node = port = is_output = false;
@@ -198,10 +197,9 @@ ResourceImpl::add_properties(const Properties& p)
void
ResourceImpl::remove_properties(const Properties& p)
{
- const LV2URIMap& uris = Shared::LV2URIMap::instance();
typedef Resource::Properties::const_iterator iterator;
for (iterator i = p.begin(); i != p.end(); ++i) {
- if (i->second == uris.wildcard) {
+ if (i->second == _uris.wildcard) {
_properties.erase(i->first);
} else {
for (Properties::iterator j = _properties.find(i->first);
diff --git a/src/shared/ResourceImpl.hpp b/src/shared/ResourceImpl.hpp
index 8e827df8..7b77d669 100644
--- a/src/shared/ResourceImpl.hpp
+++ b/src/shared/ResourceImpl.hpp
@@ -21,16 +21,22 @@
#include <map>
#include <sigc++/sigc++.h>
#include "raul/URI.hpp"
+#include "raul/SharedPtr.hpp"
#include "interface/Resource.hpp"
#include "interface/PortType.hpp"
namespace Ingen {
namespace Shared {
+class LV2URIMap;
+
class ResourceImpl : virtual public Resource
{
public:
- ResourceImpl(const Raul::URI& uri) : _uri(uri) {}
+ ResourceImpl(LV2URIMap& uris, const Raul::URI& uri)
+ : _uris(uris), _uri(uri) {}
+
+ LV2URIMap& uris() const { return _uris; }
virtual void set_uri(const Raul::URI& uri) { _uri = uri; }
virtual const Raul::URI& uri() const { return _uri; }
@@ -56,6 +62,7 @@ public:
* output parameter set to true. Otherwise false is returned.
*/
static bool type(
+ const LV2URIMap& uris,
const Properties& properties,
bool& patch,
bool& node,
@@ -67,6 +74,8 @@ public:
protected:
Raul::Atom& set_property(const Raul::URI& uri, const Raul::Atom& value) const;
+ LV2URIMap& _uris;
+
private:
Raul::URI _uri;
mutable Properties _properties;
diff --git a/src/shared/runtime_paths.cpp b/src/shared/runtime_paths.cpp
index f823c4e2..832c3472 100644
--- a/src/shared/runtime_paths.cpp
+++ b/src/shared/runtime_paths.cpp
@@ -41,29 +41,44 @@ set_bundle_path_from_code(void* function)
Dl_info dli;
dladdr(function, &dli);
+#ifdef BUNDLE
char bin_loc[PATH_MAX];
realpath(dli.dli_fname, bin_loc);
+#else
+ const char* bin_loc = dli.dli_fname;
+#endif
-#ifdef BUNDLE
string bundle = bin_loc;
bundle = bundle.substr(0, bundle.find_last_of(G_DIR_SEPARATOR));
bundle_path = bundle;
-#endif
}
+void
+set_bundle_path(const char* path)
+{
+ bundle_path = path;
+}
+
+
+/** Return the absolute path of a file in an Ingen LV2 bundle
+ */
+std::string
+bundle_file_path(const std::string& name)
+{
+ return Glib::build_filename(bundle_path, name);
+}
+
/** Return the absolute path of a 'resource' file.
*/
std::string
data_file_path(const std::string& name)
{
- std::string ret;
#ifdef BUNDLE
- ret = Glib::build_filename(bundle_path, Glib::build_path(INGEN_DATA_DIR, name));
+ return Glib::build_filename(bundle_path, Glib::build_path(INGEN_DATA_DIR, name));
#else
- ret = Glib::build_filename(INGEN_DATA_DIR, name);
+ return Glib::build_filename(INGEN_DATA_DIR, name);
#endif
- return ret;
}
@@ -72,13 +87,11 @@ data_file_path(const std::string& name)
std::string
module_path(const std::string& name)
{
- std::string ret;
#ifdef BUNDLE
- ret = Glib::Module::build_path(Glib::build_path(bundle_path, INGEN_MODULE_DIR), name);
+ return Glib::Module::build_path(Glib::build_path(bundle_path, INGEN_MODULE_DIR), name);
#else
- ret = Glib::Module::build_path(INGEN_MODULE_DIR, name);
+ return Glib::Module::build_path(INGEN_MODULE_DIR, name);
#endif
- return ret;
}
diff --git a/src/shared/runtime_paths.hpp b/src/shared/runtime_paths.hpp
index e93e2343..0e8e2b85 100644
--- a/src/shared/runtime_paths.hpp
+++ b/src/shared/runtime_paths.hpp
@@ -27,8 +27,10 @@
namespace Ingen {
namespace Shared {
+void set_bundle_path(const char* path);
void set_bundle_path_from_code(void* function);
+std::string bundle_file_path(const std::string& name);
std::string data_file_path(const std::string& name);
std::string module_path(const std::string& name);
diff --git a/src/shared/wscript b/src/shared/wscript
index 540d4e83..6626f55a 100644
--- a/src/shared/wscript
+++ b/src/shared/wscript
@@ -9,6 +9,7 @@ def build(bld):
obj.source = '''
Builder.cpp
ClashAvoider.cpp
+ Configuration.cpp
LV2Features.cpp
LV2Object.cpp
LV2URIMap.cpp