uint64_t Controller::connect(uint64_t tail_id, uint64_t head_id) { SPtr<Node> tail = dynamic_ptr_cast<Node>(find(tail_id)); SPtr<Node> head = dynamic_ptr_cast<Node>(find(head_id)); if (!tail) { std::cerr << "error: tail node " << tail_id << " not found" << std::endl; return 0; } else if (!head) { std::cerr << "error: head node " << head_id << " not found" << std::endl; return 0; } SPtr<Edge> edge(new Edge(tail, head)); tail->add_edge(edge); _objects.insert(edge); Forge& forge = _engine->forge(); const Properties properties = { { URIs::instance().rdf_type, forge.make_urid(URIs::instance().machina_Edge) }, { URIs::instance().machina_probability, forge.make(1.0f) }, { URIs::instance().machina_tail_id, forge.make((int32_t)tail->id()) }, { URIs::instance().machina_head_id, forge.make((int32_t)head->id()) } }; _model.new_object(edge->id(), properties); return edge->id(); }
/** Load (create) all objects from RDF into the engine. * * @param uri URI of machine (resolvable URI to an RDF document). * @return Loaded Machine. */ SPtr<Machine> Loader::load(const Glib::ustring& uri) { using Glib::ustring; ustring document_uri = uri; // If "URI" doesn't contain a colon, try to resolve as a filename if (uri.find(":") == ustring::npos) { document_uri = "file://" + document_uri; } cout << "Loading " << document_uri << endl; TimeUnit beats(TimeUnit::BEATS, MACHINA_PPQN); SPtr<Machine> machine(new Machine(beats)); typedef std::map<Sord::Node, SPtr<Node> > Created; Created created; Sord::URI base_uri(_rdf_world, document_uri); Sord::Model model(_rdf_world, document_uri); SerdEnv* env = serd_env_new(base_uri.to_serd_node()); model.load_file(env, SERD_TURTLE, document_uri); serd_env_free(env); Sord::Node nil; Sord::URI machina_SelectorNode(_rdf_world, MACHINA_NS_SelectorNode); Sord::URI machina_duration(_rdf_world, MACHINA_NS_duration); Sord::URI machina_edge(_rdf_world, MACHINA_NS_arc); Sord::URI machina_head(_rdf_world, MACHINA_NS_head); Sord::URI machina_node(_rdf_world, MACHINA_NS_node); Sord::URI machina_onEnter(_rdf_world, MACHINA_NS_onEnter); Sord::URI machina_onExit(_rdf_world, MACHINA_NS_onExit); Sord::URI machina_probability(_rdf_world, MACHINA_NS_probability); Sord::URI machina_start(_rdf_world, MACHINA_NS_start); Sord::URI machina_tail(_rdf_world, MACHINA_NS_tail); Sord::URI rdf_type(_rdf_world, MACHINA_URI_RDF "type"); Sord::Node subject = base_uri; // Get start node ID (but re-use existing start node) Sord::Iter i = model.find(subject, machina_start, nil); if (i.end()) { cerr << "error: Machine has no start node" << std::endl; } created[i.get_object()] = machine->initial_node(); // Get remaining nodes for (Sord::Iter i = model.find(subject, machina_node, nil); !i.end(); ++i) { const Sord::Node& id = i.get_object(); if (created.find(id) != created.end()) { cerr << "warning: Machine lists the same node twice" << std::endl; continue; } // Create node Sord::Iter d = model.find(id, machina_duration, nil); SPtr<Node> node(new Node(TimeStamp(beats, d.get_object().to_float()))); machine->add_node(node); created[id] = node; node->set_enter_action( load_action(model, model.get(id, machina_onEnter, nil))); node->set_exit_action( load_action(model, model.get(id, machina_onExit, nil))); } // Get arcs for (Sord::Iter i = model.find(subject, machina_edge, nil); !i.end(); ++i) { Sord::Node edge = i.get_object(); Sord::Iter t = model.find(edge, machina_tail, nil); Sord::Iter h = model.find(edge, machina_head, nil); Sord::Iter p = model.find(edge, machina_probability, nil); Sord::Node tail = t.get_object(); Sord::Node head = h.get_object(); Sord::Node probability = p.get_object(); float prob = probability.to_float(); Created::iterator tail_i = created.find(tail); Created::iterator head_i = created.find(head); if (tail_i != created.end() && head_i != created.end()) { const SPtr<Node> tail = tail_i->second; const SPtr<Node> head = head_i->second; tail->add_edge(SPtr<Edge>(new Edge(tail, head, prob))); } else { cerr << "warning: Ignored edge between unknown nodes " << tail << " -> " << head << endl; } } if (machine && !machine->nodes().empty()) { machine->reset(NULL, machine->time()); return machine; } else { return SPtr<Machine>(); } }