From fd1e2ef17c7799e8c5d5965932c3bec1570262bd Mon Sep 17 00:00:00 2001
From: David Robillard <d@drobilla.net>
Date: Fri, 27 Apr 2012 19:20:53 +0000
Subject: Implement connecting via atom interface.

git-svn-id: http://svn.drobilla.net/lad/trunk/ingen@4285 a436a847-0d15-0410-975c-d299462d15a1
---
 src/shared/AtomReader.cpp | 51 ++++++++++++++++++++++++++++++++++-------------
 src/shared/AtomWriter.cpp |  8 +++++---
 src/shared/URIs.cpp       |  6 +++---
 3 files changed, 45 insertions(+), 20 deletions(-)

(limited to 'src/shared')

diff --git a/src/shared/AtomReader.cpp b/src/shared/AtomReader.cpp
index a7ea5e68..fa14243a 100644
--- a/src/shared/AtomReader.cpp
+++ b/src/shared/AtomReader.cpp
@@ -18,6 +18,7 @@
 
 #include "ingen/shared/AtomReader.hpp"
 #include "lv2/lv2plug.in/ns/ext/atom/util.h"
+#include "raul/Path.hpp"
 #include "raul/log.hpp"
 
 namespace Ingen {
@@ -31,21 +32,24 @@ AtomReader::AtomReader(LV2URIMap& map, URIs& uris, Forge& forge, Interface& ifac
 {
 }
 
+void
+AtomReader::get_uri(const LV2_Atom* in, Raul::Atom& out)
+{
+	if (in->type == _uris.atom_URID) {
+		const LV2_Atom_URID* urid = (const LV2_Atom_URID*)in;
+		out = _forge.alloc_uri(_map.unmap_uri(urid->body));
+	} else {
+		out = _forge.alloc(in->size, in->type, LV2_ATOM_BODY(in));
+	}
+}
+
 void
 AtomReader::get_props(const LV2_Atom_Object*       obj,
                       Ingen::Resource::Properties& props)
 {
 	LV2_ATOM_OBJECT_FOREACH(obj, p) {
 		Raul::Atom val;
-		if (p->value.type == _uris.atom_URID) {
-			const LV2_Atom_URID* urid = (const LV2_Atom_URID*)&p->value;
-			val = _forge.alloc_uri(_map.unmap_uri(urid->body));
-		} else {
-			val = _forge.alloc(p->value.size,
-			                   p->value.type,
-			                   LV2_ATOM_BODY(&p->value));
-		}
-
+		get_uri(&p->value, val);
 		props.insert(std::make_pair(_map.unmap_uri(p->key), val));
 	}
 }
@@ -83,11 +87,30 @@ AtomReader::write(const LV2_Atom* msg)
 			return;
 		}
 
-		Ingen::Resource::Properties props;
-		get_props(body, props);
-
-		_iface.set_response_id(obj->body.id);
-		_iface.put(subject_uri, props);
+		if (body->body.otype == _uris.ingen_Edge) {
+			LV2_Atom* tail = NULL;
+			LV2_Atom* head = NULL;
+			lv2_atom_object_get(body,
+			                    (LV2_URID)_uris.ingen_tail, &tail,
+			                    (LV2_URID)_uris.ingen_head, &head,
+			                    NULL);
+			if (!tail || !head) {
+				Raul::warn << "Edge has no tail or head" << std::endl;
+				return;
+			}
+
+			Raul::Atom tail_atom;
+			Raul::Atom head_atom;
+			get_uri(tail, tail_atom);
+			get_uri(head, head_atom);
+			_iface.connect(Raul::Path(tail_atom.get_uri()),
+			               Raul::Path(head_atom.get_uri()));
+		} else {
+			Ingen::Resource::Properties props;
+			get_props(body, props);
+			_iface.set_response_id(obj->body.id);
+			_iface.put(subject_uri, props);
+		}
 	} else if (obj->body.otype == _uris.patch_Patch) {
 		if (!subject_uri) {
 			Raul::warn << "Put message has no subject" << std::endl;
diff --git a/src/shared/AtomWriter.cpp b/src/shared/AtomWriter.cpp
index 913c85ce..4e3853e8 100644
--- a/src/shared/AtomWriter.cpp
+++ b/src/shared/AtomWriter.cpp
@@ -177,13 +177,15 @@ AtomWriter::connect(const Raul::Path& src,
 {
 	LV2_Atom_Forge_Frame msg;
 	lv2_atom_forge_blank(&_forge, &msg, next_id(), _uris.patch_Put);
+	lv2_atom_forge_property_head(&_forge, _uris.patch_subject, 0);
+	forge_uri(Raul::Path::lca(src, dst));
 	lv2_atom_forge_property_head(&_forge, _uris.patch_body, 0);
 
 	LV2_Atom_Forge_Frame body;
-	lv2_atom_forge_blank(&_forge, &body, 0, _uris.ingen_Connection);
-	lv2_atom_forge_property_head(&_forge, _uris.ingen_source, 0);
+	lv2_atom_forge_blank(&_forge, &body, 0, _uris.ingen_Edge);
+	lv2_atom_forge_property_head(&_forge, _uris.ingen_tail, 0);
 	forge_uri(src);
-	lv2_atom_forge_property_head(&_forge, _uris.ingen_destination, 0);
+	lv2_atom_forge_property_head(&_forge, _uris.ingen_head, 0);
 	forge_uri(dst);
 	lv2_atom_forge_pop(&_forge, &body);
 
diff --git a/src/shared/URIs.cpp b/src/shared/URIs.cpp
index 415fc421..b1ecda5f 100644
--- a/src/shared/URIs.cpp
+++ b/src/shared/URIs.cpp
@@ -64,7 +64,7 @@ URIs::URIs(Ingen::Forge& f, LV2URIMap* map)
 	, atom_eventTransfer    (forge, map, LV2_ATOM__eventTransfer)
 	, atom_supports         (forge, map, LV2_ATOM__supports)
 	, doap_name             (forge, map, "http://usefulinc.com/ns/doap#name")
-	, ingen_Connection      (forge, map, NS_INGEN "Connection")
+	, ingen_Edge            (forge, map, NS_INGEN "Edge")
 	, ingen_Internal        (forge, map, NS_INGEN "Internal")
 	, ingen_Node            (forge, map, NS_INGEN "Node")
 	, ingen_Patch           (forge, map, NS_INGEN "Patch")
@@ -74,17 +74,17 @@ URIs::URIs(Ingen::Forge& f, LV2URIMap* map)
 	, ingen_canvasX         (forge, map, NS_INGEN "canvasX")
 	, ingen_canvasY         (forge, map, NS_INGEN "canvasY")
 	, ingen_controlBinding  (forge, map, NS_INGEN "controlBinding")
-	, ingen_destination     (forge, map, NS_INGEN "destination")
 	, ingen_document        (forge, map, NS_INGEN "document")
 	, ingen_enabled         (forge, map, NS_INGEN "enabled")
 	, ingen_engine          (forge, map, NS_INGEN "engine")
+	, ingen_head            (forge, map, NS_INGEN "head")
 	, ingen_nil             (forge, map, NS_INGEN "nil")
 	, ingen_node            (forge, map, NS_INGEN "node")
 	, ingen_polyphonic      (forge, map, NS_INGEN "polyphonic")
 	, ingen_polyphony       (forge, map, NS_INGEN "polyphony")
 	, ingen_sampleRate      (forge, map, NS_INGEN "sampleRate")
 	, ingen_selected        (forge, map, NS_INGEN "selected")
-	, ingen_source          (forge, map, NS_INGEN "source")
+	, ingen_tail            (forge, map, NS_INGEN "tail")
 	, ingen_uiEmbedded      (forge, map, NS_INGEN "uiEmbedded")
 	, ingen_value           (forge, map, NS_INGEN "value")
 	, lv2_AudioPort         (forge, map, LV2_CORE__AudioPort)
-- 
cgit v1.2.1