summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorDavid Robillard <d@drobilla.net>2017-03-19 13:26:38 +0100
committerDavid Robillard <d@drobilla.net>2017-03-20 02:58:56 +0100
commitf1c793f7e2148b10610a09a459d9e89b39d2d87b (patch)
treeb898407dce08af0f2f978d59a85d4887d8555b54 /src
parentefc0fe0a973db706d9409b345ad6fae585f4388c (diff)
downloadingen-f1c793f7e2148b10610a09a459d9e89b39d2d87b.tar.gz
ingen-f1c793f7e2148b10610a09a459d9e89b39d2d87b.tar.bz2
ingen-f1c793f7e2148b10610a09a459d9e89b39d2d87b.zip
Fix round-trip preservation of property contexts
Diffstat (limited to 'src')
-rw-r--r--src/AtomReader.cpp69
-rw-r--r--src/AtomWriter.cpp25
-rw-r--r--src/Parser.cpp9
-rw-r--r--src/URIs.cpp3
-rw-r--r--src/client/ClientStore.cpp8
-rw-r--r--src/client/PluginUI.cpp13
-rw-r--r--src/gui/App.cpp10
-rw-r--r--src/gui/App.hpp6
-rw-r--r--src/gui/SubgraphModule.cpp8
-rw-r--r--src/server/Broadcaster.hpp12
-rw-r--r--src/server/EventWriter.cpp19
-rw-r--r--src/server/EventWriter.hpp6
-rw-r--r--src/server/events/Delta.cpp16
13 files changed, 134 insertions, 70 deletions
diff --git a/src/AtomReader.cpp b/src/AtomReader.cpp
index 57aa09bb..18b5877c 100644
--- a/src/AtomReader.cpp
+++ b/src/AtomReader.cpp
@@ -106,6 +106,21 @@ AtomReader::atom_to_path(const LV2_Atom* atom)
return boost::optional<Raul::Path>();
}
+Resource::Graph
+AtomReader::atom_to_context(const LV2_Atom* atom)
+{
+ Resource::Graph ctx = Resource::Graph::DEFAULT;
+ if (atom) {
+ boost::optional<Raul::URI> maybe_uri = atom_to_uri(atom);
+ if (maybe_uri) {
+ ctx = Resource::uri_to_graph(*maybe_uri);
+ } else {
+ _log.warn("Message has invalid context\n");
+ }
+ }
+ return ctx;
+}
+
bool
AtomReader::is_message(const URIs& uris, const LV2_Atom* msg)
{
@@ -168,8 +183,8 @@ AtomReader::write(const LV2_Atom* msg, int32_t default_id)
const LV2_Atom* head = NULL;
const LV2_Atom* incidentTo = NULL;
lv2_atom_object_get(body,
- (LV2_URID)_uris.ingen_tail, &tail,
- (LV2_URID)_uris.ingen_head, &head,
+ (LV2_URID)_uris.ingen_tail, &tail,
+ (LV2_URID)_uris.ingen_head, &head,
(LV2_URID)_uris.ingen_incidentTo, &incidentTo,
NULL);
@@ -187,8 +202,12 @@ AtomReader::write(const LV2_Atom* msg, int32_t default_id)
}
}
} else if (obj->body.otype == _uris.patch_Put) {
- const LV2_Atom_Object* body = NULL;
- lv2_atom_object_get(obj, (LV2_URID)_uris.patch_body, &body, 0);
+ const LV2_Atom_Object* body = NULL;
+ const LV2_Atom* context = NULL;
+ lv2_atom_object_get(obj,
+ (LV2_URID)_uris.patch_body, &body,
+ (LV2_URID)_uris.patch_context, &context,
+ 0);
if (!body) {
_log.warn("Put message has no body\n");
return false;
@@ -219,7 +238,7 @@ AtomReader::write(const LV2_Atom* msg, int32_t default_id)
} else {
Ingen::Properties props;
get_props(body, props);
- _iface.put(*subject_uri, props);
+ _iface.put(*subject_uri, props, atom_to_context(context));
}
} else if (obj->body.otype == _uris.patch_Set) {
if (!subject_uri) {
@@ -227,16 +246,18 @@ AtomReader::write(const LV2_Atom* msg, int32_t default_id)
return false;
}
- const LV2_Atom_URID* prop = NULL;
- lv2_atom_object_get(obj, (LV2_URID)_uris.patch_property, &prop, 0);
+ const LV2_Atom_URID* prop = NULL;
+ const LV2_Atom* value = NULL;
+ const LV2_Atom* context = NULL;
+ lv2_atom_object_get(obj,
+ (LV2_URID)_uris.patch_property, &prop,
+ (LV2_URID)_uris.patch_value, &value,
+ (LV2_URID)_uris.patch_context, &context,
+ 0);
if (!prop || ((const LV2_Atom*)prop)->type != _uris.atom_URID) {
_log.warn("Set message missing property\n");
return false;
- }
-
- const LV2_Atom* value = NULL;
- lv2_atom_object_get(obj, (LV2_URID)_uris.patch_value, &value, 0);
- if (!value) {
+ } else if (!value) {
_log.warn("Set message missing value\n");
return false;
}
@@ -245,23 +266,26 @@ AtomReader::write(const LV2_Atom* msg, int32_t default_id)
get_atom(value, atom);
_iface.set_property(*subject_uri,
Raul::URI(_map.unmap_uri(prop->body)),
- atom);
+ atom,
+ atom_to_context(context));
} else if (obj->body.otype == _uris.patch_Patch) {
if (!subject_uri) {
_log.warn("Patch message has no subject\n");
return false;
}
- const LV2_Atom_Object* remove = NULL;
- lv2_atom_object_get(obj, (LV2_URID)_uris.patch_remove, &remove, 0);
+ const LV2_Atom_Object* remove = NULL;
+ const LV2_Atom_Object* add = NULL;
+ const LV2_Atom* context = NULL;
+ lv2_atom_object_get(obj,
+ (LV2_URID)_uris.patch_remove, &remove,
+ (LV2_URID)_uris.patch_add, &add,
+ (LV2_URID)_uris.patch_context, &context,
+ 0);
if (!remove) {
_log.warn("Patch message has no remove\n");
return false;
- }
-
- const LV2_Atom_Object* add = NULL;
- lv2_atom_object_get(obj, (LV2_URID)_uris.patch_add, &add, 0);
- if (!add) {
+ } else if (!add) {
_log.warn("Patch message has no add\n");
return false;
}
@@ -272,7 +296,8 @@ AtomReader::write(const LV2_Atom* msg, int32_t default_id)
Ingen::Properties remove_props;
get_props(remove, remove_props);
- _iface.delta(*subject_uri, remove_props, add_props);
+ _iface.delta(*subject_uri, remove_props, add_props,
+ atom_to_context(context));
} else if (obj->body.otype == _uris.patch_Copy) {
if (!subject) {
_log.warn("Copy message has no subject\n");
@@ -330,7 +355,7 @@ AtomReader::write(const LV2_Atom* msg, int32_t default_id)
const LV2_Atom* body = NULL;
lv2_atom_object_get(obj,
(LV2_URID)_uris.patch_sequenceNumber, &seq,
- (LV2_URID)_uris.patch_body, &body,
+ (LV2_URID)_uris.patch_body, &body,
0);
if (!seq || seq->type != _uris.atom_Int) {
_log.warn("Response message has no sequence number\n");
diff --git a/src/AtomWriter.cpp b/src/AtomWriter.cpp
index 2fc3ee18..54dcd0a2 100644
--- a/src/AtomWriter.cpp
+++ b/src/AtomWriter.cpp
@@ -165,6 +165,22 @@ AtomWriter::forge_request(LV2_Atom_Forge_Frame* frame, LV2_URID type)
}
}
+void
+AtomWriter::forge_context(Resource::Graph ctx)
+{
+ switch (ctx) {
+ case Resource::Graph::EXTERNAL:
+ lv2_atom_forge_key(&_forge, _uris.patch_context);
+ forge_uri(_uris.ingen_externalContext);
+ break;
+ case Resource::Graph::INTERNAL:
+ lv2_atom_forge_key(&_forge, _uris.patch_context);
+ forge_uri(_uris.ingen_internalContext);
+ break;
+ default: break;
+ }
+}
+
/** @page protocol
* @section methods Methods
* @subsection Put
@@ -196,6 +212,7 @@ AtomWriter::put(const Raul::URI& uri,
{
LV2_Atom_Forge_Frame msg;
forge_request(&msg, _uris.patch_Put);
+ forge_context(ctx);
lv2_atom_forge_key(&_forge, _uris.patch_subject);
forge_uri(uri);
lv2_atom_forge_key(&_forge, _uris.patch_body);
@@ -238,10 +255,12 @@ AtomWriter::put(const Raul::URI& uri,
void
AtomWriter::delta(const Raul::URI& uri,
const Properties& remove,
- const Properties& add)
+ const Properties& add,
+ Resource::Graph ctx)
{
LV2_Atom_Forge_Frame msg;
forge_request(&msg, _uris.patch_Patch);
+ forge_context(ctx);
lv2_atom_forge_key(&_forge, _uris.patch_subject);
forge_uri(uri);
@@ -371,10 +390,12 @@ AtomWriter::del(const Raul::URI& uri)
void
AtomWriter::set_property(const Raul::URI& subject,
const Raul::URI& predicate,
- const Atom& value)
+ const Atom& value,
+ Resource::Graph ctx)
{
LV2_Atom_Forge_Frame msg;
forge_request(&msg, _uris.patch_Set);
+ forge_context(ctx);
lv2_atom_forge_key(&_forge, _uris.patch_subject);
forge_uri(subject);
lv2_atom_forge_key(&_forge, _uris.patch_property);
diff --git a/src/Parser.cpp b/src/Parser.cpp
index c26553a9..c3d6eaaf 100644
--- a/src/Parser.cpp
+++ b/src/Parser.cpp
@@ -351,9 +351,8 @@ parse_graph(Ingen::World* world,
{
const URIs& uris = world->uris();
- const Sord::URI ingen_block(*world->rdf_world(), uris.ingen_block);
- const Sord::URI ingen_polyphony(*world->rdf_world(), uris.ingen_polyphony);
- const Sord::URI lv2_port(*world->rdf_world(), LV2_CORE__port);
+ const Sord::URI ingen_block(*world->rdf_world(), uris.ingen_block);
+ const Sord::URI lv2_port(*world->rdf_world(), LV2_CORE__port);
const Sord::Node& graph = subject_node;
const Sord::Node nil;
@@ -542,11 +541,11 @@ parse_properties(Ingen::World* world,
{
Properties properties = get_properties(world, model, subject, ctx);
- target->put(uri, properties);
+ target->put(uri, properties, ctx);
// Set passed properties last to override any loaded values
if (data)
- target->put(uri, data.get());
+ target->put(uri, data.get(), ctx);
return true;
}
diff --git a/src/URIs.cpp b/src/URIs.cpp
index 47cf64c9..f5e0903d 100644
--- a/src/URIs.cpp
+++ b/src/URIs.cpp
@@ -97,9 +97,11 @@ URIs::URIs(Forge& f, URIMap* map, LilvWorld* lworld)
, ingen_canvasX (forge, map, lworld, INGEN__canvasX)
, ingen_canvasY (forge, map, lworld, INGEN__canvasY)
, ingen_enabled (forge, map, lworld, INGEN__enabled)
+ , ingen_externalContext (forge, map, lworld, INGEN__externalContext)
, ingen_file (forge, map, lworld, INGEN__file)
, ingen_head (forge, map, lworld, INGEN__head)
, ingen_incidentTo (forge, map, lworld, INGEN__incidentTo)
+ , ingen_internalContext (forge, map, lworld, INGEN__internalContext)
, ingen_loadedBundle (forge, map, lworld, INGEN__loadedBundle)
, ingen_maxRunLoad (forge, map, lworld, INGEN__maxRunLoad)
, ingen_meanRunLoad (forge, map, lworld, INGEN__meanRunLoad)
@@ -169,6 +171,7 @@ URIs::URIs(Forge& f, URIMap* map, LilvWorld* lworld)
, patch_Set (forge, map, lworld, LV2_PATCH__Set)
, patch_add (forge, map, lworld, LV2_PATCH__add)
, patch_body (forge, map, lworld, LV2_PATCH__body)
+ , patch_context (forge, map, lworld, LV2_PATCH__context)
, patch_destination (forge, map, lworld, LV2_PATCH__destination)
, patch_property (forge, map, lworld, LV2_PATCH__property)
, patch_remove (forge, map, lworld, LV2_PATCH__remove)
diff --git a/src/client/ClientStore.cpp b/src/client/ClientStore.cpp
index eac853f7..a622068c 100644
--- a/src/client/ClientStore.cpp
+++ b/src/client/ClientStore.cpp
@@ -342,7 +342,8 @@ ClientStore::put(const Raul::URI& uri,
void
ClientStore::delta(const Raul::URI& uri,
const Properties& remove,
- const Properties& add)
+ const Properties& add,
+ Resource::Graph ctx)
{
if (uri == Raul::URI("ingen:/clients/this")) {
// Client property, which we don't store (yet?)
@@ -370,7 +371,8 @@ ClientStore::delta(const Raul::URI& uri,
void
ClientStore::set_property(const Raul::URI& subject_uri,
const Raul::URI& predicate,
- const Atom& value)
+ const Atom& value,
+ Resource::Graph ctx)
{
if (subject_uri == Raul::URI("ingen:/engine")) {
_log.info(fmt("Engine property <%1%> = %2%\n")
@@ -384,7 +386,7 @@ ClientStore::set_property(const Raul::URI& subject_uri,
blinkenlights) but do not store the property. */
subject->on_property(predicate, value);
} else {
- subject->set_property(predicate, value);
+ subject->set_property(predicate, value, ctx);
}
} else {
SPtr<PluginModel> plugin = _plugin(subject_uri);
diff --git a/src/client/PluginUI.cpp b/src/client/PluginUI.cpp
index b4631f0d..d4558ed4 100644
--- a/src/client/PluginUI.cpp
+++ b/src/client/PluginUI.cpp
@@ -73,7 +73,8 @@ lv2_ui_write(SuilController controller,
ui->signal_property_changed()(
port->uri(),
uris.ingen_value,
- ui->world()->forge().make(value));
+ ui->world()->forge().make(value),
+ Resource::Graph::DEFAULT);
} else if (format == uris.atom_eventTransfer.urid.get<LV2_URID>()) {
const LV2_Atom* atom = (const LV2_Atom*)buffer;
@@ -81,8 +82,8 @@ lv2_ui_write(SuilController controller,
atom->size, atom->type, LV2_ATOM_BODY_CONST(atom));
ui->signal_property_changed()(port->uri(),
uris.ingen_activity,
- val);
-
+ val,
+ Resource::Graph::DEFAULT);
} else {
ui->world()->log().warn(
fmt("Unknown value format %1% from LV2 UI\n")
@@ -119,7 +120,8 @@ lv2_ui_subscribe(SuilController controller,
ui->signal_property_changed()(
ui->block()->ports()[port_index]->uri(),
ui->world()->uris().ingen_broadcast,
- ui->world()->forge().make(true));
+ ui->world()->forge().make(true),
+ Resource::Graph::DEFAULT);
return 0;
}
@@ -139,7 +141,8 @@ lv2_ui_unsubscribe(SuilController controller,
ui->signal_property_changed()(
ui->block()->ports()[port_index]->uri(),
ui->world()->uris().ingen_broadcast,
- ui->world()->forge().make(false));
+ ui->world()->forge().make(false),
+ Resource::Graph::DEFAULT);
return 0;
}
diff --git a/src/gui/App.cpp b/src/gui/App.cpp
index d303348a..15bdc796 100644
--- a/src/gui/App.cpp
+++ b/src/gui/App.cpp
@@ -258,17 +258,18 @@ App::error_message(const string& str)
void
App::set_property(const Raul::URI& subject,
const Raul::URI& key,
- const Atom& value)
+ const Atom& value,
+ Resource::Graph ctx)
{
// Send message to server
- interface()->set_property(subject, key, value);
+ interface()->set_property(subject, key, value, ctx);
/* The server does not feed back set messages (kludge to prevent control
feedback and bandwidth wastage, see Delta.cpp). So, assume everything
went as planned here and fire the signal ourselves as if the server
feedback came back immediately. */
if (key != uris().ingen_activity) {
- _client->signal_property_change().emit(subject, key, value);
+ _client->signal_property_change().emit(subject, key, value, ctx);
}
}
@@ -298,7 +299,8 @@ App::put(const Raul::URI& uri,
void
App::property_change(const Raul::URI& subject,
const Raul::URI& key,
- const Atom& value)
+ const Atom& value,
+ Resource::Graph ctx)
{
if (subject != Raul::URI("ingen:/engine")) {
return;
diff --git a/src/gui/App.hpp b/src/gui/App.hpp
index 4967513c..6dcab171 100644
--- a/src/gui/App.hpp
+++ b/src/gui/App.hpp
@@ -101,7 +101,8 @@ public:
void set_property(const Raul::URI& subject,
const Raul::URI& key,
- const Atom& value);
+ const Atom& value,
+ Resource::Graph ctx = Resource::Graph::DEFAULT);
/** Set the tooltip for a widget from its RDF documentation. */
void set_tooltip(Gtk::Widget* widget, const LilvNode* node);
@@ -149,7 +150,8 @@ protected:
void property_change(const Raul::URI& subject,
const Raul::URI& key,
- const Atom& value);
+ const Atom& value,
+ Resource::Graph ctx = Resource::Graph::DEFAULT);
static Gtk::Main* _main;
diff --git a/src/gui/SubgraphModule.cpp b/src/gui/SubgraphModule.cpp
index 5c05153f..c261ec36 100644
--- a/src/gui/SubgraphModule.cpp
+++ b/src/gui/SubgraphModule.cpp
@@ -70,10 +70,10 @@ SubgraphModule::store_location(double ax, double ay)
if (x != _block->get_property(uris.ingen_canvasX) ||
y != _block->get_property(uris.ingen_canvasY))
{
- app().interface()->put(
- _graph->uri(),
- {{uris.ingen_canvasX, Property(x, Resource::Graph::EXTERNAL)},
- {uris.ingen_canvasY, Property(y, Resource::Graph::EXTERNAL)}});
+ app().interface()->put(_graph->uri(),
+ {{uris.ingen_canvasX, x},
+ {uris.ingen_canvasY, y}},
+ Resource::Graph::EXTERNAL);
}
}
diff --git a/src/server/Broadcaster.hpp b/src/server/Broadcaster.hpp
index 2d184559..fd8d3996 100644
--- a/src/server/Broadcaster.hpp
+++ b/src/server/Broadcaster.hpp
@@ -102,13 +102,14 @@ public:
void put(const Raul::URI& uri,
const Properties& properties,
Resource::Graph ctx = Resource::Graph::DEFAULT) {
- BROADCAST(put, uri, properties);
+ BROADCAST(put, uri, properties, ctx);
}
void delta(const Raul::URI& uri,
const Properties& remove,
- const Properties& add) {
- BROADCAST(delta, uri, remove, add);
+ const Properties& add,
+ Resource::Graph ctx = Resource::Graph::DEFAULT) {
+ BROADCAST(delta, uri, remove, add, ctx);
}
void copy(const Raul::URI& old_uri,
@@ -142,8 +143,9 @@ public:
void set_property(const Raul::URI& subject,
const Raul::URI& predicate,
- const Atom& value) {
- BROADCAST(set_property, subject, predicate, value);
+ const Atom& value,
+ Resource::Graph ctx = Resource::Graph::DEFAULT) {
+ BROADCAST(set_property, subject, predicate, value, ctx);
}
Raul::URI uri() const { return Raul::URI("ingen:/broadcaster"); }
diff --git a/src/server/EventWriter.cpp b/src/server/EventWriter.cpp
index 1cd573b2..28a8d319 100644
--- a/src/server/EventWriter.cpp
+++ b/src/server/EventWriter.cpp
@@ -78,14 +78,14 @@ EventWriter::put(const Raul::URI& uri,
}
void
-EventWriter::delta(const Raul::URI& uri,
- const Properties& remove,
- const Properties& add)
+EventWriter::delta(const Raul::URI& uri,
+ const Properties& remove,
+ const Properties& add,
+ const Resource::Graph ctx)
{
_engine.enqueue_event(
new Events::Delta(_engine, _respondee, _request_id, now(),
- Events::Delta::Type::PATCH, Resource::Graph::DEFAULT,
- uri, add, remove),
+ Events::Delta::Type::PATCH, ctx, uri, add, remove),
_event_mode);
}
@@ -149,13 +149,14 @@ EventWriter::disconnect_all(const Raul::Path& graph,
}
void
-EventWriter::set_property(const Raul::URI& uri,
- const Raul::URI& predicate,
- const Atom& value)
+EventWriter::set_property(const Raul::URI& uri,
+ const Raul::URI& predicate,
+ const Atom& value,
+ const Resource::Graph ctx)
{
_engine.enqueue_event(
new Events::Delta(_engine, _respondee, _request_id, now(),
- Events::Delta::Type::SET, Resource::Graph::DEFAULT,
+ Events::Delta::Type::SET, ctx,
uri, {{predicate, value}}, {}),
_event_mode);
}
diff --git a/src/server/EventWriter.hpp b/src/server/EventWriter.hpp
index 32e3b249..18e98421 100644
--- a/src/server/EventWriter.hpp
+++ b/src/server/EventWriter.hpp
@@ -63,7 +63,8 @@ public:
virtual void delta(const Raul::URI& path,
const Properties& remove,
- const Properties& add);
+ const Properties& add,
+ Resource::Graph ctx = Resource::Graph::DEFAULT);
virtual void copy(const Raul::URI& old_uri,
const Raul::URI& new_uri);
@@ -79,7 +80,8 @@ public:
virtual void set_property(const Raul::URI& subject_path,
const Raul::URI& predicate,
- const Atom& value);
+ const Atom& value,
+ Resource::Graph ctx = Resource::Graph::DEFAULT);
virtual void del(const Raul::URI& uri);
diff --git a/src/server/events/Delta.cpp b/src/server/events/Delta.cpp
index 9f4c1da2..ecc1830a 100644
--- a/src/server/events/Delta.cpp
+++ b/src/server/events/Delta.cpp
@@ -364,7 +364,7 @@ Delta::pre_process(PreProcessContext& ctx)
if (value.get<int32_t>() < 1 || value.get<int32_t>() > 128) {
_status = Status::INVALID_POLY;
} else {
- op = SpecialType::POLYPHONY;
+ op = SpecialType::POLYPHONY;
_graph->prepare_internal_poly(
*_engine.buffer_factory(), value.get<int32_t>());
}
@@ -585,7 +585,7 @@ Delta::post_process()
}
break;
case Type::PATCH:
- _engine.broadcaster()->delta(_subject, _remove, _properties);
+ _engine.broadcaster()->delta(_subject, _remove, _properties, _context);
break;
}
}
@@ -597,15 +597,17 @@ Delta::undo(Interface& target)
if (_create_event) {
_create_event->undo(target);
} else if (_type == Type::PATCH) {
- target.delta(_subject, _added, _removed);
+ target.delta(_subject, _added, _removed, _context);
} else if (_type == Type::SET || _type == Type::PUT) {
if (_removed.size() == 1) {
- target.set_property(
- _subject, _removed.begin()->first, _removed.begin()->second);
+ target.set_property(_subject,
+ _removed.begin()->first,
+ _removed.begin()->second,
+ _context);
} else if (_removed.empty()) {
- target.delta(_subject, _added, {});
+ target.delta(_subject, _added, {}, _context);
} else {
- target.put(_subject, _removed);
+ target.put(_subject, _removed, _context);
}
}
}