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 | |
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')
-rw-r--r-- | src/serialisation/Parser.cpp | 148 | ||||
-rw-r--r-- | src/serialisation/Parser.hpp | 13 | ||||
-rw-r--r-- | src/serialisation/Serialiser.cpp | 55 | ||||
-rw-r--r-- | src/serialisation/serialisation.cpp | 8 |
4 files changed, 142 insertions, 82 deletions
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()))); } }; |