diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/client/ClientStore.cpp | 22 | ||||
-rw-r--r-- | src/engine/ClientBroadcaster.cpp | 8 | ||||
-rw-r--r-- | src/engine/ClientBroadcaster.hpp | 4 | ||||
-rw-r--r-- | src/engine/QueuedEngineInterface.cpp | 3 | ||||
-rw-r--r-- | src/engine/events/SetMetadataEvent.cpp | 165 | ||||
-rw-r--r-- | src/engine/events/SetMetadataEvent.hpp | 44 | ||||
-rw-r--r-- | src/serialisation/Parser.cpp | 70 | ||||
-rw-r--r-- | src/shared/ResourceImpl.cpp | 17 | ||||
-rw-r--r-- | src/shared/ResourceImpl.hpp | 3 |
9 files changed, 211 insertions, 125 deletions
diff --git a/src/client/ClientStore.cpp b/src/client/ClientStore.cpp index 7774e9c3..12bbdaf9 100644 --- a/src/client/ClientStore.cpp +++ b/src/client/ClientStore.cpp @@ -104,6 +104,14 @@ ClientStore::add_object(SharedPtr<ObjectModel> 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); + /*cout << "[Store] Added " << object->path() << " {" << endl; for (iterator i = begin(); i != end(); ++i) { cout << "\t" << i->first << endl; @@ -279,6 +287,12 @@ ClientStore::put(const URI& uri, const Resource::Properties& properties) cerr << "\t" << i->first << " = " << i->second << " :: " << i->second.type() << endl; cerr << "}" << endl; + SharedPtr<ObjectModel> obj = PtrCast<ObjectModel>(object(path)); + if (obj) { + cerr << "OBJECT EXISTS " << path << endl; + obj->set_properties(properties); + } + bool is_patch, is_node, is_port, is_output; DataType data_type(DataType::UNKNOWN); ResourceImpl::type(properties, is_patch, is_node, is_port, is_output, data_type); @@ -289,7 +303,7 @@ ClientStore::put(const URI& uri, const Resource::Properties& properties) if (p != properties.end() && p->second.is_valid() && p->second.type() == Atom::INT) poly = p->second.get_int32(); SharedPtr<PatchModel> model(new PatchModel(path, poly)); - model->merge_properties(properties); + model->set_properties(properties); add_object(model); } else if (is_node) { const Resource::Properties::const_iterator p = properties.find("rdf:instanceOf"); @@ -297,11 +311,11 @@ ClientStore::put(const URI& uri, const Resource::Properties& properties) if (p->second.is_valid() && p->second.type() == Atom::URI) { if ((plug = plugin(p->second.get_uri()))) { SharedPtr<NodeModel> n(new NodeModel(plug, path)); - n->merge_properties(properties); + n->set_properties(properties); add_object(n); } else { SharedPtr<NodeModel> n(new NodeModel(p->second.get_uri(), path)); - n->merge_properties(properties); + n->set_properties(properties); //add_plugin_orphan(n); add_object(n); } @@ -312,7 +326,7 @@ ClientStore::put(const URI& uri, const Resource::Properties& properties) if (data_type != DataType::UNKNOWN) { PortModel::Direction pdir = is_output ? PortModel::OUTPUT : PortModel::INPUT; SharedPtr<PortModel> p(new PortModel(path, 0, data_type, pdir)); - p->merge_properties(properties); + p->set_properties(properties); add_object(p); } else { cerr << "WARNING: Illegal port " << path << endl; diff --git a/src/engine/ClientBroadcaster.cpp b/src/engine/ClientBroadcaster.cpp index 8aaffe94..50a1112b 100644 --- a/src/engine/ClientBroadcaster.cpp +++ b/src/engine/ClientBroadcaster.cpp @@ -162,6 +162,14 @@ ClientBroadcaster::send_disconnection(const Path& src_port_path, const Path& dst } +void +ClientBroadcaster::send_put(const Raul::URI& subject, const Shared::Resource::Properties& properties) +{ + for (Clients::const_iterator i = _clients.begin(); i != _clients.end(); ++i) + (*i).second->put(subject, properties); +} + + /** Send notification of a property update. * * Like control changes, does not send update to client that set the property, if applicable. diff --git a/src/engine/ClientBroadcaster.hpp b/src/engine/ClientBroadcaster.hpp index 2aea8eb0..8d9d5c4d 100644 --- a/src/engine/ClientBroadcaster.hpp +++ b/src/engine/ClientBroadcaster.hpp @@ -69,8 +69,8 @@ public: void send_connection(const SharedPtr<const ConnectionImpl> connection); void send_disconnection(const Raul::Path& src_port_path, const Raul::Path& dst_port_path); void send_move(const Raul::Path& old_path, const Raul::Path& new_path); - void send_variable_change(const Raul::URI& node_path, const Raul::URI& key, const Raul::Atom& value); - void send_property_change(const Raul::URI& node_path, const Raul::URI& key, const Raul::Atom& value); + void send_put(const Raul::URI& subject, const Shared::Resource::Properties& properties); + void send_property_change(const Raul::URI& subject, const Raul::URI& key, const Raul::Atom& value); void send_port_value(const Raul::Path& port_path, const Raul::Atom& value); void send_activity(const Raul::Path& path); diff --git a/src/engine/QueuedEngineInterface.cpp b/src/engine/QueuedEngineInterface.cpp index 4b2926e7..7d9a8dcc 100644 --- a/src/engine/QueuedEngineInterface.cpp +++ b/src/engine/QueuedEngineInterface.cpp @@ -155,6 +155,7 @@ void QueuedEngineInterface::put(const URI& uri, const Resource::Properties& properties) { + cerr << "PUT " << uri << endl; size_t hash = uri.find("#"); bool meta = (hash != string::npos); Path path(meta ? (string("/") + uri.chop_start("#")) : uri.str()); @@ -169,6 +170,8 @@ QueuedEngineInterface::put(const URI& uri, DataType data_type(DataType::UNKNOWN); ResourceImpl::type(properties, is_patch, is_node, is_port, is_output, data_type); + // PutEvent + if (is_patch) { uint32_t poly = 1; iterator p = properties.find("ingen:polyphony"); diff --git a/src/engine/events/SetMetadataEvent.cpp b/src/engine/events/SetMetadataEvent.cpp index 00db9161..a88490d6 100644 --- a/src/engine/events/SetMetadataEvent.cpp +++ b/src/engine/events/SetMetadataEvent.cpp @@ -43,10 +43,7 @@ SetMetadataEvent::SetMetadataEvent( const Atom& value) : QueuedEvent(engine, responder, timestamp) , _error(NO_ERROR) - , _special_type(NONE) , _subject(subject) - , _key(key) - , _value(value) , _object(NULL) , _patch(NULL) , _compiled_patch(NULL) @@ -55,6 +52,27 @@ SetMetadataEvent::SetMetadataEvent( { cerr << "SET " << subject << " : " << key << " = " << value << endl; assert(value.type() != Atom::URI || strcmp(value.get_uri(), "lv2:ControlPort")); + _properties.insert(make_pair(key, value)); +} + + +SetMetadataEvent::SetMetadataEvent( + Engine& engine, + SharedPtr<Responder> responder, + SampleCount timestamp, + bool meta, + const URI& subject, + const Shared::Resource::Properties& properties) + : QueuedEvent(engine, responder, timestamp) + , _error(NO_ERROR) + , _subject(subject) + , _properties(properties) + , _object(NULL) + , _patch(NULL) + , _compiled_patch(NULL) + , _is_meta(meta) + , _success(false) +{ } @@ -75,43 +93,55 @@ SetMetadataEvent::pre_process() /*cerr << "SET " << _object->path() << (_property ? " PROP " : " VAR ") << _key << " :: " << _value.type() << endl;*/ - GraphObjectImpl* obj = dynamic_cast<GraphObjectImpl*>(_object); - if (obj) { - if (_is_meta) - obj->meta().set_property(_key, _value); - else - obj->set_property(_key, _value); - - _patch = dynamic_cast<PatchImpl*>(_object); - - if (_key.str() == "ingen:broadcast") { - _special_type = ENABLE_BROADCAST; - } else if (_patch) { - if (_key.str() == "ingen:enabled") { - if (_value.type() == Atom::BOOL) { - _special_type = ENABLE; - if (_value.get_bool() && !_patch->compiled_patch()) - _compiled_patch = _patch->compile(); + _types.reserve(_properties.size()); + typedef Shared::Resource::Properties Properties; + for (Properties::iterator p = _properties.begin(); p != _properties.end(); ++p) { + const Raul::URI& key = p->first; + const Raul::Atom& value = p->second; + GraphObjectImpl* obj = dynamic_cast<GraphObjectImpl*>(_object); + if (obj) { + if (_is_meta) + obj->meta().set_property(key, value); + else + obj->set_property(key, value); + + _patch = dynamic_cast<PatchImpl*>(_object); + + if (key.str() == "ingen:broadcast") { + _types.push_back(ENABLE_BROADCAST); + } else if (_patch) { + if (key.str() == "ingen:enabled") { + if (value.type() == Atom::BOOL) { + _types.push_back(ENABLE); + if (value.get_bool() && !_patch->compiled_patch()) + _compiled_patch = _patch->compile(); + } else { + _error = BAD_TYPE; + } + } else if (key.str() == "ingen:polyphonic") { + if (value.type() == Atom::BOOL) { + _types.push_back(POLYPHONIC); + } else { + _error = BAD_TYPE; + } + } else if (key.str() == "ingen:polyphony") { + if (value.type() == Atom::INT) { + _types.push_back(POLYPHONY); + _patch->prepare_internal_poly(value.get_int32()); + } else { + _error = BAD_TYPE; + } } else { - _error = BAD_TYPE; - } - } else if (_key.str() == "ingen:polyphonic") { - if (_value.type() == Atom::BOOL) { - _special_type = POLYPHONIC; - } else { - _error = BAD_TYPE; - } - } else if (_key.str() == "ingen:polyphony") { - if (_value.type() == Atom::INT) { - _special_type = POLYPHONY; - _patch->prepare_internal_poly(_value.get_int32()); - } else { - _error = BAD_TYPE; + _types.push_back(NONE); } + if (_error != NO_ERROR) + break; } + } else { + _types.push_back(NONE); } - } else { - _object->set_property(_key, _value); + + _object->set_property(key, value); } QueuedEvent::pre_process(); @@ -124,33 +154,38 @@ SetMetadataEvent::execute(ProcessContext& context) if (_error != NO_ERROR) return; - PortImpl* port = 0; - GraphObjectImpl* object = 0; - switch (_special_type) { - case ENABLE_BROADCAST: - if ((port = dynamic_cast<PortImpl*>(_object))) - port->broadcast(_value.get_bool()); - break; - case ENABLE: - if (_value.get_bool()) { - if (!_patch->compiled_patch()) - _patch->compiled_patch(_compiled_patch); - _patch->enable(); - } else { - _patch->disable(); + typedef Shared::Resource::Properties Properties; + std::vector<SpecialType>::const_iterator t = _types.begin(); + for (Properties::iterator p = _properties.begin(); p != _properties.end(); ++p, ++t) { + const Raul::Atom& value = p->second; + PortImpl* port = 0; + GraphObjectImpl* object = 0; + switch (*t) { + case ENABLE_BROADCAST: + if ((port = dynamic_cast<PortImpl*>(_object))) + port->broadcast(value.get_bool()); + break; + case ENABLE: + if (value.get_bool()) { + if (!_patch->compiled_patch()) + _patch->compiled_patch(_compiled_patch); + _patch->enable(); + } else { + _patch->disable(); + } + break; + case POLYPHONIC: + if ((object = dynamic_cast<GraphObjectImpl*>(_object))) + if (!object->set_polyphonic(*_engine.maid(), value.get_bool())) + _error = INTERNAL; + break; + case POLYPHONY: + if (!_patch->apply_internal_poly(*_engine.maid(), value.get_int32())) + _error = INTERNAL; + break; + default: + _success = true; } - break; - case POLYPHONIC: - if ((object = dynamic_cast<GraphObjectImpl*>(_object))) - if (!object->set_polyphonic(*_engine.maid(), _value.get_bool())) - _error = INTERNAL; - break; - case POLYPHONY: - if (!_patch->apply_internal_poly(*_engine.maid(), _value.get_int32())) - _error = INTERNAL; - break; - default: - _success = true; } QueuedEvent::execute(context); @@ -163,16 +198,16 @@ SetMetadataEvent::post_process() switch (_error) { case NO_ERROR: _responder->respond_ok(); - _engine.broadcaster()->send_property_change(_subject, _key, _value); + _engine.broadcaster()->send_put(_subject, _properties); break; case NOT_FOUND: _responder->respond_error((boost::format( - "Unable to find object '%1%' to set '%2%'") % _subject % _key).str()); + "Unable to find object '%1%'") % _subject).str()); case INTERNAL: _responder->respond_error("Internal error"); break; case BAD_TYPE: - _responder->respond_error((boost::format("Bad type for '%1%'") % _key).str()); + _responder->respond_error("Bad type for predicate"); break; } } diff --git a/src/engine/events/SetMetadataEvent.hpp b/src/engine/events/SetMetadataEvent.hpp index b33cc9ca..e43b1e9f 100644 --- a/src/engine/events/SetMetadataEvent.hpp +++ b/src/engine/events/SetMetadataEvent.hpp @@ -18,6 +18,7 @@ #ifndef SETMETADATAEVENT_H #define SETMETADATAEVENT_H +#include <vector> #include "raul/URI.hpp" #include "raul/Atom.hpp" #include "shared/ResourceImpl.hpp" @@ -37,13 +38,22 @@ class CompiledPatch; class SetMetadataEvent : public QueuedEvent { public: - SetMetadataEvent(Engine& engine, - SharedPtr<Responder> responder, - SampleCount timestamp, - bool meta, - const Raul::URI& subject, - const Raul::URI& key, - const Raul::Atom& value); + SetMetadataEvent( + Engine& engine, + SharedPtr<Responder> responder, + SampleCount timestamp, + bool meta, + const Raul::URI& subject, + const Raul::URI& key, + const Raul::Atom& value); + + SetMetadataEvent( + Engine& engine, + SharedPtr<Responder> responder, + SampleCount timestamp, + bool meta, + const Raul::URI& subject, + const Shared::Resource::Properties& properties); void pre_process(); void execute(ProcessContext& context); @@ -51,22 +61,22 @@ public: private: enum { NO_ERROR, NOT_FOUND, INTERNAL, BAD_TYPE } _error; - enum { + enum SpecialType { NONE, ENABLE, ENABLE_BROADCAST, POLYPHONY, POLYPHONIC - } _special_type; + }; - Raul::URI _subject; - Raul::URI _key; - Raul::Atom _value; - Shared::ResourceImpl* _object; - PatchImpl* _patch; - CompiledPatch* _compiled_patch; - bool _is_meta; - bool _success; + std::vector<SpecialType> _types; + Raul::URI _subject; + Shared::Resource::Properties _properties; + Shared::ResourceImpl* _object; + PatchImpl* _patch; + CompiledPatch* _compiled_patch; + bool _is_meta; + bool _success; }; diff --git a/src/serialisation/Parser.cpp b/src/serialisation/Parser.cpp index 781278a4..41b777a3 100644 --- a/src/serialisation/Parser.cpp +++ b/src/serialisation/Parser.cpp @@ -224,7 +224,7 @@ Parser::parse_update( for (Redland::Query::Results::iterator i = results.begin(); i != results.end(); ++i) { Glib::Mutex::Lock lock(world->rdf_world->mutex()); const string obj_uri((*i)["s"].to_string()); - const string key(world->rdf_world->prefixes().qualify((*i)["p"].to_string())); + const string key(world->rdf_world->qualify((*i)["p"].to_string())); const Redland::Node& val_node((*i)["o"]); const Atom a(AtomRDF::node_to_atom(val_node)); if (key != "") @@ -437,10 +437,10 @@ Parser::parse_patch( patches.insert((*i)["patch"].to_string()); } - typedef multimap<std::string, Redland::Node> Properties; - typedef map<string, Redland::Node> Resources; - typedef map<string, Properties> Objects; - typedef map<string, string> Types; + typedef multimap<Raul::URI, Raul::Atom> Properties; + typedef map<string, Redland::Node> Resources; + typedef map<string, Properties> Objects; + typedef map<string, string> Types; /* Find nodes on this patch */ @@ -486,10 +486,11 @@ Parser::parse_patch( Objects::iterator plug_i = plugin_nodes.find(node.to_string()); Types::iterator type_i = types.find(node.to_string()); if (node.type() == Redland::Node::RESOURCE && type_i != types.end()) { + const string key = world->rdf_world->qualify(predicate.to_string()); if (patch_i != patch_nodes.end()) { - patch_i->second.insert(make_pair(predicate.to_string(), object)); + patch_i->second.insert(make_pair(key, object)); } else if (plug_i != plugin_nodes.end()) { - plug_i->second.insert(make_pair(predicate.to_string(), object)); + plug_i->second.insert(make_pair(key, object)); } else { cerr << "WARNING: Unrecognized node: " << node.to_string() << endl; } @@ -507,10 +508,7 @@ Parser::parse_patch( continue; parse_patch(world, target, model, res_i->second, patch_path, Symbol(node_path.name())); Glib::Mutex::Lock lock(world->rdf_world->mutex()); - for (Properties::iterator j = i->second.begin(); j != i->second.end(); ++j) { - const string key = world->rdf_world->prefixes().qualify(j->first); - target->set_property(node_path, key, AtomRDF::node_to_atom(j->second)); - } + target->put(node_path, i->second); } /* Create plugin nodes */ @@ -522,12 +520,8 @@ Parser::parse_patch( Resource::Properties props; props.insert(make_pair("rdf:type", Raul::Atom(Raul::Atom::URI, "ingen:Node"))); props.insert(make_pair("rdf:instanceOf", Raul::Atom(Raul::Atom::URI, type_i->second))); + props.insert(i->second.begin(), i->second.end()); target->put(node_path, props); - Glib::Mutex::Lock lock(world->rdf_world->mutex()); - for (Properties::iterator j = i->second.begin(); j != i->second.end(); ++j) { - const string key = world->rdf_world->prefixes().qualify(j->first); - target->set_property(node_path, key, AtomRDF::node_to_atom(j->second)); - } } @@ -538,6 +532,7 @@ Parser::parse_patch( "?node lv2:port ?port .\n" "?port ?key ?val .\n" "}"); + Objects node_ports; results = query.run(*world->rdf_world, model, base_uri); for (Results::iterator i = results.begin(); i != results.end(); ++i) { Glib::Mutex::Lock lock(world->rdf_world->mutex()); @@ -548,15 +543,19 @@ Parser::parse_patch( continue; } + Objects::iterator p = node_ports.find(port_uri); + if (p == node_ports.end()) + p = node_ports.insert(make_pair(port_uri, Properties())).first; + const Path node_path(relative_uri(base_uri, node_uri, true)); const Symbol port_sym = port_uri.substr(node_uri.length() + 1); const Path port_path = node_path.base() + port_sym; - const string key = world->rdf_world->prefixes().qualify((*i)["key"].to_string()); - if (key == "ingen:value") { - target->set_port_value(port_path, AtomRDF::node_to_atom((*i)["val"])); - } else { - target->set_property(port_path, key, AtomRDF::node_to_atom((*i)["val"])); - } + const string key = world->rdf_world->qualify((*i)["key"].to_string()); + p->second.insert(make_pair(key, AtomRDF::node_to_atom((*i)["val"]))); + } + + for (Objects::iterator i = node_ports.begin(); i != node_ports.end(); ++i) { + target->put(Raul::Path(relative_uri(base_uri, i->first, true)), i->second); } @@ -574,7 +573,7 @@ Parser::parse_patch( Redland::Node& type = (*i)["type"]; if (port.type() == Redland::Node::RESOURCE && type.type() == Redland::Node::RESOURCE) { types.insert(make_pair(port.to_string(), - world->rdf_world->prefixes().qualify(type.to_string()))); + world->rdf_world->qualify(type.to_string()))); patch_ports.insert(make_pair(port.to_string(), Properties())); } } @@ -591,7 +590,7 @@ Parser::parse_patch( Glib::Mutex::Lock lock(world->rdf_world->mutex()); const string port_uri = (*i)["port"].to_string(); const Path port_path(Path(relative_uri(base_uri, port_uri, true))); - const string key = world->rdf_world->prefixes().qualify((*i)["key"].to_string()); + const string key = world->rdf_world->qualify((*i)["key"].to_string()); Objects::iterator ports_i = patch_ports.find(port_uri); if (ports_i == patch_ports.end()) ports_i = patch_ports.insert(make_pair(port_uri, Properties())).first; @@ -609,13 +608,15 @@ Parser::parse_patch( } bool is_input = false; bool is_output = false; - Redland::Node* type = 0; + Raul::Atom* type = 0; for (Properties::iterator t = types_range.first; t != types_range.second; ++t) { - if (t->second.to_string() == "lv2:InputPort") { + if (t->second.type() != Atom::URI) { + continue; + } else if (!strcmp(t->second.get_uri(), "lv2:InputPort")) { is_input = true; - } else if (t->second.to_string() == "lv2:OutputPort") { + } else if (!strcmp(t->second.get_uri(), "lv2:OutputPort")) { is_output = true; - } else if (!type || type->to_string() == t->second.to_string()) { + } else if (!type) { type = &t->second; } else { cerr << "ERROR: Port has several data types" << endl; @@ -790,20 +791,23 @@ Parser::parse_properties( subject + " ?key ?val .\n" "}"); + Resource::Properties properties; Redland::Query::Results results = query.run(*world->rdf_world, model); for (Redland::Query::Results::iterator i = results.begin(); i != results.end(); ++i) { Glib::Mutex::Lock lock(world->rdf_world->mutex()); - const string key = world->rdf_world->prefixes().qualify(string((*i)["key"])); + const string key = world->rdf_world->qualify(string((*i)["key"])); const Redland::Node& val = (*i)["val"]; if (key != "") - target->set_property(path, key, AtomRDF::node_to_atom(val)); + properties.insert(make_pair(key, AtomRDF::node_to_atom(val))); } + cout << "PROPERTIES: " << path << endl; + + target->put(path, properties); + // Set passed properties last to override any loaded values if (data) - for (GraphObject::Properties::const_iterator i = data.get().begin(); - i != data.get().end(); ++i) - target->set_property(path, i->first, i->second); + target->put(path, data.get()); return true; } diff --git a/src/shared/ResourceImpl.cpp b/src/shared/ResourceImpl.cpp index 9e403be3..ca3eaacd 100644 --- a/src/shared/ResourceImpl.cpp +++ b/src/shared/ResourceImpl.cpp @@ -50,8 +50,6 @@ ResourceImpl::add_property(const Raul::URI& uri, const Raul::Atom& value) void ResourceImpl::set_property(const Raul::URI& uri, const Raul::Atom& value) { - cerr << "SET PROPERTY " << uri << " = " << value << endl; - assert(value.type() != Raul::Atom::URI || strcmp(value.get_uri(), "lv2:ControlPort")); _properties.erase(uri); _properties.insert(make_pair(uri, value)); } @@ -126,10 +124,23 @@ ResourceImpl::type( void -ResourceImpl::merge_properties(const Properties& p) +ResourceImpl::set_properties(const Properties& p) { typedef Resource::Properties::const_iterator iterator; for (iterator i = p.begin(); i != p.end(); ++i) + _properties.erase(i->first); + for (iterator i = p.begin(); i != p.end(); ++i) + set_property(i->first, i->second); +} + + +void +ResourceImpl::add_properties(const Properties& p) +{ + typedef Resource::Properties::const_iterator iterator; + for (iterator i = p.begin(); i != p.end(); ++i) + _properties.erase(i->first); + for (iterator i = p.begin(); i != p.end(); ++i) add_property(i->first, i->second); } diff --git a/src/shared/ResourceImpl.hpp b/src/shared/ResourceImpl.hpp index 1f8dbedd..118d4dbe 100644 --- a/src/shared/ResourceImpl.hpp +++ b/src/shared/ResourceImpl.hpp @@ -40,7 +40,8 @@ public: const Raul::Atom& get_property(const Raul::URI& uri) const; void set_property(const Raul::URI& uri, const Raul::Atom& value); void add_property(const Raul::URI& uri, const Raul::Atom& value); - void merge_properties(const Properties& p); + void set_properties(const Properties& p); + void add_properties(const Properties& p); sigc::signal<void, const Raul::URI&, const Raul::Atom&> signal_property; |