From 6b18de71d1c603255b263a64434005306f152f13 Mon Sep 17 00:00:00 2001 From: David Robillard Date: Sat, 19 Feb 2011 05:10:29 +0000 Subject: Save/load patches as nested bundles (fix ticket #520). Sane (context-based, ala RDF quads) approach to the problem of externally visible / internally visible properties. git-svn-id: http://svn.drobilla.net/lad/trunk/ingen@2993 a436a847-0d15-0410-975c-d299462d15a1 --- src/client/ClientStore.cpp | 62 +++--- src/client/ClientStore.hpp | 29 ++- src/client/HTTPEngineSender.cpp | 3 +- src/client/HTTPEngineSender.hpp | 3 +- src/client/OSCEngineSender.cpp | 3 +- src/client/OSCEngineSender.hpp | 3 +- src/client/ObjectModel.cpp | 18 +- src/client/ObjectModel.hpp | 3 - src/client/SigClientInterface.hpp | 9 +- src/client/ThreadedSigClientInterface.hpp | 16 +- src/common/interface/CommonInterface.hpp | 3 +- src/common/interface/GraphObject.hpp | 10 +- src/common/interface/Resource.hpp | 64 +++++- src/engine/ClientBroadcaster.hpp | 3 +- src/engine/DuplexPort.hpp | 4 +- src/engine/Engine.cpp | 20 +- src/engine/GraphObjectImpl.cpp | 8 +- src/engine/GraphObjectImpl.hpp | 8 +- src/engine/HTTPClientSender.cpp | 3 +- src/engine/HTTPClientSender.hpp | 3 +- src/engine/LV2Node.cpp | 2 - src/engine/NodeImpl.cpp | 12 +- src/engine/OSCClientSender.cpp | 3 +- src/engine/OSCClientSender.hpp | 3 +- src/engine/ObjectSender.cpp | 14 +- src/engine/PortImpl.hpp | 2 +- src/engine/QueuedEngineInterface.cpp | 28 +-- src/engine/QueuedEngineInterface.hpp | 3 +- src/engine/events/CreatePatch.cpp | 7 +- src/engine/events/CreatePort.cpp | 3 - src/engine/events/RequestMetadata.cpp | 6 +- src/engine/events/RequestMetadata.hpp | 22 +- src/engine/events/SetMetadata.cpp | 14 +- src/engine/events/SetMetadata.hpp | 4 +- src/gui/NewSubpatchWindow.cpp | 9 +- src/gui/NodeModule.cpp | 4 +- src/gui/PatchCanvas.cpp | 6 +- src/gui/PatchPortModule.cpp | 6 +- src/gui/PatchView.cpp | 4 - src/gui/PortPropertiesWindow.cpp | 2 +- src/serialisation/Parser.cpp | 341 +++++++++++++++++------------- src/serialisation/Parser.hpp | 4 +- src/serialisation/Serialiser.cpp | 212 +++++++++---------- src/serialisation/Serialiser.hpp | 26 +-- src/serialisation/serialisation.cpp | 2 +- src/shared/Builder.cpp | 1 - src/shared/ClashAvoider.cpp | 3 +- src/shared/ClashAvoider.hpp | 3 +- src/shared/ResourceImpl.cpp | 36 ++-- src/shared/ResourceImpl.hpp | 5 +- 50 files changed, 571 insertions(+), 491 deletions(-) diff --git a/src/client/ClientStore.cpp b/src/client/ClientStore.cpp index 2ac8a5ee..2b457aa0 100644 --- a/src/client/ClientStore.cpp +++ b/src/client/ClientStore.cpp @@ -97,10 +97,6 @@ ClientStore::add_object(SharedPtr object) } - for (Resource::Properties::const_iterator i = object->meta().properties().begin(); - i != object->meta().properties().end(); ++i) - object->signal_property(i->first, i->second); - for (Resource::Properties::const_iterator i = object->properties().begin(); i != object->properties().end(); ++i) object->signal_property(i->first, i->second); @@ -252,34 +248,41 @@ ClientStore::move(const Path& old_path_str, const Path& new_path_str) void -ClientStore::put(const URI& uri, const Resource::Properties& properties) +ClientStore::put(const URI& uri, + const Resource::Properties& properties, + Resource::Graph ctx) { typedef Resource::Properties::const_iterator iterator; - /*LOG(info) << "PUT " << uri << " {" << endl; + /* + LOG(info) << "PUT " << uri << " {" << endl; for (iterator i = properties.begin(); i != properties.end(); ++i) LOG(info) << " " << i->first << " = " << i->second << " :: " << i->second.type() << endl; - LOG(info) << "}" << endl;*/ - + LOG(info) << "}" << endl; + */ + + bool is_patch, is_node, is_port, is_output; + PortType data_type(PortType::UNKNOWN); + ResourceImpl::type(uris(), properties, is_patch, is_node, is_port, is_output, data_type); // Check if uri is a plugin const Atom& type = properties.find(_uris->rdf_type)->second; if (type.type() == Atom::URI) { - const URI& type_uri = type.get_uri(); - if (Plugin::type_from_uri(type_uri) != Plugin::NIL) { + const URI& type_uri = type.get_uri(); + const Plugin::Type plugin_type = Plugin::type_from_uri(type_uri); + if (plugin_type == Plugin::Patch) { + is_patch = true; + } else if (plugin_type != Plugin::NIL) { SharedPtr p(new PluginModel(uris(), uri, type_uri, properties)); add_plugin(p); return; } } - bool is_meta = ResourceImpl::is_meta_uri(uri); - - string path_str = is_meta ? (string("/") + uri.chop_start("#")) : uri.str(); - if (!Path::is_valid(path_str)) { - LOG(error) << "Bad path: " << uri.str() << " - " << path_str << endl; + if (!Path::is_valid(uri.str())) { + LOG(error) << "Bad path `" << uri.str() << "'" << endl; return; } - Path path(is_meta ? (string("/") + uri.chop_start("#")) : uri.str()); + const Path path(uri.str()); SharedPtr obj = PtrCast(object(path)); if (obj) { @@ -287,10 +290,6 @@ ClientStore::put(const URI& uri, const Resource::Properties& properties) return; } - bool is_patch, is_node, is_port, is_output; - PortType data_type(PortType::UNKNOWN); - ResourceImpl::type(uris(), properties, is_patch, is_node, is_port, is_output, data_type); - if (path.is_root()) { is_patch = true; } @@ -347,14 +346,13 @@ ClientStore::delta(const URI& uri, const Resource::Properties& remove, const Res for (iterator i = add.begin(); i != add.end(); ++i) LOG(info) << " + " << i->first << " = " << i->second << " :: " << i->second.type() << endl; LOG(info) << "}" << endl;*/ - bool is_meta = ResourceImpl::is_meta_uri(uri); - string path_str = is_meta ? (string("/") + uri.chop_start("#")) : uri.str(); - if (!Path::is_valid(path_str)) { - LOG(error) << "Bad path: " << uri.str() << " - " << path_str << endl; + + if (!Path::is_valid(uri.str())) { + LOG(error) << "Bad path `" << uri.str() << "'" << endl; return; } - Path path(is_meta ? (string("/") + uri.chop_start("#")) : uri.str()); + const Path path(uri.str()); SharedPtr obj = object(path); if (obj) { @@ -370,23 +368,15 @@ void ClientStore::set_property(const URI& subject_uri, const URI& predicate, const Atom& value) { SharedPtr subject = resource(subject_uri); - - size_t hash = subject_uri.find("#"); - if (!value.is_valid()) { - LOG(error) << "Property '" << predicate << "' is invalid" << endl; - } else if (subject) { + if (subject) { subject->set_property(predicate, value); - } else if (ResourceImpl::is_meta_uri(subject_uri)) { - Path instance_path = string("/") + subject_uri.substr(hash + 1); - SharedPtr om = PtrCast(subject); - if (om) - om->meta().set_property(predicate, value); } else { SharedPtr plugin = this->plugin(subject_uri); if (plugin) plugin->set_property(predicate, value); else - LOG(warn) << "Property '" << predicate << "' for unknown object " << subject_uri << endl; + LOG(warn) << "Property '" << predicate << "' for unknown object " + << subject_uri << endl; } } diff --git a/src/client/ClientStore.hpp b/src/client/ClientStore.hpp index a2a424c8..a3928760 100644 --- a/src/client/ClientStore.hpp +++ b/src/client/ClientStore.hpp @@ -71,13 +71,28 @@ public: // CommonInterface bool new_object(const Shared::GraphObject* object); - void put(const Raul::URI& path, const Shared::Resource::Properties& properties); - void delta(const Raul::URI& path, const Shared::Resource::Properties& remove, - const Shared::Resource::Properties& add); - void move(const Raul::Path& old_path, const Raul::Path& new_path); - void set_property(const Raul::URI& subject_path, const Raul::URI& predicate, const Raul::Atom& value); - void connect(const Raul::Path& src_port_path, const Raul::Path& dst_port_path); - void disconnect(const Raul::Path& src_port_path, const Raul::Path& dst_port_path); + + void put(const Raul::URI& uri, + const Shared::Resource::Properties& properties, + Shared::Resource::Graph ctx=Shared::Resource::DEFAULT); + + void delta(const Raul::URI& uri, + const Shared::Resource::Properties& remove, + const Shared::Resource::Properties& add); + + void move(const Raul::Path& old_path, + const Raul::Path& new_path); + + void set_property(const Raul::URI& subject_path, + const Raul::URI& predicate, + const Raul::Atom& value); + + void connect(const Raul::Path& src_port_path, + const Raul::Path& dst_port_path); + + void disconnect(const Raul::Path& src_port_path, + const Raul::Path& dst_port_path); + void del(const Raul::Path& path); sigc::signal< void, SharedPtr > signal_new_object; diff --git a/src/client/HTTPEngineSender.cpp b/src/client/HTTPEngineSender.cpp index 6468deef..84448743 100644 --- a/src/client/HTTPEngineSender.cpp +++ b/src/client/HTTPEngineSender.cpp @@ -116,7 +116,8 @@ HTTPEngineSender::quit() void HTTPEngineSender::put(const URI& uri, - const Resource::Properties& properties) + const Resource::Properties& properties, + Shared::Resource::Graph ctx) { const string path = (uri.substr(0, 6) == "path:/") ? uri.substr(6) : uri.str(); const string full_uri = _engine_url.str() + "/" + path; diff --git a/src/client/HTTPEngineSender.hpp b/src/client/HTTPEngineSender.hpp index 12ba98b5..2b31701f 100644 --- a/src/client/HTTPEngineSender.hpp +++ b/src/client/HTTPEngineSender.hpp @@ -85,7 +85,8 @@ public: // Object commands virtual void put(const Raul::URI& path, - const Shared::Resource::Properties& properties); + const Shared::Resource::Properties& properties, + Shared::Resource::Graph ctx=Shared::Resource::DEFAULT); virtual void delta(const Raul::URI& path, const Shared::Resource::Properties& remove, diff --git a/src/client/OSCEngineSender.cpp b/src/client/OSCEngineSender.cpp index 66327768..512d21aa 100644 --- a/src/client/OSCEngineSender.cpp +++ b/src/client/OSCEngineSender.cpp @@ -135,7 +135,8 @@ OSCEngineSender::quit() void OSCEngineSender::put(const Raul::URI& path, - const Shared::Resource::Properties& properties) + const Shared::Resource::Properties& properties, + Shared::Resource::Graph ctx) { typedef Shared::Resource::Properties::const_iterator iterator; lo_message m = lo_message_new(); diff --git a/src/client/OSCEngineSender.hpp b/src/client/OSCEngineSender.hpp index c2146f7a..c696eb1b 100644 --- a/src/client/OSCEngineSender.hpp +++ b/src/client/OSCEngineSender.hpp @@ -78,7 +78,8 @@ public: // Object commands virtual void put(const Raul::URI& path, - const Shared::Resource::Properties& properties); + const Shared::Resource::Properties& properties, + Shared::Resource::Graph ctx=Shared::Resource::DEFAULT); virtual void delta(const Raul::URI& path, const Shared::Resource::Properties& remove, diff --git a/src/client/ObjectModel.cpp b/src/client/ObjectModel.cpp index d3726862..728d530e 100644 --- a/src/client/ObjectModel.cpp +++ b/src/client/ObjectModel.cpp @@ -29,7 +29,7 @@ namespace Client { ObjectModel::ObjectModel(Shared::LV2URIMap& uris, const Raul::Path& path) : ResourceImpl(uris, path) - , _meta(uris, ResourceImpl::meta_uri(path)) + , _meta(uris, Raul::URI("http://example.org/FIXME")) , _path(path) , _symbol((path == Path::root()) ? "root" : path.symbol()) { @@ -62,8 +62,7 @@ ObjectModel::set_property(const Raul::URI& key, const Raul::Atom& value) Raul::Atom& ObjectModel::set_meta_property(const Raul::URI& key, const Raul::Atom& value) { - signal_property.emit(key, value); - return _meta.set_property(key, value); + return set_property(key, Resource::Property(value, Resource::INTERNAL)); } @@ -78,8 +77,9 @@ ObjectModel::add_property(const Raul::URI& key, const Raul::Atom& value) const Atom& ObjectModel::get_property(const Raul::URI& key) const { + static const Atom null_atom; Resource::Properties::const_iterator i = properties().find(key); - return (i != properties().end()) ? i->second : _meta.get_property(key); + return (i != properties().end()) ? i->second : null_atom; } @@ -103,11 +103,8 @@ ObjectModel::set(SharedPtr o) if (o->_parent) _parent = o->_parent; - for (Properties::const_iterator v = o->meta().properties().begin(); v != o->meta().properties().end(); ++v) { - o->meta().set_property(v->first, v->second); - signal_property.emit(v->first, v->second); - } - for (Properties::const_iterator v = o->properties().begin(); v != o->properties().end(); ++v) { + for (Properties::const_iterator v = o->properties().begin(); + v != o->properties().end(); ++v) { ResourceImpl::set_property(v->first, v->second); signal_property.emit(v->first, v->second); } @@ -117,9 +114,8 @@ ObjectModel::set(SharedPtr o) void ObjectModel::set_path(const Raul::Path& p) { - _path = p; + _path = p; _symbol = p.symbol(); - _meta.set_uri(ResourceImpl::meta_uri(p)); signal_moved.emit(); } diff --git a/src/client/ObjectModel.hpp b/src/client/ObjectModel.hpp index 9f480567..0899ed99 100644 --- a/src/client/ObjectModel.hpp +++ b/src/client/ObjectModel.hpp @@ -62,9 +62,6 @@ public: void add_property(const Raul::URI& key, const Raul::Atom& value); Raul::Atom& set_meta_property(const Raul::URI& key, const Raul::Atom& value); - Resource& meta() { return _meta; } - const Resource& meta() const { return _meta; } - const Raul::URI& meta_uri() const { return _meta.uri(); } const Raul::Path& path() const { return _path; } const Raul::Symbol& symbol() const { return _symbol; } SharedPtr parent() const { return _parent; } diff --git a/src/client/SigClientInterface.hpp b/src/client/SigClientInterface.hpp index a2c6da73..55965fd2 100644 --- a/src/client/SigClientInterface.hpp +++ b/src/client/SigClientInterface.hpp @@ -50,7 +50,8 @@ public: sigc::signal signal_error; sigc::signal signal_new_patch; sigc::signal signal_new_port; - sigc::signal signal_put; + sigc::signal signal_put; sigc::signal signal_delta; sigc::signal signal_object_moved; @@ -89,8 +90,10 @@ protected: void error(const std::string& msg) { EMIT(error, msg); } - void put(const Raul::URI& uri, const Shared::Resource::Properties& properties) - { EMIT(put, uri, properties); } + void put(const Raul::URI& uri, + const Shared::Resource::Properties& properties, + Shared::Resource::Graph ctx=Shared::Resource::DEFAULT) + { EMIT(put, uri, properties, ctx); } void delta(const Raul::URI& uri, const Shared::Resource::Properties& remove, const Shared::Resource::Properties& add) diff --git a/src/client/ThreadedSigClientInterface.hpp b/src/client/ThreadedSigClientInterface.hpp index 5f5ea5a9..06a8da73 100644 --- a/src/client/ThreadedSigClientInterface.hpp +++ b/src/client/ThreadedSigClientInterface.hpp @@ -83,11 +83,14 @@ public: void error(const std::string& msg) { push_sig(sigc::bind(error_slot, msg)); } - void put(const Raul::URI& path, const Shared::Resource::Properties& properties) - { push_sig(sigc::bind(put_slot, path, properties)); } - - void delta(const Raul::URI& path, - const Shared::Resource::Properties& remove, const Shared::Resource::Properties& add) + void put(const Raul::URI& path, + const Shared::Resource::Properties& properties, + Shared::Resource::Graph ctx=Shared::Resource::DEFAULT) + { push_sig(sigc::bind(put_slot, path, properties, ctx)); } + + void delta(const Raul::URI& path, + const Shared::Resource::Properties& remove, + const Shared::Resource::Properties& add) { push_sig(sigc::bind(delta_slot, path, remove, add)); } void connect(const Raul::Path& src_port_path, const Raul::Path& dst_port_path) @@ -126,7 +129,8 @@ private: sigc::slot error_slot; sigc::slot new_plugin_slot; sigc::slot new_port_slot; - sigc::slot put_slot; + sigc::slot put_slot; sigc::slot delta_slot; sigc::slot connection_slot; diff --git a/src/common/interface/CommonInterface.hpp b/src/common/interface/CommonInterface.hpp index efd80050..cbf3573c 100644 --- a/src/common/interface/CommonInterface.hpp +++ b/src/common/interface/CommonInterface.hpp @@ -46,7 +46,8 @@ public: virtual void bundle_end() = 0; virtual void put(const Raul::URI& uri, - const Resource::Properties& properties) = 0; + const Resource::Properties& properties, + Resource::Graph ctx=Resource::DEFAULT) = 0; virtual void delta(const Raul::URI& uri, const Resource::Properties& remove, diff --git a/src/common/interface/GraphObject.hpp b/src/common/interface/GraphObject.hpp index de908cc5..ed592971 100644 --- a/src/common/interface/GraphObject.hpp +++ b/src/common/interface/GraphObject.hpp @@ -39,15 +39,11 @@ class GraphObject : public Raul::Deletable , public virtual Resource { public: - virtual const Resource& meta() const = 0; - virtual Resource& meta() = 0; - virtual void set_path(const Raul::Path& path) = 0; - virtual const Raul::Path& path() const = 0; - virtual const Raul::Symbol& symbol() const = 0; - - virtual GraphObject* graph_parent() const = 0; + virtual const Raul::Path& path() const = 0; + virtual const Raul::Symbol& symbol() const = 0; + virtual GraphObject* graph_parent() const = 0; }; diff --git a/src/common/interface/Resource.hpp b/src/common/interface/Resource.hpp index c5b5624a..3b2f9aa6 100644 --- a/src/common/interface/Resource.hpp +++ b/src/common/interface/Resource.hpp @@ -30,22 +30,66 @@ namespace Shared { class Resource { public: + enum Graph { + DEFAULT, + EXTERNAL, + INTERNAL + }; + + class Property : public Raul::Atom { + public: + Property(const Raul::Atom& atom, Graph ctx=DEFAULT) + : Raul::Atom(atom) + , _ctx(ctx) + {} + + Property() : Raul::Atom(), _ctx(DEFAULT) {} + Property(int32_t val) : Raul::Atom(val), _ctx(DEFAULT) {} + Property(float val) : Raul::Atom(val), _ctx(DEFAULT) {} + Property(bool val) : Raul::Atom(val), _ctx(DEFAULT) {} + Property(const char* val) : Raul::Atom(val), _ctx(DEFAULT) {} + Property(const std::string& val) : Raul::Atom(val), _ctx(DEFAULT) {} + + Property(const Raul::Atom::DictValue& dict) + : Raul::Atom(dict) + , _ctx(DEFAULT) + {} + + Property(Type t, const std::string& uri) + : Raul::Atom(t, uri) + , _ctx(DEFAULT) + {} + + Graph context() const { return _ctx; } + void set_context(Graph ctx) { _ctx = ctx; } + + private: + Graph _ctx; + }; + virtual ~Resource() {} - typedef std::multimap Properties; - virtual const Raul::URI& uri() const = 0; - virtual const Properties& properties() const = 0; - virtual Properties& properties() = 0; + virtual const Raul::URI& uri() const = 0; - virtual Raul::Atom& set_property(const Raul::URI& uri, - const Raul::Atom& value) = 0; + typedef std::multimap Properties; - virtual void add_property(const Raul::URI& uri, - const Raul::Atom& value) = 0; + static void set_context(Properties& props, Graph ctx) { + for (Properties::iterator i = props.begin(); i != props.end(); ++i) { + i->second.set_context(ctx); + } + } - virtual const Raul::Atom& get_property(const Raul::URI& uri) const = 0; + virtual Properties properties(Resource::Graph ctx) const = 0; - virtual bool has_property(const Raul::URI& uri, const Raul::Atom& value) const = 0; + virtual const Properties& properties() const = 0; + virtual Properties& properties() = 0; + virtual const Raul::Atom& get_property(const Raul::URI& uri) const = 0; + virtual Raul::Atom& set_property(const Raul::URI& uri, + const Raul::Atom& value) = 0; + virtual void add_property(const Raul::URI& uri, + const Raul::Atom& value) = 0; + virtual bool has_property(const Raul::URI& uri, + const Raul::Atom& value) const = 0; }; diff --git a/src/engine/ClientBroadcaster.hpp b/src/engine/ClientBroadcaster.hpp index 4102f50e..11668218 100644 --- a/src/engine/ClientBroadcaster.hpp +++ b/src/engine/ClientBroadcaster.hpp @@ -69,7 +69,8 @@ public: void bundle_end() { BROADCAST(bundle_end); } void put(const Raul::URI& uri, - const Shared::Resource::Properties& properties) { + const Shared::Resource::Properties& properties, + Shared::Resource::Graph ctx=Shared::Resource::DEFAULT) { BROADCAST(put, uri, properties); } diff --git a/src/engine/DuplexPort.hpp b/src/engine/DuplexPort.hpp index 9d1db378..3c7ad421 100644 --- a/src/engine/DuplexPort.hpp +++ b/src/engine/DuplexPort.hpp @@ -54,8 +54,8 @@ public: bool get_buffers(BufferFactory& bufs, Raul::Array* buffers, uint32_t poly); - void pre_process(Context& context); - void post_process(Context& context); + void pre_process(Ingen::Context& context); + void post_process(Ingen::Context& context); bool is_input() const { return !_is_output; } bool is_output() const { return _is_output; } diff --git a/src/engine/Engine.cpp b/src/engine/Engine.cpp index 8e0d7e0e..12c479f5 100644 --- a/src/engine/Engine.cpp +++ b/src/engine/Engine.cpp @@ -179,9 +179,11 @@ Engine::activate() PatchImpl* root_patch = _driver->root_patch(); if (!root_patch) { root_patch = new PatchImpl(*this, "root", 1, NULL, _driver->sample_rate(), 1); - root_patch->meta().set_property(uris.rdf_type, uris.ingen_Patch); - root_patch->meta().set_property(uris.ingen_polyphony, Raul::Atom(int32_t(1))); - root_patch->set_property(uris.rdf_type, uris.ingen_Node); + root_patch->set_property(uris.rdf_type, + Resource::Property(uris.ingen_Patch, Resource::INTERNAL)); + root_patch->set_property(uris.ingen_polyphony, + Resource::Property(Raul::Atom(int32_t(1)), + Resource::INTERNAL)); root_patch->activate(*_buffer_factory); _world->store()->add(root_patch); root_patch->compiled_patch(root_patch->compile()); @@ -197,8 +199,10 @@ Engine::activate() Shared::Resource::Properties in_properties(control_properties); in_properties.insert(make_pair(uris.rdf_type, uris.lv2_InputPort)); in_properties.insert(make_pair(uris.lv2_index, 0)); - in_properties.insert(make_pair(uris.ingenui_canvas_x, 32.0f)); - in_properties.insert(make_pair(uris.ingenui_canvas_y, 32.0f)); + in_properties.insert(make_pair(uris.ingenui_canvas_x, + Resource::Property(32.0f, Resource::EXTERNAL))); + in_properties.insert(make_pair(uris.ingenui_canvas_y, + Resource::Property(32.0f, Resource::EXTERNAL))); execute_and_delete_event(context, new Events::CreatePort( *this, SharedPtr(), 0, @@ -208,8 +212,10 @@ Engine::activate() Shared::Resource::Properties out_properties(control_properties); out_properties.insert(make_pair(uris.rdf_type, uris.lv2_OutputPort)); out_properties.insert(make_pair(uris.lv2_index, 1)); - out_properties.insert(make_pair(uris.ingenui_canvas_x, 128.0f)); - out_properties.insert(make_pair(uris.ingenui_canvas_y, 32.0f)); + out_properties.insert(make_pair(uris.ingenui_canvas_x, + Resource::Property(128.0f, Resource::EXTERNAL))); + out_properties.insert(make_pair(uris.ingenui_canvas_y, + Resource::Property(32.0f, Resource::EXTERNAL))); execute_and_delete_event(context, new Events::CreatePort( *this, SharedPtr(), 0, diff --git a/src/engine/GraphObjectImpl.cpp b/src/engine/GraphObjectImpl.cpp index 87a9a844..c257b319 100644 --- a/src/engine/GraphObjectImpl.cpp +++ b/src/engine/GraphObjectImpl.cpp @@ -35,7 +35,6 @@ GraphObjectImpl::GraphObjectImpl(Shared::LV2URIMap& uris, , _parent(parent) , _path(parent ? parent->path().child(symbol) : "/") , _symbol(symbol) - , _meta(uris, ResourceImpl::meta_uri(uri())) { } @@ -43,22 +42,23 @@ GraphObjectImpl::GraphObjectImpl(Shared::LV2URIMap& uris, void GraphObjectImpl::add_meta_property(const Raul::URI& key, const Atom& value) { - _meta.add_property(key, value); + add_property(key, Resource::Property(value, Resource::INTERNAL)); } void GraphObjectImpl::set_meta_property(const Raul::URI& key, const Atom& value) { - _meta.set_property(key, value); + set_property(key, Resource::Property(value, Resource::INTERNAL)); } const Atom& GraphObjectImpl::get_property(const Raul::URI& key) const { + static const Atom null_atom; Resource::Properties::const_iterator i = properties().find(key); - return (i != properties().end()) ? i->second : _meta.get_property(key); + return (i != properties().end()) ? i->second : null_atom; } diff --git a/src/engine/GraphObjectImpl.hpp b/src/engine/GraphObjectImpl.hpp index 3f8defe7..59f28b3e 100644 --- a/src/engine/GraphObjectImpl.hpp +++ b/src/engine/GraphObjectImpl.hpp @@ -54,14 +54,11 @@ class GraphObjectImpl : virtual public Ingen::Shared::GraphObject public: virtual ~GraphObjectImpl() {} - const Raul::URI& meta_uri() const { return _meta.uri(); } - const Raul::URI& uri() const { return _path; } - const Raul::Symbol& symbol() const { return _symbol; } + const Raul::URI& uri() const { return _path; } + const Raul::Symbol& symbol() const { return _symbol; } GraphObject* graph_parent() const { return _parent; } GraphObjectImpl* parent() const { return _parent; } - Resource& meta() { return _meta; } - const Resource& meta() const { return _meta; } //virtual void process(ProcessContext& context) = 0; @@ -106,7 +103,6 @@ protected: GraphObjectImpl* _parent; Raul::Path _path; Raul::Symbol _symbol; - ResourceImpl _meta; }; diff --git a/src/engine/HTTPClientSender.cpp b/src/engine/HTTPClientSender.cpp index 6f1f293a..e5633c4c 100644 --- a/src/engine/HTTPClientSender.cpp +++ b/src/engine/HTTPClientSender.cpp @@ -54,7 +54,8 @@ HTTPClientSender::error(const std::string& msg) void HTTPClientSender::put(const URI& uri, - const Resource::Properties& properties) + const Resource::Properties& properties, + Shared::Resource::Graph ctx) { const string path = (uri.substr(0, 6) == "path:/") ? uri.substr(6) : uri.str(); const string full_uri = _url + "/" + path; diff --git a/src/engine/HTTPClientSender.hpp b/src/engine/HTTPClientSender.hpp index 37b9b112..630bdd5a 100644 --- a/src/engine/HTTPClientSender.hpp +++ b/src/engine/HTTPClientSender.hpp @@ -68,7 +68,8 @@ public: void error(const std::string& msg); virtual void put(const Raul::URI& path, - const Shared::Resource::Properties& properties); + const Shared::Resource::Properties& properties, + Shared::Resource::Graph ctx); virtual void delta(const Raul::URI& path, const Shared::Resource::Properties& remove, diff --git a/src/engine/LV2Node.cpp b/src/engine/LV2Node.cpp index ee6bf4ed..35da06ba 100644 --- a/src/engine/LV2Node.cpp +++ b/src/engine/LV2Node.cpp @@ -294,11 +294,9 @@ LV2Node::instantiate(BufferFactory& bufs) if (direction == INPUT && data_type == PortType::CONTROL) { port->set_value(val); if (!isnan(min_values[j])) { - port->meta().set_property(uris.lv2_minimum, min_values[j]); port->set_property(uris.lv2_minimum, min_values[j]); } if (!isnan(max_values[j])) { - port->meta().set_property(uris.lv2_maximum, max_values[j]); port->set_property(uris.lv2_maximum, max_values[j]); } } diff --git a/src/engine/NodeImpl.cpp b/src/engine/NodeImpl.cpp index e2bb1139..7c1e185a 100644 --- a/src/engine/NodeImpl.cpp +++ b/src/engine/NodeImpl.cpp @@ -91,7 +91,7 @@ NodeImpl::activate(BufferFactory& bufs) assert(!_activated); _activated = true; - for (unsigned long p = 0; p < num_ports(); ++p) { + for (uint32_t p = 0; p < num_ports(); ++p) { PortImpl* const port = _ports->at(p); port->setup_buffers(bufs, port->poly()); port->connect_buffers(); @@ -130,8 +130,9 @@ NodeImpl::prepare_poly(BufferFactory& bufs, uint32_t poly) if (!_polyphonic) poly = 1; - for (size_t i = 0; i < _ports->size(); ++i) - _ports->at(i)->prepare_poly(bufs, poly); + if (_ports) + for (size_t i = 0; i < _ports->size(); ++i) + _ports->at(i)->prepare_poly(bufs, poly); return true; } @@ -147,8 +148,9 @@ NodeImpl::apply_poly(Raul::Maid& maid, uint32_t poly) _polyphony = poly; - for (size_t i = 0; i < num_ports(); ++i) - _ports->at(i)->apply_poly(maid, poly); + if (_ports) + for (size_t i = 0; i < num_ports(); ++i) + _ports->at(i)->apply_poly(maid, poly); return true; } diff --git a/src/engine/OSCClientSender.cpp b/src/engine/OSCClientSender.cpp index 22f9d41f..75f330b3 100644 --- a/src/engine/OSCClientSender.cpp +++ b/src/engine/OSCClientSender.cpp @@ -110,7 +110,8 @@ OSCClientSender::error(const std::string& msg) */ void OSCClientSender::put(const Raul::URI& path, - const Shared::Resource::Properties& properties) + const Shared::Resource::Properties& properties, + Shared::Resource::Graph ctx) { typedef Shared::Resource::Properties::const_iterator iterator; lo_message m = lo_message_new(); diff --git a/src/engine/OSCClientSender.hpp b/src/engine/OSCClientSender.hpp index 09d2e452..7df10d15 100644 --- a/src/engine/OSCClientSender.hpp +++ b/src/engine/OSCClientSender.hpp @@ -67,7 +67,8 @@ public: void error(const std::string& msg); virtual void put(const Raul::URI& path, - const Shared::Resource::Properties& properties); + const Shared::Resource::Properties& properties, + Shared::Resource::Graph ctx=Shared::Resource::DEFAULT); virtual void delta(const Raul::URI& path, const Shared::Resource::Properties& remove, diff --git a/src/engine/ObjectSender.cpp b/src/engine/ObjectSender.cpp index 8253eb9c..b962da2e 100644 --- a/src/engine/ObjectSender.cpp +++ b/src/engine/ObjectSender.cpp @@ -63,8 +63,13 @@ ObjectSender::send_patch(ClientInterface* client, const PatchImpl* patch, bool r if (bundle) client->transfer_begin(); - client->put(patch->meta_uri(), patch->meta().properties()); - client->put(patch->path(), patch->properties()); + client->put(patch->path(), + patch->properties(Resource::INTERNAL), + Resource::INTERNAL); + + client->put(patch->path(), + patch->properties(Resource::EXTERNAL), + Resource::EXTERNAL); if (recursive) { // Send nodes @@ -131,11 +136,6 @@ ObjectSender::send_port(ClientInterface* client, const PortImpl* port, bool bund if (bundle) client->bundle_begin(); - PatchImpl* graph_parent = dynamic_cast(port->parent_node()); - - if (graph_parent) - client->put(port->meta_uri(), port->meta().properties()); - client->put(port->path(), port->properties()); // Send control value diff --git a/src/engine/PortImpl.hpp b/src/engine/PortImpl.hpp index 2ae853bd..c9b74ca4 100644 --- a/src/engine/PortImpl.hpp +++ b/src/engine/PortImpl.hpp @@ -133,7 +133,7 @@ public: void raise_set_by_user_flag() { _set_by_user = true; } - Context::ID context() const { return _context; } + Context::ID context() const { return _context; } void set_context(Context::ID c); BufferFactory& bufs() const { return _bufs; } diff --git a/src/engine/QueuedEngineInterface.cpp b/src/engine/QueuedEngineInterface.cpp index 3984ca39..c1051c0a 100644 --- a/src/engine/QueuedEngineInterface.cpp +++ b/src/engine/QueuedEngineInterface.cpp @@ -157,13 +157,11 @@ QueuedEngineInterface::bundle_end() void -QueuedEngineInterface::put(const URI& uri, - const Resource::Properties& properties) +QueuedEngineInterface::put(const URI& uri, + const Resource::Properties& properties, + const Shared::Resource::Graph ctx) { - bool meta = ResourceImpl::is_meta_uri(uri); - URI subject(meta ? (string("path:/") + uri.substr(6)) : uri.str()); - - push_queued(new Events::SetMetadata(_engine, _request, now(), true, meta, subject, properties)); + push_queued(new Events::SetMetadata(_engine, _request, now(), true, ctx, uri, properties)); } @@ -172,10 +170,7 @@ QueuedEngineInterface::delta(const URI& uri, const Shared::Resource::Properties& remove, const Shared::Resource::Properties& add) { - bool meta = ResourceImpl::is_meta_uri(uri); - URI subject(meta ? (string("path:/") + uri.substr(6)) : uri.str()); - - push_queued(new Events::SetMetadata(_engine, _request, now(), false, meta, subject, add, remove)); + push_queued(new Events::SetMetadata(_engine, _request, now(), false, Resource::DEFAULT, uri, add, remove)); } @@ -224,14 +219,11 @@ QueuedEngineInterface::set_property(const URI& uri, const URI& predicate, const Atom& value) { - size_t hash = uri.find("#"); - bool meta = (hash != string::npos); - Path path = meta ? (string("/") + path.chop_start("/")) : uri.str(); Resource::Properties remove; remove.insert(make_pair(predicate, _engine.world()->uris()->wildcard)); Resource::Properties add; add.insert(make_pair(predicate, value)); - push_queued(new Events::SetMetadata(_engine, _request, now(), false, meta, path, add, remove)); + push_queued(new Events::SetMetadata(_engine, _request, now(), false, Resource::DEFAULT, uri, add, remove)); } // Requests // @@ -257,13 +249,7 @@ QueuedEngineInterface::get(const URI& uri) void QueuedEngineInterface::request_property(const URI& uri, const URI& key) { - size_t hash = uri.find("#"); - bool meta = (hash != string::npos); - const string path_str = string("/") + uri.chop_start("/"); - if (meta && Path::is_valid(path_str)) - push_queued(new Events::RequestMetadata(_engine, _request, now(), meta, path_str, key)); - else - push_queued(new Events::RequestMetadata(_engine, _request, now(), meta, uri, key)); + push_queued(new Events::RequestMetadata(_engine, _request, now(), Resource::DEFAULT, uri, key)); } diff --git a/src/engine/QueuedEngineInterface.hpp b/src/engine/QueuedEngineInterface.hpp index b6d06134..2c1e94b9 100644 --- a/src/engine/QueuedEngineInterface.hpp +++ b/src/engine/QueuedEngineInterface.hpp @@ -72,7 +72,8 @@ public: // CommonInterface object commands virtual void put(const Raul::URI& path, - const Shared::Resource::Properties& properties); + const Shared::Resource::Properties& properties, + const Shared::Resource::Graph g=Shared::Resource::DEFAULT); virtual void delta(const Raul::URI& path, const Shared::Resource::Properties& remove, diff --git a/src/engine/events/CreatePatch.cpp b/src/engine/events/CreatePatch.cpp index 38f97fe4..f5e07797 100644 --- a/src/engine/events/CreatePatch.cpp +++ b/src/engine/events/CreatePatch.cpp @@ -87,9 +87,10 @@ CreatePatch::pre_process() _patch = new PatchImpl(_engine, path.symbol(), poly, _parent, _engine.driver()->sample_rate(), _poly); - _patch->meta().properties().insert(_properties.begin(), _properties.end()); - _patch->meta().set_property(uris.rdf_type, uris.ingen_Patch); - _patch->set_property(uris.rdf_type, uris.ingen_Node); + _patch->properties().insert(_properties.begin(), _properties.end()); + _patch->add_property(uris.rdf_type, uris.ingen_Patch); + _patch->add_property(uris.rdf_type, + Resource::Property(uris.ingen_Node, Resource::EXTERNAL)); if (_parent != NULL) { _parent->add_node(new PatchImpl::Nodes::Node(_patch)); diff --git a/src/engine/events/CreatePort.cpp b/src/engine/events/CreatePort.cpp index 332cb1ce..cb05a020 100644 --- a/src/engine/events/CreatePort.cpp +++ b/src/engine/events/CreatePort.cpp @@ -110,11 +110,8 @@ CreatePort::pre_process() && poly_i->second.get_bool()); _patch_port = _patch->create_port(*_engine.buffer_factory(), _path.symbol(), _data_type, buffer_size, _is_output, polyphonic); - if (_patch->parent()) - _patch_port->set_property(uris.rdf_instanceOf, _patch_port->meta_uri()); _patch_port->properties().insert(_properties.begin(), _properties.end()); - _patch_port->meta().properties().insert(_properties.begin(), _properties.end()); assert(index_i->second == Atom((int)_patch_port->index())); diff --git a/src/engine/events/RequestMetadata.cpp b/src/engine/events/RequestMetadata.cpp index fd8d98fe..e16bf57a 100644 --- a/src/engine/events/RequestMetadata.cpp +++ b/src/engine/events/RequestMetadata.cpp @@ -43,7 +43,7 @@ using namespace Shared; RequestMetadata::RequestMetadata(Engine& engine, SharedPtr request, SampleCount timestamp, - bool is_meta, + Resource::Graph ctx, const URI& subject, const URI& key) : QueuedEvent(engine, request, timestamp) @@ -51,7 +51,7 @@ RequestMetadata::RequestMetadata(Engine& engine, , _uri(subject) , _key(key) , _resource(0) - , _is_meta(is_meta) + , _context(ctx) { } @@ -76,8 +76,6 @@ RequestMetadata::pre_process() if (obj) { if (_key == _engine.world()->uris()->ingen_value) _special_type = PORT_VALUE; - else if (_is_meta) - _value = obj->meta().get_property(_key); else _value = obj->get_property(_key); } else { diff --git a/src/engine/events/RequestMetadata.hpp b/src/engine/events/RequestMetadata.hpp index 99c77651..96afe6b2 100644 --- a/src/engine/events/RequestMetadata.hpp +++ b/src/engine/events/RequestMetadata.hpp @@ -44,12 +44,12 @@ namespace Events { class RequestMetadata : public QueuedEvent { public: - RequestMetadata(Engine& engine, - SharedPtr request, - SampleCount timestamp, - bool meta, - const Raul::URI& subject, - const Raul::URI& key); + RequestMetadata(Engine& engine, + SharedPtr request, + SampleCount timestamp, + Shared::Resource::Graph context, + const Raul::URI& subject, + const Raul::URI& key); void pre_process(); void execute(ProcessContext& context); @@ -62,11 +62,11 @@ private: PORT_VALUE } _special_type; - Raul::URI _uri; - Raul::URI _key; - Raul::Atom _value; - Shared::ResourceImpl* _resource; - bool _is_meta; + Raul::URI _uri; + Raul::URI _key; + Raul::Atom _value; + Shared::ResourceImpl* _resource; + Shared::Resource::Graph _context; }; diff --git a/src/engine/events/SetMetadata.cpp b/src/engine/events/SetMetadata.cpp index d1a1c53e..a6b446d4 100644 --- a/src/engine/events/SetMetadata.cpp +++ b/src/engine/events/SetMetadata.cpp @@ -54,7 +54,7 @@ SetMetadata::SetMetadata( SharedPtr request, SampleCount timestamp, bool create, - bool meta, + Resource::Graph context, const URI& subject, const Properties& properties, const Properties& remove) @@ -67,10 +67,14 @@ SetMetadata::SetMetadata( , _patch(NULL) , _compiled_patch(NULL) , _create(create) - , _is_meta(meta) + , _context(context) { + if (context != Resource::DEFAULT) { + Resource::set_context(_properties, context); + } + /* - LOG(info) << "Set " << subject << " {" << endl; + LOG(info) << "Set " << subject << " : " << context << " {" << endl; typedef Resource::Properties::const_iterator iterator; for (iterator i = properties.begin(); i != properties.end(); ++i) LOG(info) << " " << i->first << " = " << i->second << " :: " << i->second.type() << endl; @@ -177,7 +181,7 @@ SetMetadata::pre_process() const Raul::Atom& value = p->second; SpecialType op = NONE; if (obj) { - Resource& resource = _is_meta ? obj->meta() : *obj; + Resource& resource = *obj; resource.add_property(key, value); PortImpl* port = dynamic_cast(_object); @@ -353,7 +357,7 @@ SetMetadata::post_process() else _request->respond_ok(); if (_create) - _engine.broadcaster()->put(_subject, _properties); + _engine.broadcaster()->put(_subject, _properties, _context); else _engine.broadcaster()->delta(_subject, _remove, _properties); break; diff --git a/src/engine/events/SetMetadata.hpp b/src/engine/events/SetMetadata.hpp index b2e73679..021cb3f4 100644 --- a/src/engine/events/SetMetadata.hpp +++ b/src/engine/events/SetMetadata.hpp @@ -69,7 +69,7 @@ public: SharedPtr request, SampleCount timestamp, bool create, - bool meta, + Shared::Resource::Graph context, const Raul::URI& subject, const Shared::Resource::Properties& properties, const Shared::Resource::Properties& remove=Shared::Resource::Properties()); @@ -112,7 +112,7 @@ private: CompiledPatch* _compiled_patch; std::string _error_predicate; bool _create; - bool _is_meta; + Shared::Resource::Graph _context; SharedPtr _old_bindings; }; diff --git a/src/gui/NewSubpatchWindow.cpp b/src/gui/NewSubpatchWindow.cpp index 44fb54b0..13ea0c47 100644 --- a/src/gui/NewSubpatchWindow.cpp +++ b/src/gui/NewSubpatchWindow.cpp @@ -96,14 +96,17 @@ NewSubpatchWindow::ok_clicked() const Path path = _patch->path().base() + Path::nameify(_name_entry->get_text()); const uint32_t poly = _poly_spinbutton->get_value_as_int(); + // Create patch Resource::Properties props; props.insert(make_pair(app.uris().rdf_type, app.uris().ingen_Patch)); props.insert(make_pair(app.uris().ingen_polyphony, Atom(int32_t(poly)))); - app.engine()->put(ResourceImpl::meta_uri(path), props); + props.insert(make_pair(app.uris().ingen_enabled, Atom(bool(true)))); + app.engine()->put(path, props, Resource::INTERNAL); + // Set external (node perspective) properties props = _initial_data; - props.insert(make_pair(app.uris().ingen_enabled, bool(true))); - app.engine()->put(path, props); + props.insert(make_pair(app.uris().rdf_type, app.uris().ingen_Patch)); + app.engine()->put(path, _initial_data, Resource::EXTERNAL); hide(); } diff --git a/src/gui/NodeModule.cpp b/src/gui/NodeModule.cpp index 44748aeb..52f14772 100644 --- a/src/gui/NodeModule.cpp +++ b/src/gui/NodeModule.cpp @@ -94,9 +94,6 @@ NodeModule::create(boost::shared_ptr canvas, SharedPtr n else ret = boost::shared_ptr(new NodeModule(canvas, node)); - for (GraphObject::Properties::const_iterator m = node->meta().properties().begin(); m != node->meta().properties().end(); ++m) - ret->property_changed(m->first, m->second); - for (GraphObject::Properties::const_iterator m = node->properties().begin(); m != node->properties().end(); ++m) ret->property_changed(m->first, m->second); @@ -392,6 +389,7 @@ NodeModule::store_location() add.insert(make_pair(uris.ingenui_canvas_x, Atom(x))); add.insert(make_pair(uris.ingenui_canvas_y, Atom(y))); App::instance().engine()->delta(_node->path(), remove, add); + // FIXME: context } } diff --git a/src/gui/PatchCanvas.cpp b/src/gui/PatchCanvas.cpp index 3ee6e3cb..ce8c0892 100644 --- a/src/gui/PatchCanvas.cpp +++ b/src/gui/PatchCanvas.cpp @@ -645,8 +645,10 @@ PatchCanvas::copy_selection() for (list >::iterator c = _selected_connections.begin(); c != _selected_connections.end(); ++c) { boost::shared_ptr connection = boost::dynamic_pointer_cast(*c); - if (connection) - serialiser.serialise_connection(_patch, connection->model()); + if (connection) { + Sord::URI subject(*App::instance().world()->rdf_world(), _patch->path().str()); + serialiser.serialise_connection(subject, connection->model()); + } } string result = serialiser.finish(); diff --git a/src/gui/PatchPortModule.cpp b/src/gui/PatchPortModule.cpp index cbfb6f03..b8e74a8f 100644 --- a/src/gui/PatchPortModule.cpp +++ b/src/gui/PatchPortModule.cpp @@ -64,10 +64,6 @@ PatchPortModule::create(boost::shared_ptr canvas, SharedPtrset_port(port); ret->set_menu(port->menu()); - for (GraphObject::Properties::const_iterator m = model->meta().properties().begin(); - m != model->meta().properties().end(); ++m) - ret->property_changed(m->first, m->second); - for (GraphObject::Properties::const_iterator m = model->properties().begin(); m != model->properties().end(); ++m) ret->property_changed(m->first, m->second); @@ -104,7 +100,7 @@ PatchPortModule::store_location() Shared::Resource::Properties props; props.insert(make_pair(uris.ingenui_canvas_x, Atom(x))); props.insert(make_pair(uris.ingenui_canvas_y, Atom(y))); - App::instance().engine()->put(_model->meta_uri(), props); + App::instance().engine()->put(_model->path(), props, Resource::INTERNAL); } } diff --git a/src/gui/PatchView.cpp b/src/gui/PatchView.cpp index 21717f55..1313f65e 100644 --- a/src/gui/PatchView.cpp +++ b/src/gui/PatchView.cpp @@ -77,10 +77,6 @@ PatchView::set_patch(SharedPtr patch) _poly_spin->set_value(patch->internal_poly()); - for (GraphObject::Properties::const_iterator i = patch->meta().properties().begin(); - i != patch->meta().properties().end(); ++i) - property_changed(i->first, i->second); - for (GraphObject::Properties::const_iterator i = patch->properties().begin(); i != patch->properties().end(); ++i) property_changed(i->first, i->second); diff --git a/src/gui/PortPropertiesWindow.cpp b/src/gui/PortPropertiesWindow.cpp index 7ba5ba28..5cfe33ef 100644 --- a/src/gui/PortPropertiesWindow.cpp +++ b/src/gui/PortPropertiesWindow.cpp @@ -157,7 +157,7 @@ PortPropertiesWindow::ok() Shared::Resource::Properties props; props.insert(make_pair(uris.lv2_minimum, float(_min_spinner->get_value()))); props.insert(make_pair(uris.lv2_maximum, float(_max_spinner->get_value()))); - App::instance().engine()->put(_port_model->meta().uri(), props); + App::instance().engine()->put(_port_model->path(), props); hide(); } diff --git a/src/serialisation/Parser.cpp b/src/serialisation/Parser.cpp index 06922653..059a9bfd 100644 --- a/src/serialisation/Parser.cpp +++ b/src/serialisation/Parser.cpp @@ -86,17 +86,37 @@ relative_uri(Glib::ustring base, const Glib::ustring uri, bool leading_slash) return ret; } +static std::string +get_basename(const std::string& uri) +{ + std::string ret = Glib::path_get_basename(uri); + ret = ret.substr(0, ret.find_last_of('.')); + return ret; +} + +static bool +skip_property(const Sord::Node& predicate) +{ + return (predicate.to_string() == "http://drobilla.net/ns/ingen#node" + || predicate.to_string() == "http://drobilla.net/ns/ingen#connection" + || predicate.to_string() == "http://lv2plug.in/ns/lv2core#port"); +} + +Parser::Parser(Ingen::Shared::World& world) +{ +} + Parser::PatchRecords Parser::find_patches(Ingen::Shared::World* world, const Glib::ustring& manifest_uri) { + const Sord::URI ingen_Patch (*world->rdf_world(), NS_INGEN "Patch"); + const Sord::URI rdf_type (*world->rdf_world(), NS_RDF "type"); + const Sord::URI rdfs_seeAlso(*world->rdf_world(), NS_RDFS "seeAlso"); + Sord::Model model(*world->rdf_world(), manifest_uri); model.load_file(manifest_uri); - Sord::URI rdf_type(*world->rdf_world(), NS_RDF "type"); - Sord::URI rdfs_seeAlso(*world->rdf_world(), NS_RDFS "seeAlso"); - Sord::URI ingen_Patch(*world->rdf_world(), NS_INGEN "Patch"); - std::list records; for (Sord::Iter i = model.find(nil, rdf_type, ingen_Patch); !i.end(); ++i) { const Sord::Node patch = i.get_subject(); @@ -204,13 +224,14 @@ Parser::parse(Ingen::Shared::World* world, boost::optional symbol, boost::optional data) { - const Sord::URI rdf_type (*world->rdf_world(), NS_RDF "type"); - const Sord::URI patch_class (*world->rdf_world(), NS_INGEN "Patch"); - const Sord::URI node_class (*world->rdf_world(), NS_INGEN "URI"); - const Sord::URI internal_class (*world->rdf_world(), NS_INGEN "Internal"); - const Sord::URI in_port_class (*world->rdf_world(), NS_LV2 "InputPort"); - const Sord::URI out_port_class (*world->rdf_world(), NS_LV2 "OutputPort"); - const Sord::URI lv2_class (*world->rdf_world(), NS_LV2 "Plugin"); + const Sord::URI patch_class (*world->rdf_world(), NS_INGEN "Patch"); + const Sord::URI node_class (*world->rdf_world(), NS_INGEN "Node"); + const Sord::URI port_class (*world->rdf_world(), NS_INGEN "Port"); + const Sord::URI internal_class(*world->rdf_world(), NS_INGEN "Internal"); + const Sord::URI in_port_class (*world->rdf_world(), NS_LV2 "InputPort"); + const Sord::URI out_port_class(*world->rdf_world(), NS_LV2 "OutputPort"); + const Sord::URI lv2_class (*world->rdf_world(), NS_LV2 "Plugin"); + const Sord::URI rdf_type (*world->rdf_world(), NS_RDF "type"); Sord::Node subject = nil; if (data_path && data_path->is_root()) { @@ -228,23 +249,40 @@ Parser::parse(Ingen::Shared::World* world, path = parent->child(*symbol); } - boost::optional ret; - boost::optional root_path; + // Get all subjects and their types (?subject a ?type) + typedef std::map< Sord::Node, std::set > Subjects; + Subjects subjects; for (Sord::Iter i = model.find(subject, rdf_type, nil); !i.end(); ++i) { const Sord::Node& subject = i.get_subject(); const Sord::Node& rdf_class = i.get_object(); - if (rdf_class == patch_class) { + Subjects::iterator s = subjects.find(subject); + if (s == subjects.end()) { + std::set types; + types.insert(rdf_class); + subjects.insert(make_pair(subject, types)); + } else { + s->second.insert(rdf_class); + } + } + + // Parse and create each subject + boost::optional ret; + boost::optional root_path; + for (Subjects::const_iterator i = subjects.begin(); i != subjects.end(); ++i) { + const Sord::Node& subject = i->first; + const std::set& types = i->second; + if (types.find(patch_class) != types.end()) { ret = parse_patch(world, target, model, subject, parent, symbol, data); - } else if (rdf_class == node_class) { + } else if (types.find(node_class) != types.end()) { ret = parse_node(world, target, model, subject, path, data); - } else if (rdf_class == in_port_class || rdf_class == out_port_class) { + } else if (types.find(port_class) != types.end()) { parse_properties(world, target, model, subject, path, data); ret = path; } - + if (!ret) { - LOG(error) << "Failed to parse object " << path << endl; + LOG(error) << "Failed to parse " << path << endl; return boost::optional(); } @@ -256,6 +294,60 @@ Parser::parse(Ingen::Shared::World* world, return path; } +static Resource::Properties +get_properties(Sord::Model& model, + const Sord::Node& subject) +{ + Resource::Properties props; + for (Sord::Iter i = model.find(subject, nil, nil); !i.end(); ++i) { + const Sord::Node& predicate = i.get_predicate(); + const Sord::Node& object = i.get_object(); + if (!skip_property(predicate)) { + props.insert( + make_pair(predicate.to_string(), + AtomRDF::node_to_atom(model, object))); + } + } + return props; +} + +typedef std::pair PortRecord; + +static int +get_port(Ingen::Shared::World* world, + Sord::Model& model, + const Sord::Node& subject, + const Raul::Path& parent, + PortRecord& record) +{ + const LV2URIMap& uris = *world->uris().get(); + + // Get all properties + Resource::Properties props = get_properties(model, subject); + + // Get index + Resource::Properties::const_iterator i = props.find(uris.lv2_index); + if (i == props.end() + || i->second.type() != Atom::INT + || i->second.get_int32() < 0) { + LOG(error) << "Port " << subject << " has no valid lv2:index" << endl; + return -1; + } + const uint32_t index = i->second.get_int32(); + + // Get symbol + Resource::Properties::const_iterator s = props.find(uris.lv2_symbol); + if (s == props.end()) { + LOG(error) << "Port " << subject << " has no symbol" << endl; + return -1; + } + const Symbol port_sym = s->second.get_string(); + const Path port_path = parent.child(port_sym); + + record = make_pair(port_path, props); + return index; +} + boost::optional Parser::parse_patch(Ingen::Shared::World* world, Ingen::Shared::CommonInterface* target, @@ -265,24 +357,23 @@ Parser::parse_patch(Ingen::Shared::World* world, boost::optional a_symbol, boost::optional data) { - const LV2URIMap& uris = *world->uris().get(); - - Sord::URI ingen_polyphony(*world->rdf_world(), NS_INGEN "polyphony"); - Sord::URI lv2_port(*world->rdf_world(), NS_LV2 "port"); - Sord::URI lv2_symbol(*world->rdf_world(), NS_LV2 "symbol"); + const Sord::URI ingen_node(*world->rdf_world(), NS_INGEN "node"); + const Sord::URI ingen_polyphony(*world->rdf_world(), NS_INGEN "polyphony"); + const Sord::URI lv2_port(*world->rdf_world(), NS_LV2 "port"); + const LV2URIMap& uris = *world->uris().get(); const Sord::Node& patch = subject_node; uint32_t patch_poly = 0; - /* Use parameter overridden polyphony, if given */ + // Use parameter overridden polyphony, if given if (data) { GraphObject::Properties::iterator poly_param = data.get().find(uris.ingen_polyphony); if (poly_param != data.get().end() && poly_param->second.type() == Atom::INT) patch_poly = poly_param->second.get_int32(); } - /* Load polyphony from file if necessary */ + // Load polyphony from file if necessary if (patch_poly == 0) { Sord::Iter i = model.find(subject_node, ingen_polyphony, nil); if (!i.end()) { @@ -294,7 +385,7 @@ Parser::parse_patch(Ingen::Shared::World* world, } } - /* No polyphony found anywhere, use 1 */ + // No polyphony found anywhere, use 1 if (patch_poly == 0) patch_poly = 1; @@ -304,8 +395,7 @@ Parser::parse_patch(Ingen::Shared::World* world, if (a_symbol) { symbol = *a_symbol; } else { - const std::string basename = Glib::path_get_basename(base_uri); - symbol = Raul::Symbol::symbolify(basename.substr(0, basename.find('.'))); + const std::string basename = get_basename(base_uri); } string patch_path_str = relative_uri(base_uri, subject_node.to_string(), true); @@ -317,132 +407,63 @@ Parser::parse_patch(Ingen::Shared::World* world, return boost::optional(); } - /* Create patch */ + // Create patch Path patch_path(patch_path_str); - Resource::Properties props; - props.insert(make_pair(uris.rdf_type, Raul::URI(uris.ingen_Patch))); - props.insert(make_pair(uris.ingen_polyphony, Raul::Atom(int32_t(patch_poly)))); + Resource::Properties props = get_properties(model, subject_node); target->put(patch_path, props); - Sord::URI rdf_type(*world->rdf_world(), NS_RDF "type"); - Sord::URI ingen_Patch(*world->rdf_world(), NS_INGEN "Patch"); - Sord::URI ingen_node(*world->rdf_world(), NS_INGEN "node"); - - typedef multimap Properties; - typedef map Resources; - typedef map Objects; - typedef map Types; - - Objects patch_nodes; - Objects plugin_nodes; - Resources resources; - Types types; - - /* For each node in this patch */ - typedef map Nodes; - Nodes nodes; + // For each node in this patch for (Sord::Iter n = model.find(subject_node, ingen_node, nil); !n.end(); ++n) { - Sord::Node node = n.get_object(); - - /* Get all node properties */ - Properties node_properties; - for (Sord::Iter np = model.find(node, nil, nil); !np.end(); ++np) { - const Sord::Node& predicate = np.get_predicate(); - const Sord::Node& object = np.get_object(); - if (!skip_property(predicate)) { - node_properties.insert( - make_pair(predicate.to_string(), - AtomRDF::node_to_atom(model, object))); - } - } + Sord::Node node = n.get_object(); + const Path node_path = patch_path.child(get_basename(node.to_string())); - /* Create node */ - const Path node_path = patch_path.child( - relative_uri(base_uri, node.to_string(), false)); - target->put(node_path, node_properties); + // Parse and create node + parse_node(world, target, model, node, node_path, + boost::optional()); - /* For each port on this node */ + // For each port on this node for (Sord::Iter p = model.find(node, lv2_port, nil); !p.end(); ++p) { Sord::Node port = p.get_object(); - /* Get all port properties */ - Properties port_properties; - for (Sord::Iter pp = model.find(port, nil, nil); !pp.end(); ++pp) { - const Sord::Node& predicate = pp.get_predicate(); - const Sord::Node& object = pp.get_object(); - if (!skip_property(predicate)) { - port_properties.insert( - make_pair(predicate.to_string(), - AtomRDF::node_to_atom(model, object))); - } - } - - /* Set port properties */ - Properties::const_iterator s = port_properties.find(uris.lv2_symbol); - if (s == port_properties.end()) { - LOG(error) << "Port on " << node_path << " has no symbol" << endl; + // Get all properties + PortRecord port_record; + const int index = get_port(world, model, port, node_path, port_record); + if (index < 0) { + LOG(error) << "Invalid port " << port << endl; return boost::optional(); } - const Symbol port_sym = s->second.get_string(); - const Path port_path = node_path.child(port_sym); - target->put(port_path, port_properties); + // Create port and/or set all port properties + target->put(port_record.first, port_record.second); } } - /* For each port on this patch */ + // For each port on this patch + typedef std::map PortRecords; + PortRecords ports; for (Sord::Iter p = model.find(patch, lv2_port, nil); !p.end(); ++p) { Sord::Node port = p.get_object(); - /* Get all port properties */ - Properties port_properties; - for (Sord::Iter pp = model.find(port, nil, nil); !pp.end(); ++pp) { - const Sord::Node& predicate = pp.get_predicate(); - const Sord::Node& object = pp.get_object(); - if (!skip_property(predicate)) { - port_properties.insert( - make_pair(predicate.to_string(), - AtomRDF::node_to_atom(model, object))); - } - } - - /* Set port properties */ - Properties::const_iterator s = port_properties.find(uris.lv2_symbol); - if (s == port_properties.end()) { - LOG(error) << "Port on " << patch_path << " has no symbol" << endl; + // Get all properties + PortRecord port_record; + const int index = get_port(world, model, port, patch_path, port_record); + if (index < 0) { + LOG(error) << "Invalid port " << port << endl; return boost::optional(); } - const Symbol port_sym = s->second.get_string(); - const Path port_path = patch_path.child(port_sym); - target->put(port_path, port_properties); + // Store port information in ports map + ports[index] = port_record; } - parse_properties(world, target, model, subject_node, patch_path, data); + // Create ports in order by index + for (PortRecords::const_iterator i = ports.begin(); i != ports.end(); ++i) { + target->put(i->second.first, i->second.second); + } + + //parse_properties(world, target, model, subject_node, patch_path, data); parse_connections(world, target, model, subject_node, patch_path); - cerr << "FIXME: enable patch" << endl; - target->set_property(patch_path, uris.ingen_enabled, (bool)true); -#if 0 - /* Enable */ - query = Sord::Query(*world->rdf_world(), Glib::ustring( - "SELECT DISTINCT ?enabled WHERE {\n") - + subject + " ingen:enabled ?enabled .\n" - "}"); - - results = query.run(*world->rdf_world(), model, base_uri); - for (; !results->finished(); results->next()) { - Glib::Mutex::Lock lock(world->rdf_world()->mutex()); - const Sord::Node& enabled_node = results->get("enabled"); - if (enabled_node.is_bool() && enabled_node) { - target->set_property(patch_path, uris.ingen_enabled, (bool)true); - break; - } else { - LOG(warn) << "Unknown type for ingen:enabled" << endl; - } - } -#endif - return patch_path; } @@ -458,27 +479,52 @@ Parser::parse_node(Ingen::Shared::World* world, Sord::URI rdf_instanceOf(*world->rdf_world(), NS_RDF "instanceOf"); - /* Get plugin */ Sord::Iter i = model.find(subject, rdf_instanceOf, nil); - if (i.end()) { - LOG(error) << "Node missing mandatory rdf:instanceOf property" << endl; + if (i.end() || i.get_object().type() != Sord::Node::URI) { + LOG(error) << "Node missing mandatory rdf:instanceOf" << endl; return boost::optional(); } - const Sord::Node& plugin_node = i.get_object(); - if (plugin_node.type() != Sord::Node::URI) { - LOG(error) << "Node's rdf:instanceOf property is not a resource" << endl; - return boost::optional(); - } + const std::string type_uri = relative_uri( + model.base_uri().to_string(), + i.get_object().to_string(), + false); - Resource::Properties props; - props.insert(make_pair(uris.rdf_type, - Raul::URI(uris.ingen_Node))); - props.insert(make_pair(uris.rdf_instanceOf, - AtomRDF::node_to_atom(model, plugin_node))); - target->put(path, props); + if (!serd_uri_string_has_scheme((const uint8_t*)type_uri.c_str())) { + SerdURI base_uri; + serd_uri_parse(model.base_uri().to_u_string(), &base_uri); + + SerdURI ignored; + SerdNode sub_uri = serd_node_new_uri_from_string( + i.get_object().to_u_string(), + &base_uri, + &ignored); + + const std::string sub_uri_str((const char*)sub_uri.buf); + std::string basename = get_basename(sub_uri_str); + + const std::string sub_file = + string((const char*)sub_uri.buf) + "/" + basename + ".ttl"; + + Sord::Model sub_model(*world->rdf_world(), sub_file); + sub_model.load_file(sub_file); + + Sord::URI sub_node(*world->rdf_world(), sub_file); + parse_patch(world, target, sub_model, sub_node, + path.parent(), Raul::Symbol(path.symbol())); + + cout << "DONE PARSING SUB PATCH FILE" << endl; - parse_properties(world, target, model, subject, path, data); + parse_patch(world, target, model, subject, + path.parent(), Raul::Symbol(path.symbol())); + + cout << "} SUB PATCH" << endl; + } else { + Resource::Properties props = get_properties(model, subject); + props.insert(make_pair(uris.rdf_type, + Raul::URI(uris.ingen_Node))); + target->put(path, props); + } return path; } @@ -558,13 +604,6 @@ Parser::parse_properties(Ingen::Shared::World* world, return true; } -bool -Parser::skip_property(const Sord::Node& predicate) -{ - return (predicate.to_string() == "http://drobilla.net/ns/ingen#node" - || predicate.to_string() == "http://lv2plug.in/ns/lv2core#port"); -} - } // namespace Serialisation } // namespace Ingen diff --git a/src/serialisation/Parser.hpp b/src/serialisation/Parser.hpp index 5d4fc3fc..948a2e74 100644 --- a/src/serialisation/Parser.hpp +++ b/src/serialisation/Parser.hpp @@ -39,6 +39,8 @@ namespace Serialisation { class Parser { public: + Parser(Ingen::Shared::World& world); + virtual ~Parser() {} typedef Shared::GraphObject::Properties Properties; @@ -115,8 +117,6 @@ private: Sord::Model& model, const Sord::Node& subject, const Raul::Path& patch); - - bool skip_property(const Sord::Node& predicate); }; } // namespace Serialisation diff --git a/src/serialisation/Serialiser.cpp b/src/serialisation/Serialiser.cpp index 39723177..0629a97c 100644 --- a/src/serialisation/Serialiser.cpp +++ b/src/serialisation/Serialiser.cpp @@ -95,11 +95,10 @@ uri_to_symbol(const std::string& uri) } void -Serialiser::write_manifest(const std::string& bundle_uri, +Serialiser::write_manifest(const std::string& bundle_path, SharedPtr patch, const std::string& patch_symbol) { - const string bundle_path(Glib::filename_from_uri(bundle_uri)); const string manifest_path(Glib::build_filename(bundle_path, "manifest.ttl")); const string binary_path(Glib::Module::build_path("", "ingen_lv2")); @@ -129,24 +128,56 @@ Serialiser::write_manifest(const std::string& bundle_uri, finish(); } +std::string +normal_bundle_uri(const std::string& uri) +{ + std::string ret = uri; + size_t i; + while ((i = ret.find("/./")) != std::string::npos) { + ret = ret.substr(0, i) + ret.substr(i + 2); + } + const size_t last_slash = ret.find_last_of("/"); + if (last_slash != std::string::npos) { + return ret.substr(0, last_slash); + } else { + return ret + "/"; + } + return ret; +} + void Serialiser::write_bundle(SharedPtr patch, const std::string& uri) { - string bundle_uri = uri; - if (bundle_uri[bundle_uri.length()-1] != '/') - bundle_uri.append("/"); + Glib::ustring path = ""; + try { + path = Glib::filename_from_uri(uri); + } catch (...) { + LOG(error) << "Illegal file URI `" << uri << "'" << endl; + return; + } + + if (Glib::file_test(path, Glib::FILE_TEST_EXISTS) + && !Glib::file_test(path, Glib::FILE_TEST_IS_DIR)) { + path = Glib::path_get_dirname(path); + } - g_mkdir_with_parents(Glib::filename_from_uri(bundle_uri).c_str(), 0744); + if (path[path.length() - 1] != '/') + path.append("/"); + + g_mkdir_with_parents(path.c_str(), 0744); const string symbol = uri_to_symbol(uri); - const string root_file = bundle_uri + symbol + INGEN_PATCH_FILE_EXT; + const string root_file = path + symbol + INGEN_PATCH_FILE_EXT; start_to_filename(root_file); + const Path old_root_path = _root_path; + _root_path = patch->path(); serialise_patch(patch, Sord::URI(_model->world(), "")); + _root_path = old_root_path; finish(); - write_manifest(bundle_uri, patch, symbol); + write_manifest(path, patch, symbol); } string @@ -160,13 +191,9 @@ Serialiser::to_string(SharedPtr object, Sord::URI base_rdf_node(_model->world(), base_uri); for (GraphObject::Properties::const_iterator v = extra_rdf.begin(); v != extra_rdf.end(); ++v) { - if (v->first.find(":") != string::npos) { - _model->add_statement(base_rdf_node, - AtomRDF::atom_to_node(*_model, v->first), - AtomRDF::atom_to_node(*_model, v->second)); - } else { - LOG(warn) << "Not serialising extra RDF with key '" << v->first << "'" << endl; - } + _model->add_statement(base_rdf_node, + AtomRDF::atom_to_node(*_model, v->first), + AtomRDF::atom_to_node(*_model, v->second)); } return finish(); @@ -244,7 +271,8 @@ Serialiser::path_rdf_node(const Path& path) { assert(_model); assert(path.is_child_of(_root_path)); - return Sord::URI(_model->world(), path.chop_scheme().substr(1)); + const Path rel_path(path.relative_to_base(_root_path)); + return Sord::URI(_model->world(), rel_path.chop_scheme().substr(1)); } void @@ -269,7 +297,7 @@ Serialiser::serialise(SharedPtr object) throw (std::logic_error) SharedPtr port = PtrCast(object); if (port) { - serialise_port(port.get(), path_rdf_node(port->path())); + serialise_port(port.get(), Resource::DEFAULT, path_rdf_node(port->path())); return; } @@ -299,7 +327,8 @@ Serialiser::serialise_patch(SharedPtr patch, const Sord::Node& pa if (s == patch->properties().end() || !s->second.type() == Atom::STRING || !Symbol::is_valid(s->second.get_string())) { - symbol = Glib::path_get_basename(Glib::filename_from_uri(_model->base_uri().to_c_string())); + const string path = Glib::filename_from_uri(_model->base_uri().to_c_string()); + symbol = Glib::path_get_basename(path); symbol = Symbol::symbolify(symbol.substr(0, symbol.find('.'))); _model->add_statement( patch_id, @@ -310,12 +339,12 @@ Serialiser::serialise_patch(SharedPtr patch, const Sord::Node& pa } // If the patch has no doap:name (required by LV2), use the symbol - if (patch->meta().properties().find(uris.doap_name) == patch->meta().properties().end()) + if (patch->properties().find(uris.doap_name) == patch->properties().end()) _model->add_statement(patch_id, AtomRDF::atom_to_node(*_model, uris.doap_name), Sord::Literal(world, symbol)); - serialise_properties(patch_id, NULL, patch->meta().properties()); + serialise_properties(patch.get(), Resource::INTERNAL, patch_id); for (Store::const_iterator n = _store->children_begin(patch); n != _store->children_end(patch); ++n) { @@ -367,10 +396,6 @@ Serialiser::serialise_patch(SharedPtr patch, const Sord::Node& pa } } - assert(_model); - - bool root = (patch->path() == _root_path); - for (uint32_t i = 0; i < patch->num_ports(); ++i) { Port* p = patch->port(i); const Sord::Node port_id = path_rdf_node(p->path()); @@ -382,14 +407,12 @@ Serialiser::serialise_patch(SharedPtr patch, const Sord::Node& pa _model->add_statement(patch_id, Sord::URI(world, NS_LV2 "port"), port_id); - serialise_port_meta(p, port_id); - if (root) - serialise_properties(port_id, &p->meta(), p->properties()); + serialise_port(p, Resource::INTERNAL, port_id); } for (Shared::Patch::Connections::const_iterator c = patch->connections().begin(); c != patch->connections().end(); ++c) { - serialise_connection(patch, c->second); + serialise_connection(patch_id, c->second); } } @@ -408,96 +431,72 @@ Serialiser::serialise_node(SharedPtr node, Sord::Curie(_model->world(), "lv2:symbol"), Sord::Literal(_model->world(), node->path().symbol())); - serialise_properties(node_id, &node->meta(), node->properties()); + serialise_properties(node.get(), Resource::EXTERNAL, node_id); for (uint32_t i = 0; i < node->num_ports(); ++i) { Port* const p = node->port(i); const Sord::Node port_id = path_rdf_node(p->path()); - serialise_port(p, port_id); + serialise_port(p, Resource::EXTERNAL, port_id); _model->add_statement(node_id, Sord::Curie(_model->world(), "lv2:port"), port_id); } } -/** Serialise a port on a Node */ void -Serialiser::serialise_port(const Port* port, const Sord::Node& port_id) +Serialiser::serialise_port(const Port* port, + Shared::Resource::Graph context, + const Sord::Node& port_id) { Sord::World& world = _model->world(); - if (port->is_input()) + if (port->is_input()) { _model->add_statement(port_id, Sord::Curie(world, "rdf:type"), Sord::Curie(world, "lv2:InputPort")); - else + } else { _model->add_statement(port_id, Sord::Curie(world, "rdf:type"), Sord::Curie(world, "lv2:OutputPort")); + } for (Port::PortTypes::const_iterator i = port->types().begin(); - i != port->types().end(); ++i) + i != port->types().end(); ++i) { _model->add_statement(port_id, Sord::Curie(world, "rdf:type"), Sord::URI(world, i->uri().str())); + } _model->add_statement(port_id, Sord::Curie(world, "lv2:symbol"), Sord::Literal(world, port->path().symbol())); - serialise_properties(port_id, &port->meta(), port->properties()); -} + serialise_properties(port, context, port_id); -/** Serialise a port on a Patch */ -void -Serialiser::serialise_port_meta(const Port* port, const Sord::Node& port_id) -{ - Sord::World& world = _model->world(); - - if (port->is_input()) - _model->add_statement(port_id, - Sord::Curie(world, "rdf:type"), - Sord::Curie(world, "lv2:InputPort")); - else - _model->add_statement(port_id, - Sord::Curie(world, "rdf:type"), - Sord::Curie(world, "lv2:OutputPort")); - - for (Port::PortTypes::const_iterator i = port->types().begin(); - i != port->types().end(); ++i) - _model->add_statement(port_id, - Sord::Curie(world, "rdf:type"), - Sord::URI(world, i->uri().str())); - - _model->add_statement( - port_id, - Sord::Curie(world, "lv2:index"), - AtomRDF::atom_to_node(*_model, Atom((int)port->index()))); - - _model->add_statement( - port_id, - Sord::Curie(world, "lv2:symbol"), - Sord::Literal(world, port->path().symbol())); - - if (!port->get_property(NS_LV2 "default").is_valid()) { - if (port->is_input()) { - if (port->value().is_valid()) { - _model->add_statement( - port_id, - Sord::Curie(world, "lv2:default"), - AtomRDF::atom_to_node(*_model, port->value())); - } else if (port->is_a(PortType::CONTROL)) { - LOG(warn) << "Port " << port->path() << " has no lv2:default" << endl; + if (context == Resource::INTERNAL) { + _model->add_statement( + port_id, + Sord::Curie(world, "lv2:index"), + AtomRDF::atom_to_node(*_model, Atom((int)port->index()))); + + if (!port->get_property(NS_LV2 "default").is_valid()) { + if (port->is_input()) { + if (port->value().is_valid()) { + _model->add_statement( + port_id, + Sord::Curie(world, "lv2:default"), + AtomRDF::atom_to_node(*_model, port->value())); + } else if (port->is_a(PortType::CONTROL)) { + LOG(warn) << "Port " << port->path() << " has no lv2:default" << endl; + } } } } - - serialise_properties(port_id, NULL, port->meta().properties()); } void -Serialiser::serialise_connection(SharedPtr parent, - SharedPtr connection) throw (std::logic_error) +Serialiser::serialise_connection(const Sord::Node& parent, + SharedPtr connection) throw (std::logic_error) { Sord::World& world = _model->world(); @@ -515,38 +514,35 @@ Serialiser::serialise_connection(SharedPtr parent, Sord::Curie(world, "ingen:destination"), dst); - if (parent) { - const Sord::Node parent_id = path_rdf_node(parent->path()); - _model->add_statement(parent_id, - Sord::Curie(world, "ingen:connection"), - connection_id); - } else { - _model->add_statement(connection_id, - Sord::Curie(world, "rdf:type"), - Sord::Curie(world, "ingen:Connection")); - } + _model->add_statement(parent, + Sord::Curie(world, "ingen:connection"), + connection_id); +} + +static bool +skip_property(const Sord::Node& predicate) +{ + return (predicate.to_string() == "http://drobilla.net/ns/ingen#document"); } void -Serialiser::serialise_properties(Sord::Node subject, - const Shared::Resource* meta, - const GraphObject::Properties& properties) +Serialiser::serialise_properties(const Shared::GraphObject* o, + Shared::Resource::Graph context, + Sord::Node id) { - for (GraphObject::Properties::const_iterator v = properties.begin(); - v != properties.end(); ++v) { - if (v->second.is_valid()) { - if (!meta || !meta->has_property(v->first.str(), v->second)) { - const Sord::URI key(_model->world(), v->first.str()); - const Sord::Node value(AtomRDF::atom_to_node(*_model, v->second)); - if (value.is_valid()) { - _model->add_statement(subject, key, value); - } else { - LOG(warn) << "Can not serialise variable '" << v->first << "' :: " - << (int)v->second.type() << endl; - } + const GraphObject::Properties props = o->properties(context); + + typedef GraphObject::Properties::const_iterator iterator; + for (iterator v = props.begin(); v != props.end(); ++v) { + const Sord::URI key(_model->world(), v->first.str()); + const Sord::Node value(AtomRDF::atom_to_node(*_model, v->second)); + if (!skip_property(key)) { + if (value.is_valid()) { + _model->add_statement(id, key, value); + } else { + LOG(warn) << "Can not serialise variable '" << v->first << "' :: " + << (int)v->second.type() << endl; } - } else { - LOG(warn) << "Property '" << v->first << "' has no value" << endl; } } } diff --git a/src/serialisation/Serialiser.hpp b/src/serialisation/Serialiser.hpp index 55dbcea1..596cb1c5 100644 --- a/src/serialisation/Serialiser.hpp +++ b/src/serialisation/Serialiser.hpp @@ -69,8 +69,8 @@ public: void start_to_string(const Raul::Path& root, const std::string& base_uri); void serialise(SharedPtr object) throw (std::logic_error); - void serialise_connection(SharedPtr parent, - SharedPtr c) throw (std::logic_error); + void serialise_connection(const Sord::Node& parent, + SharedPtr c) throw (std::logic_error); std::string finish(); @@ -79,22 +79,24 @@ private: void start_to_filename(const std::string& filename); - void serialise_patch(SharedPtr p, const Sord::Node& id); + void serialise_patch(SharedPtr p, + const Sord::Node& id); + void serialise_node(SharedPtr n, - const Sord::Node& class_id, const Sord::Node& id); - void serialise_port(const Shared::Port* p, const Sord::Node& id); - void serialise_port_meta(const Shared::Port* p, const Sord::Node& id); + const Sord::Node& class_id, + const Sord::Node& id); - void serialise_meta_properties(Sord::Node subject, - const Properties& properties); + void serialise_port(const Shared::Port* p, + Shared::Resource::Graph context, + const Sord::Node& id); - void serialise_properties(Sord::Node subject, - const Shared::Resource* meta, - const Properties& properties); + void serialise_properties(const Shared::GraphObject* o, + Shared::Resource::Graph context, + Sord::Node id); Sord::Node path_rdf_node(const Raul::Path& path); - void write_manifest(const std::string& bundle_uri, + void write_manifest(const std::string& bundle_path, SharedPtr patch, const std::string& patch_symbol); diff --git a/src/serialisation/serialisation.cpp b/src/serialisation/serialisation.cpp index e6780ed6..c6141d7d 100644 --- a/src/serialisation/serialisation.cpp +++ b/src/serialisation/serialisation.cpp @@ -25,7 +25,7 @@ using namespace Ingen; struct IngenSerialisationModule : public Shared::Module { void load(Shared::World* world) { world->set_parser(SharedPtr( - new Serialisation::Parser())); + new Serialisation::Parser(*world))); world->set_serialiser(SharedPtr( new Serialisation::Serialiser(*world, world->store()))); } diff --git a/src/shared/Builder.cpp b/src/shared/Builder.cpp index ef8c23e1..98ce3879 100644 --- a/src/shared/Builder.cpp +++ b/src/shared/Builder.cpp @@ -97,7 +97,6 @@ void Builder::build_object(SharedPtr object) { typedef GraphObject::Properties::const_iterator iterator; - _interface.put(object->meta().uri(), object->meta().properties()); _interface.put(object->uri(), object->properties()); } diff --git a/src/shared/ClashAvoider.cpp b/src/shared/ClashAvoider.cpp index 36fc5e4e..36244303 100644 --- a/src/shared/ClashAvoider.cpp +++ b/src/shared/ClashAvoider.cpp @@ -145,7 +145,8 @@ ClashAvoider::exists(const Raul::Path& path) const void ClashAvoider::put(const Raul::URI& path, - const Shared::Resource::Properties& properties) + const Shared::Resource::Properties& properties, + Resource::Graph ctx) { _target.put(map_uri(path), properties); } diff --git a/src/shared/ClashAvoider.hpp b/src/shared/ClashAvoider.hpp index 745d3272..6c43bd72 100644 --- a/src/shared/ClashAvoider.hpp +++ b/src/shared/ClashAvoider.hpp @@ -49,7 +49,8 @@ public: // Object commands virtual void put(const Raul::URI& path, - const Resource::Properties& properties); + const Resource::Properties& properties, + Resource::Graph ctx=Resource::DEFAULT); virtual void delta(const Raul::URI& path, const Shared::Resource::Properties& remove, diff --git a/src/shared/ResourceImpl.cpp b/src/shared/ResourceImpl.cpp index dc9bfbae..8b8a56ec 100644 --- a/src/shared/ResourceImpl.cpp +++ b/src/shared/ResourceImpl.cpp @@ -27,20 +27,6 @@ namespace Ingen { namespace Shared { -bool -ResourceImpl::is_meta_uri(const Raul::URI& uri) -{ - return uri.substr(0, 6) == "meta:#"; -} - - -const Raul::URI -ResourceImpl::meta_uri(const Raul::URI& uri) -{ - return string("meta:#") + uri.chop_start("/"); -} - - void ResourceImpl::add_property(const Raul::URI& uri, const Raul::Atom& value) { @@ -154,8 +140,6 @@ ResourceImpl::type( } else if (atom == uris.atom_MessagePort) { data_type = PortType::MESSAGE; port = true; - } else { - warn << "[ResourceImpl] Unrecognized type " << atom << endl; } } @@ -225,5 +209,25 @@ ResourceImpl::dump(std::ostream& os) const } +Resource::Properties +ResourceImpl::properties(Resource::Graph ctx) const +{ + if (ctx == Resource::DEFAULT) { + return properties(); + } + + typedef Resource::Properties::const_iterator iterator; + + Properties props; + for (iterator i = _properties.begin(); i != _properties.end(); ++i) { + if (i->second.context() == Resource::DEFAULT + || i->second.context() == ctx) { + props.insert(make_pair(i->first, i->second)); + } + } + + return props; +} + } // namespace Shared } // namespace Ingen diff --git a/src/shared/ResourceImpl.hpp b/src/shared/ResourceImpl.hpp index 6bb88a76..6ce6cd26 100644 --- a/src/shared/ResourceImpl.hpp +++ b/src/shared/ResourceImpl.hpp @@ -43,6 +43,8 @@ public: const Properties& properties() const { return _properties; } Properties& properties() { return _properties; } + Properties properties(Resource::Graph ctx) const; + const Raul::Atom& get_property(const Raul::URI& uri) const; Raul::Atom& set_property(const Raul::URI& uri, const Raul::Atom& value); void remove_property(const Raul::URI& uri, const Raul::Atom& value); @@ -65,9 +67,6 @@ public: bool& node, bool& port, bool& is_output, PortType& data_type); - static bool is_meta_uri(const Raul::URI& uri); - static const Raul::URI meta_uri(const Raul::URI& uri); - protected: Raul::Atom& set_property(const Raul::URI& uri, const Raul::Atom& value) const; -- cgit v1.2.1