From 4c8aad127d9504c7d355975180f877f5baa9f744 Mon Sep 17 00:00:00 2001 From: David Robillard Date: Mon, 5 Feb 2007 06:23:05 +0000 Subject: It's aliiiiivee! git-svn-id: http://svn.drobilla.net/lad/machina@278 a436a847-0d15-0410-975c-d299462d15a1 --- src/Loader.cpp | 149 ++++++++++++++++++++++++++++++++++++++++++++++----------- 1 file changed, 121 insertions(+), 28 deletions(-) (limited to 'src/Loader.cpp') diff --git a/src/Loader.cpp b/src/Loader.cpp index dfac552..7f61e05 100644 --- a/src/Loader.cpp +++ b/src/Loader.cpp @@ -1,4 +1,4 @@ -/* This file is part of Machina. Copyright (C) 2006 Dave Robillard. +/* This file is part of Machina. Copyright (C) 2007 Dave Robillard. * * Machina is free software; you can redistribute it and/or modify it under the * terms of the GNU General Public License as published by the Free Software @@ -15,12 +15,16 @@ */ #include +#include #include #include +#include #include "raul/RDFQuery.h" #include "Loader.hpp" #include "Node.hpp" +#include "Edge.hpp" #include "Machine.hpp" +#include "NodeFactory.hpp" using namespace Raul; using std::cerr; using std::cout; using std::endl; @@ -28,14 +32,15 @@ using std::cerr; using std::cout; using std::endl; namespace Machina { +/* // FIXME: remove Node* create_debug_node(const Node::ID& id, FrameCount duration) { // leaks like a sieve, obviously Node* n = new Node(duration); - PrintAction* a_enter = new PrintAction(string("> ") + id); - PrintAction* a_exit = new PrintAction(string("< ")/* + name*/); + PrintAction* a_enter = new PrintAction(string("\t> ") + id); + PrintAction* a_exit = new PrintAction(string("\t< ") + id); n->add_enter_action(a_enter); n->add_exit_action(a_exit); @@ -44,10 +49,12 @@ Node* create_debug_node(const Node::ID& id, FrameCount duration) return n; } - +*/ -Loader::Loader(SharedPtr namespaces) - : _namespaces(namespaces) +Loader::Loader(SharedPtr node_factory, + SharedPtr namespaces) + : _node_factory(node_factory) + , _namespaces(namespaces) { if (!_namespaces) _namespaces = SharedPtr(new Namespaces()); @@ -66,6 +73,7 @@ Loader::Loader(SharedPtr namespaces) SharedPtr Loader::load(const Glib::ustring& filename) { + using Raul::RDFQuery; SharedPtr machine; rasqal_init(); @@ -77,45 +85,130 @@ Loader::load(const Glib::ustring& filename) if (!document_uri_str) return machine; - machine = SharedPtr(new Machine(1)); + machine = SharedPtr(new Machine()); Glib::ustring document_uri = (const char*)document_uri_str; string machine_uri = "<> "; - cerr << "[Loader] Loading " << machine_uri << " from " << document_uri << endl; + cout << "[Loader] Loading " << machine_uri << " from " << document_uri << endl; - /* Load nodes */ - - RDFQuery query = RDFQuery(*_namespaces, Glib::ustring( - "SELECT DISTINCT ?node ?midiNote ?duration FROM <") + document_uri + "> WHERE {\n" + - machine_uri + " :node ?node .\n" - "?node :midiNote ?midiNote ;\n" - " :duration ?duration .\n" - //" FILTER ( datatype(?midiNote) = xsd:decimal )\n" - //" FILTER ( datatype(?duration) = xsd:decimal )\n" - "}"); + typedef std::map > Created; + Created created; + + + /* Get initial nodes */ + Raul::RDFQuery query = Raul::RDFQuery(*_namespaces, Glib::ustring( + "SELECT DISTINCT ?initialNode ?midiNote ?duration FROM <") + + document_uri + "> WHERE {\n" + + machine_uri + " :initialNode ?initialNode .\n" + "?initialNode :midiNote ?midiNote ;\n" + " :duration ?duration .\n" + "}\n"); + RDFQuery::Results results = query.run(document_uri); for (RDFQuery::Results::iterator i = results.begin(); i != results.end(); ++i) { - raptor_uri* node_uri = raptor_new_uri((const unsigned char*)(*i)["node"].c_str()); - unsigned char* node_name - = raptor_uri_to_relative_uri_string(document_raptor_uri, node_uri); + const Glib::ustring& node_uri = (*i)["initialNode"]; + const Glib::ustring& midi_note = (*i)["midiNote"]; + const Glib::ustring& duration = (*i)["duration"]; + + raptor_uri* node_raptor_uri + = raptor_new_uri((const unsigned char*)node_uri.c_str()); + + char* node_name = (char*) + raptor_uri_to_relative_uri_string(document_raptor_uri, node_raptor_uri); - const Glib::ustring& note = (*i)["midiNote"]; - const Glib::ustring& duration = (*i)["duration"]; + //cout << "Initial: " << node_name << ": " << midi_note << " - " << duration << endl; - cout << "NODE: " << node_name << ": " << note << " - " << duration << endl; - SharedPtr node = SharedPtr( - create_debug_node((const char*)node_name, strtol(duration.c_str(), NULL, 10))); + SharedPtr node = SharedPtr(_node_factory->create_node( + node_name, + strtol(midi_note.c_str(), NULL, 10), + strtol(duration.c_str(), NULL, 10))); - machine->add_node(string((const char*)node_name).substr(1), node); // (chop leading "#") + node->set_initial(true); + //machine->add_node(string(node_name).substr(1), node); // (chop leading "#") + machine->add_node(node); + + created.insert(std::make_pair(node_uri.collate_key(), node)); - raptor_free_uri(node_uri); + raptor_free_uri(node_raptor_uri); free(node_name); } + + /* Get remaining nodes */ + + query = Raul::RDFQuery(*_namespaces, Glib::ustring( + "SELECT DISTINCT ?node ?midiNote ?duration FROM <") + + document_uri + "> WHERE {\n" + + machine_uri + " :node ?node .\n" + "?node :midiNote ?midiNote ;\n" + " :duration ?duration .\n" + "}\n"); + + results = query.run(document_uri); + + for (RDFQuery::Results::iterator i = results.begin(); i != results.end(); ++i) { + const Glib::ustring& node_uri = (*i)["node"]; + const Glib::ustring& midi_note = (*i)["midiNote"]; + const Glib::ustring& duration = (*i)["duration"]; + + raptor_uri* node_raptor_uri + = raptor_new_uri((const unsigned char*)node_uri.c_str()); + + char* node_name = (char*) + raptor_uri_to_relative_uri_string(document_raptor_uri, node_raptor_uri); + + + SharedPtr node = SharedPtr(_node_factory->create_node( + node_name, + strtol(midi_note.c_str(), NULL, 10), + strtol(duration.c_str(), NULL, 10))); + + if (created.find(node_uri) == created.end()) { + //cout << "Node: " << node_name << ": " << midi_note << " - " << duration << endl; + //machine->add_node(string(node_name).substr(1), node); // (chop leading "#") + machine->add_node(node); + created.insert(std::make_pair(node_uri.collate_key(), node)); + } + + raptor_free_uri(node_raptor_uri); + free(node_name); + } + + + /* Get edges */ + + query = Raul::RDFQuery(*_namespaces, Glib::ustring( + "SELECT DISTINCT ?src ?edge ?dst FROM <") + + document_uri + "> WHERE {\n" + + machine_uri + " :edge ?edge .\n" + "?edge :tail ?src ;\n" + " :head ?dst .\n }"); + results = query.run(document_uri); + + for (RDFQuery::Results::iterator i = results.begin(); i != results.end(); ++i) { + const Glib::ustring& src_uri = (*i)["src"]; + const Glib::ustring& dst_uri = (*i)["dst"]; + + Created::iterator src_i = created.find(src_uri.collate_key()); + Created::iterator dst_i = created.find(dst_uri.collate_key()); + + if (src_i != created.end() && dst_i != created.end()) { + const SharedPtr src = src_i->second; + const SharedPtr dst = dst_i->second; + + src->add_outgoing_edge(SharedPtr(new Edge(src, dst))); + + } else { + cerr << "[Loader] WARNING: Ignored edge between unknown nodes " + << src_uri << " -> " << dst_uri << endl; + } + + } + free(document_uri_str); raptor_free_uri(document_raptor_uri); -- cgit v1.2.1