diff options
author | David Robillard <d@drobilla.net> | 2017-03-19 13:26:38 +0100 |
---|---|---|
committer | David Robillard <d@drobilla.net> | 2017-03-20 02:58:56 +0100 |
commit | f1c793f7e2148b10610a09a459d9e89b39d2d87b (patch) | |
tree | b898407dce08af0f2f978d59a85d4887d8555b54 /src | |
parent | efc0fe0a973db706d9409b345ad6fae585f4388c (diff) | |
download | ingen-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.cpp | 69 | ||||
-rw-r--r-- | src/AtomWriter.cpp | 25 | ||||
-rw-r--r-- | src/Parser.cpp | 9 | ||||
-rw-r--r-- | src/URIs.cpp | 3 | ||||
-rw-r--r-- | src/client/ClientStore.cpp | 8 | ||||
-rw-r--r-- | src/client/PluginUI.cpp | 13 | ||||
-rw-r--r-- | src/gui/App.cpp | 10 | ||||
-rw-r--r-- | src/gui/App.hpp | 6 | ||||
-rw-r--r-- | src/gui/SubgraphModule.cpp | 8 | ||||
-rw-r--r-- | src/server/Broadcaster.hpp | 12 | ||||
-rw-r--r-- | src/server/EventWriter.cpp | 19 | ||||
-rw-r--r-- | src/server/EventWriter.hpp | 6 | ||||
-rw-r--r-- | src/server/events/Delta.cpp | 16 |
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); } } } |