summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--bundles/ingen.lv2/ingen.ttl12
-rw-r--r--ingen/shared/URIs.hpp1
-rw-r--r--src/client/ClientStore.cpp6
-rw-r--r--src/gui/PatchCanvas.cpp69
-rw-r--r--src/serialisation/Parser.cpp129
-rw-r--r--src/serialisation/Serialiser.cpp12
-rw-r--r--src/shared/URIs.cpp1
7 files changed, 125 insertions, 105 deletions
diff --git a/bundles/ingen.lv2/ingen.ttl b/bundles/ingen.lv2/ingen.ttl
index 95c26836..71124bb8 100644
--- a/bundles/ingen.lv2/ingen.ttl
+++ b/bundles/ingen.lv2/ingen.ttl
@@ -111,18 +111,6 @@ ingen:enabled
rdfs:label "Enabled" ;
rdfs:comment "Signifies the node is or should be running." .
-ingen:Port
- a owl:Class ;
- rdfs:subClassOf ingen:Object ;
- rdfs:label "Port" ;
- rdfs:comment """
-A Port is an input or output on a Node. It is implicitly an instance of the
-corresponding port on that Node's plugin (specified with ingen:prototype).
-A Port MUST have a legal lv2:symbol in the exact way a Node must, see :Node
-documentation for details. Ports inherit properties from the Port on their
-parent's Plugin in the exact way Nodes inherit properties from their Plugin.
-""" .
-
ingen:Edge
a owl:Class ;
rdfs:label "Edge" ;
diff --git a/ingen/shared/URIs.hpp b/ingen/shared/URIs.hpp
index 545a2bf0..0fd2cbdc 100644
--- a/ingen/shared/URIs.hpp
+++ b/ingen/shared/URIs.hpp
@@ -73,7 +73,6 @@ public:
const Quark ingen_Internal;
const Quark ingen_Node;
const Quark ingen_Patch;
- const Quark ingen_Port;
const Quark ingen_activity;
const Quark ingen_broadcast;
const Quark ingen_canvasX;
diff --git a/src/client/ClientStore.cpp b/src/client/ClientStore.cpp
index a78653e5..75acef63 100644
--- a/src/client/ClientStore.cpp
+++ b/src/client/ClientStore.cpp
@@ -459,9 +459,11 @@ ClientStore::attempt_connection(const Raul::Path& tail_path,
patch->add_edge(cm);
return true;
+ } else {
+ LOG(Raul::warn) << "Failed to connect " << tail_path
+ << " => " << head_path << std::endl;
+ return false;
}
-
- return false;
}
void
diff --git a/src/gui/PatchCanvas.cpp b/src/gui/PatchCanvas.cpp
index 3562a007..640051cb 100644
--- a/src/gui/PatchCanvas.cpp
+++ b/src/gui/PatchCanvas.cpp
@@ -637,42 +637,56 @@ PatchCanvas::destroy_selection()
for_each_selected_edge(destroy_edge, &_app);
}
-void
-PatchCanvas::copy_selection()
+static void
+serialise_node(GanvNode* node, void* data)
{
- std::cerr << "FIXME: copy" << std::endl;
- #if 0
- static const char* base_uri = "";
- Serialiser serialiser(*_app.world(), _app.store());
- serialiser.start_to_string(_patch->path(), base_uri);
+ Serialisation::Serialiser* serialiser = (Serialisation::Serialiser*)data;
+ if (!GANV_IS_MODULE(node)) {
+ return;
+ }
- FOREACH_ITEM(m, selected_items()) {
- NodeModule* module = dynamic_cast<NodeModule*>(*m);
- if (module) {
- serialiser.serialise(module->node());
- } else {
- PatchPortModule* port_module = dynamic_cast<PatchPortModule*>(*m);
- if (port_module)
- serialiser.serialise(port_module->port());
+ Ganv::Module* module = Glib::wrap(GANV_MODULE(node));
+ NodeModule* node_module = dynamic_cast<NodeModule*>(module);
+
+ if (node_module) {
+ serialiser->serialise(node_module->node());
+ } else {
+ PatchPortModule* port_module = dynamic_cast<PatchPortModule*>(module);
+ if (port_module) {
+ serialiser->serialise(port_module->port());
}
}
+}
- for (SelectedEdges::const_iterator c = selected_edges().begin();
- c != selected_edges().end(); ++c) {
- Edge* const edge = dynamic_cast<Edge*>(*c);
- if (edge) {
- const Sord::URI subject(*_app.world()->rdf_world(),
- base_uri);
- serialiser.serialise_edge(subject, edge->model());
- }
+static void
+serialise_edge(GanvEdge* edge, void* data)
+{
+ Serialisation::Serialiser* serialiser = (Serialisation::Serialiser*)data;
+ if (!GANV_IS_EDGE(edge)) {
+ return;
+ }
+
+ GUI::Edge* gedge = dynamic_cast<GUI::Edge*>(Glib::wrap(GANV_EDGE(edge)));
+ if (gedge) {
+ serialiser->serialise_edge(Sord::Node(), gedge->model());
}
+}
+
+void
+PatchCanvas::copy_selection()
+{
+ static const char* base_uri = "http://drobilla.net/ns/ingen/selection/";
+ Serialisation::Serialiser serialiser(*_app.world());
+ serialiser.start_to_string(_patch->path(), base_uri);
+
+ for_each_selected_node(serialise_node, &serialiser);
+ for_each_selected_edge(serialise_edge, &serialiser);
- string result = serialiser.finish();
+ const std::string result = serialiser.finish();
_paste_count = 0;
Glib::RefPtr<Gtk::Clipboard> clipboard = Gtk::Clipboard::get();
clipboard->set_text(result);
- #endif
}
void
@@ -702,7 +716,7 @@ PatchCanvas::paste()
uris.ingen_Patch));
props.insert(make_pair(uris.ingen_polyphony,
_app.forge().make(int32_t(_patch->internal_poly()))));
- clipboard.put(Path(), props);
+ clipboard.put(Path("/"), props);
size_t first_slash;
while (to_create != "/" && !to_create.empty()
&& (first_slash = to_create.find("/")) != string::npos) {
@@ -723,7 +737,8 @@ PatchCanvas::paste()
}
ClashAvoider avoider(*_app.store().get(), clipboard, &clipboard);
- parser->parse_string(_app.world(), &avoider, str, "",
+ static const char* base_uri = "http://drobilla.net/ns/ingen/selection/";
+ parser->parse_string(_app.world(), &avoider, str, base_uri,
parent, symbol);
for (Store::iterator i = clipboard.begin(); i != clipboard.end(); ++i) {
diff --git a/src/serialisation/Parser.cpp b/src/serialisation/Parser.cpp
index df17d7ff..2c56dc1e 100644
--- a/src/serialisation/Parser.cpp
+++ b/src/serialisation/Parser.cpp
@@ -177,6 +177,7 @@ parse(
Interface* target,
Sord::Model& model,
Glib::ustring document_uri,
+ Sord::Node& subject,
boost::optional<Raul::Path> parent = boost::optional<Raul::Path>(),
boost::optional<Raul::Symbol> symbol = boost::optional<Raul::Symbol>(),
boost::optional<Resource::Properties> data = boost::optional<Resource::Properties>());
@@ -397,49 +398,57 @@ parse_patch(Ingen::Shared::World* world,
}
static bool
-parse_edges(Ingen::Shared::World* world,
- Ingen::Interface* target,
- Sord::Model& model,
- const Sord::Node& subject,
- const Raul::Path& parent)
+parse_edge(Ingen::Shared::World* world,
+ Ingen::Interface* target,
+ Sord::Model& model,
+ const Sord::Node& subject,
+ const Raul::Path& parent)
{
- Sord::URI ingen_edge(*world->rdf_world(), NS_INGEN "edge");
Sord::URI ingen_tail(*world->rdf_world(), NS_INGEN "tail");
Sord::URI ingen_head(*world->rdf_world(), NS_INGEN "head");
+ Sord::Iter t = model.find(subject, ingen_tail, nil);
+ Sord::Iter h = model.find(subject, ingen_head, nil);
+
const Glib::ustring& base_uri = model.base_uri().to_string();
- RDFNodes connections;
- for (Sord::Iter i = model.find(subject, ingen_edge, nil); !i.end(); ++i) {
- connections.insert(i.get_object());
+ if (t.end()) {
+ LOG(error) << "Edge has no tail" << endl;
+ return false;
+ } else if (h.end()) {
+ LOG(error) << "Edge has no head" << endl;
+ return false;
}
- for (RDFNodes::const_iterator i = connections.begin(); i != connections.end(); ++i) {
- Sord::Iter t = model.find(*i, ingen_tail, nil);
- Sord::Iter h = model.find(*i, ingen_head, nil);
+ const Path tail_path(
+ parent.child(relative_uri(base_uri, t.get_object().to_string(), false)));
+ const Path head_path(
+ parent.child(relative_uri(base_uri, h.get_object().to_string(), false)));
- if (t.end()) {
- LOG(error) << "Edge has no tail" << endl;
- return false;
- } else if (h.end()) {
- LOG(error) << "Edge has no head" << endl;
- return false;
- }
+ if (!(++t).end()) {
+ LOG(error) << "Edge has multiple tails" << endl;
+ return false;
+ } else if (!(++h).end()) {
+ LOG(error) << "Edge has multiple heads" << endl;
+ return false;
+ }
- const Path tail_path(
- parent.child(relative_uri(base_uri, t.get_object().to_string(), false)));
- const Path head_path(
- parent.child(relative_uri(base_uri, h.get_object().to_string(), false)));
-
- if (!(++t).end()) {
- LOG(error) << "Edge has multiple tails" << endl;
- return false;
- } else if (!(++h).end()) {
- LOG(error) << "Edge has multiple heads" << endl;
- return false;
- }
+ target->connect(tail_path, head_path);
- target->connect(tail_path, head_path);
+ return true;
+}
+
+static bool
+parse_edges(Ingen::Shared::World* world,
+ Ingen::Interface* target,
+ Sord::Model& model,
+ const Sord::Node& subject,
+ const Raul::Path& parent)
+{
+ Sord::URI ingen_edge(*world->rdf_world(), NS_INGEN "edge");
+
+ for (Sord::Iter i = model.find(subject, ingen_edge, nil); !i.end(); ++i) {
+ parse_edge(world, target, model, i.get_object(), parent);
}
return true;
@@ -469,24 +478,23 @@ parse(Ingen::Shared::World* world,
Ingen::Interface* target,
Sord::Model& model,
Glib::ustring document_uri,
+ Sord::Node& subject,
boost::optional<Raul::Path> parent,
boost::optional<Raul::Symbol> symbol,
boost::optional<GraphObject::Properties> data)
{
const Sord::URI patch_class (*world->rdf_world(), NS_INGEN "Patch");
const Sord::URI node_class (*world->rdf_world(), NS_INGEN "Node");
- const Sord::URI port_class (*world->rdf_world(), NS_INGEN "Port");
+ const Sord::URI edge_class (*world->rdf_world(), NS_INGEN "Edge");
const Sord::URI internal_class(*world->rdf_world(), NS_INGEN "Internal");
const Sord::URI in_port_class (*world->rdf_world(), LV2_CORE__InputPort);
const Sord::URI out_port_class(*world->rdf_world(), LV2_CORE__OutputPort);
const Sord::URI lv2_class (*world->rdf_world(), LV2_CORE__Plugin);
- const Sord::URI rdf_type (*world->rdf_world(), NS_RDF "type");
-
- Sord::Node subject = model.base_uri();
+ const Sord::URI rdf_type (*world->rdf_world(), NS_RDF "type");
- Raul::Path path("/");
- if (parent && symbol) {
- path = parent->child(*symbol);
+ // Parse explicit subject patch
+ if (subject.is_valid()) {
+ return parse_patch(world, target, model, subject, parent, symbol, data);
}
// Get all subjects and their types (?subject a ?type)
@@ -508,19 +516,23 @@ parse(Ingen::Shared::World* world,
}
// Parse and create each subject
- boost::optional<Path> ret;
for (Subjects::const_iterator i = subjects.begin(); i != subjects.end(); ++i) {
- const Sord::Node& subject = i->first;
- const std::set<Sord::Node>& types = i->second;
+ const Sord::Node& s = i->first;
+ const std::set<Sord::Node>& types = i->second;
+ boost::optional<Path> ret;
+ const Raul::Path path(
+ relative_uri( model.base_uri().to_string(), s.to_string(), true));
if (types.find(patch_class) != types.end()) {
- ret = parse_patch(world, target, model, subject, parent, symbol, data);
+ ret = parse_patch(world, target, model, s, parent, symbol, data);
} else if (types.find(node_class) != types.end()) {
- ret = parse_node(world, target, model,
- subject, path.child(subject.to_string()),
- data);
- } else if (types.find(port_class) != types.end()) {
- parse_properties(world, target, model, subject, path, data);
+ ret = parse_node(world, target, model, s, path, data);
+ } else if (types.find(in_port_class) != types.end() ||
+ types.find(out_port_class) != types.end()) {
+ parse_properties(world, target, model, s, path, data);
ret = path;
+ } else if (types.find(edge_class) != types.end()) {
+ Path parent_path(parent ? parent.get() : Path("/"));
+ parse_edge(world, target, model, s, parent_path);
} else {
LOG(error) << "Subject has no known types" << endl;
}
@@ -533,11 +545,10 @@ parse(Ingen::Shared::World* world,
LOG(error) << " :: " << *t << endl;
assert((*t).is_uri());
}
- return boost::optional<Path>();
}
}
- return path;
+ return boost::optional<Path>();
}
Parser::Parser(Ingen::Shared::World& world)
@@ -578,7 +589,7 @@ Parser::parse_file(Ingen::Shared::World* world,
SerdEnv* env = serd_env_new(&base_node);
// Load patch file into model
- Sord::Model model(*world->rdf_world(), uri);
+ Sord::Model model(*world->rdf_world(), uri, SORD_SPO|SORD_PSO, false);
model.load_file(env, SERD_TURTLE, uri);
serd_env_free(env);
@@ -589,8 +600,9 @@ Parser::parse_file(Ingen::Shared::World* world,
if (symbol)
LOG(Raul::info)(Raul::fmt("Symbol: %1%\n") % symbol->c_str());
+ Sord::Node subject(*world->rdf_world(), Sord::Node::URI, uri);
boost::optional<Path> parsed_path
- = parse(world, target, model, path, parent, symbol, data);
+ = parse(world, target, model, path, subject, parent, symbol, data);
if (parsed_path) {
target->set_property(*parsed_path, "http://drobilla.net/ns/ingen#document",
@@ -612,8 +624,10 @@ Parser::parse_string(Ingen::Shared::World* world,
boost::optional<GraphObject::Properties> data)
{
// Load string into model
- Sord::Model model(*world->rdf_world(), base_uri);
- SerdEnv* env = serd_env_new(NULL);
+ Sord::Model model(*world->rdf_world(), base_uri, SORD_SPO|SORD_PSO, false);
+ const SerdNode base = serd_node_from_string(
+ SERD_URI, (const uint8_t*)base_uri.c_str());
+ SerdEnv* env = serd_env_new(&base);
model.load_string(env, SERD_TURTLE, str.c_str(), str.length(), base_uri);
serd_env_free(env);
@@ -622,11 +636,8 @@ Parser::parse_string(Ingen::Shared::World* world,
info << " (base " << base_uri << ")";
info << endl;
- bool ret = parse(world, target, model, base_uri, parent, symbol, data);
- Sord::URI subject(*world->rdf_world(), base_uri);
- parse_edges(world, target, model, subject, parent ? *parent : "/");
-
- return ret;
+ Sord::Node subject;
+ return parse(world, target, model, base_uri, subject, parent, symbol, data);
}
} // namespace Serialisation
diff --git a/src/serialisation/Serialiser.cpp b/src/serialisation/Serialiser.cpp
index 6e126c42..6a674eb5 100644
--- a/src/serialisation/Serialiser.cpp
+++ b/src/serialisation/Serialiser.cpp
@@ -526,9 +526,15 @@ Serialiser::Impl::serialise_edge(const Sord::Node& parent,
Sord::Curie(world, "ingen:head"),
dst);
- _model->add_statement(parent,
- Sord::Curie(world, "ingen:edge"),
- edge_id);
+ if (parent.is_valid()) {
+ _model->add_statement(parent,
+ Sord::Curie(world, "ingen:edge"),
+ edge_id);
+ } else {
+ _model->add_statement(edge_id,
+ Sord::Curie(world, "rdf:type"),
+ Sord::Curie(world, "ingen:Edge"));
+ }
}
static bool
diff --git a/src/shared/URIs.cpp b/src/shared/URIs.cpp
index 6cc32c0b..abb0a011 100644
--- a/src/shared/URIs.cpp
+++ b/src/shared/URIs.cpp
@@ -68,7 +68,6 @@ URIs::URIs(Shared::Forge& f, URIMap* map)
, ingen_Internal (forge, map, NS_INGEN "Internal")
, ingen_Node (forge, map, NS_INGEN "Node")
, ingen_Patch (forge, map, NS_INGEN "Patch")
- , ingen_Port (forge, map, NS_INGEN "Port")
, ingen_activity (forge, map, NS_INGEN "activity")
, ingen_broadcast (forge, map, NS_INGEN "broadcast")
, ingen_canvasX (forge, map, NS_INGEN "canvasX")