diff options
author | David Robillard <d@drobilla.net> | 2010-03-06 10:23:19 +0000 |
---|---|---|
committer | David Robillard <d@drobilla.net> | 2010-03-06 10:23:19 +0000 |
commit | 059f20c9666234f2be01498ee04f1e7ee795ba8f (patch) | |
tree | ef0d53073d53012aeaa7d084fccf477b166c0684 /src/serialisation/Serialiser.cpp | |
parent | 085a451dfec54126be1b9346899c81d82e6eb58e (diff) | |
download | ingen-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/serialisation/Serialiser.cpp')
-rw-r--r-- | src/serialisation/Serialiser.cpp | 55 |
1 files changed, 39 insertions, 16 deletions
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) { |