From c11ecf0fd10641218326ae384e80413ba3cdf46c Mon Sep 17 00:00:00 2001 From: David Robillard Date: Wed, 27 May 2009 17:42:51 +0000 Subject: Remove 'new_patch', 'new_node', and 'new_port' from interface in favour of generic 'put'. git-svn-id: http://svn.drobilla.net/lad/trunk/ingen@2011 a436a847-0d15-0410-975c-d299462d15a1 --- src/bindings/Client.hpp | 11 +-- src/bindings/test_ingen.py | 7 +- src/client/ClientStore.cpp | 108 +++++++++++++----------------- src/client/ClientStore.hpp | 4 +- src/client/DeprecatedLoader.cpp | 65 ++++++++++++------ src/client/HTTPEngineSender.cpp | 32 +-------- src/client/HTTPEngineSender.hpp | 14 +--- src/client/OSCClientReceiver.cpp | 40 +---------- src/client/OSCClientReceiver.hpp | 2 +- src/client/OSCEngineSender.cpp | 66 +----------------- src/client/OSCEngineSender.hpp | 14 +--- src/client/ObjectModel.cpp | 2 +- src/client/ObjectModel.hpp | 6 +- src/client/PluginModel.cpp | 2 +- src/client/SigClientInterface.hpp | 18 +---- src/client/ThreadedSigClientInterface.cpp | 26 ------- src/client/ThreadedSigClientInterface.hpp | 18 ++--- src/common/interface/CommonInterface.hpp | 14 +--- src/common/interface/Resource.hpp | 8 +-- src/engine/Engine.cpp | 3 + src/engine/GraphObjectImpl.cpp | 9 ++- src/engine/HTTPClientSender.cpp | 24 ++----- src/engine/HTTPClientSender.hpp | 14 +--- src/engine/InputPort.cpp | 8 ++- src/engine/OSCClientSender.cpp | 81 +--------------------- src/engine/OSCClientSender.hpp | 14 +--- src/engine/OSCEngineReceiver.cpp | 55 +-------------- src/engine/OSCEngineReceiver.hpp | 2 +- src/engine/ObjectSender.cpp | 37 ++++------ src/engine/OutputPort.cpp | 8 ++- src/engine/PortImpl.cpp | 35 ++++++---- src/engine/QueuedEngineInterface.cpp | 57 ++++++++-------- src/engine/QueuedEngineInterface.hpp | 23 ++----- src/engine/events/CreateNodeEvent.cpp | 14 +++- src/engine/events/CreateNodeEvent.hpp | 17 +++-- src/engine/events/CreatePatchEvent.cpp | 12 +++- src/engine/events/CreatePatchEvent.hpp | 11 ++- src/engine/events/CreatePortEvent.cpp | 18 +++-- src/engine/events/CreatePortEvent.hpp | 15 ++++- src/gui/LoadPluginWindow.cpp | 15 +++-- src/gui/LoadSubpatchWindow.cpp | 4 +- src/gui/NewSubpatchWindow.cpp | 8 ++- src/gui/NodeModule.cpp | 13 ++-- src/gui/NodeModule.hpp | 2 +- src/gui/PatchCanvas.cpp | 58 ++++++---------- src/gui/PatchCanvas.hpp | 2 - src/gui/PatchPortModule.cpp | 34 ++++------ src/gui/PatchPortModule.hpp | 1 - src/gui/PatchView.cpp | 10 +-- src/gui/PatchView.hpp | 1 - src/gui/UploadPatchWindow.cpp | 4 +- src/serialisation/Parser.cpp | 40 +++++++---- src/serialisation/Serialiser.cpp | 11 ++- src/shared/Builder.cpp | 18 +++-- src/shared/ClashAvoider.cpp | 32 +-------- src/shared/ClashAvoider.hpp | 14 +--- src/shared/ResourceImpl.cpp | 90 ++++++++++++++++++++++++- src/shared/ResourceImpl.hpp | 15 ++++- 58 files changed, 521 insertions(+), 765 deletions(-) diff --git a/src/bindings/Client.hpp b/src/bindings/Client.hpp index 1a18ea73..5e9ed094 100644 --- a/src/bindings/Client.hpp +++ b/src/bindings/Client.hpp @@ -42,15 +42,8 @@ public: const std::string& type_uri, const std::string& symbol) {} - virtual void new_patch(const std::string& path, uint32_t poly) {} - - virtual void new_node(const std::string& path, - const std::string& plugin_uri) {} - - virtual void new_port(const std::string& path, - const std::string& type, - uint32_t index, - bool is_output) {} + void put(const Path& path, + const Resource::Properties& properties) {} virtual void clear_patch(const std::string& path) {} diff --git a/src/bindings/test_ingen.py b/src/bindings/test_ingen.py index 9b925155..c858e7df 100755 --- a/src/bindings/test_ingen.py +++ b/src/bindings/test_ingen.py @@ -15,11 +15,8 @@ class PythonClient(ingen.Client): def bundle_end(self): print "*** }" - def new_port(self, path, data_type, is_output): - print "*** Received Port:", path, data_type, is_output - - def new_node(self, plugin_uri, path, polyphonic, nports): - print "*** Received Node:", plugin_uri, path, polyphonic, nports + def put(self, path, properties): + print "*** Received Object:", path c = PythonClient() c.enable() diff --git a/src/client/ClientStore.cpp b/src/client/ClientStore.cpp index 64b6ae09..c28bdca0 100644 --- a/src/client/ClientStore.cpp +++ b/src/client/ClientStore.cpp @@ -45,11 +45,8 @@ ClientStore::ClientStore(SharedPtr engine, SharedPtrsignal_object_destroyed.connect(sigc::mem_fun(this, &ClientStore::destroy)); emitter->signal_object_renamed.connect(sigc::mem_fun(this, &ClientStore::rename)); - emitter->signal_new_object.connect(sigc::mem_fun(this, &ClientStore::new_object)); emitter->signal_new_plugin.connect(sigc::mem_fun(this, &ClientStore::new_plugin)); - emitter->signal_new_patch.connect(sigc::mem_fun(this, &ClientStore::new_patch)); - emitter->signal_new_node.connect(sigc::mem_fun(this, &ClientStore::new_node)); - emitter->signal_new_port.connect(sigc::mem_fun(this, &ClientStore::new_port)); + emitter->signal_put.connect(sigc::mem_fun(this, &ClientStore::put)); emitter->signal_clear_patch.connect(sigc::mem_fun(this, &ClientStore::clear_patch)); emitter->signal_connection.connect(sigc::mem_fun(this, &ClientStore::connect)); emitter->signal_disconnection.connect(sigc::mem_fun(this, &ClientStore::disconnect)); @@ -78,7 +75,6 @@ ClientStore::add_object(SharedPtr object) if (existing != end()) { PtrCast(existing->second)->set(object); } else { - if (!object->path().is_root()) { SharedPtr parent = this->object(object->path().parent()); if (parent) { @@ -271,68 +267,60 @@ ClientStore::new_plugin(const URI& uri, const URI& type_uri, const Symbol& symbo } -bool -ClientStore::new_object(const Shared::GraphObject* object) -{ - using namespace Shared; - - const Patch* patch = dynamic_cast(object); - if (patch) { - new_patch(patch->path(), patch->internal_polyphony()); - return true; - } - - const Node* node = dynamic_cast(object); - if (node) { - new_node(node->path(), node->plugin()->uri()); - return true; - } - - const Port* port = dynamic_cast(object); - if (port) { - new_port(port->path(), port->type().uri(), port->index(), !port->is_input()); - return true; - } - - return false; -} - - void -ClientStore::new_patch(const Path& path, uint32_t poly) +ClientStore::put(const Path& path, const Resource::Properties& properties) { - SharedPtr p(new PatchModel(path, poly)); - add_object(p); -} - - -void -ClientStore::new_node(const Path& path, const URI& plugin_uri) -{ - SharedPtr plug = plugin(plugin_uri); - if (!plug) { - SharedPtr n(new NodeModel(plugin_uri, path)); - //add_plugin_orphan(n); - add_object(n); + typedef Resource::Properties::const_iterator iterator; + cerr << "CLIENT PUT " << path << " {" << endl; + for (iterator i = properties.begin(); i != properties.end(); ++i) + cerr << "\t" << i->first << " = " << i->second << " :: " << i->second.type() << endl; + cerr << "}" << endl; + + 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); + + if (is_patch) { + uint32_t poly = 1; + iterator p = properties.find("ingen:polyphony"); + if (p != properties.end() && p->second.is_valid() && p->second.type() == Atom::INT) + poly = p->second.get_int32(); + SharedPtr model(new PatchModel(path, poly)); + model->merge_properties(properties); + add_object(model); + } else if (is_node) { + const Resource::Properties::const_iterator p = properties.find("rdf:instanceOf"); + SharedPtr plug; + if (p->second.is_valid() && p->second.type() == Atom::URI) { + if ((plug = plugin(p->second.get_uri()))) { + SharedPtr n(new NodeModel(plug, path)); + n->merge_properties(properties); + add_object(n); + } else { + SharedPtr n(new NodeModel(p->second.get_uri(), path)); + n->merge_properties(properties); + //add_plugin_orphan(n); + add_object(n); + } + } else { + cerr << "ERROR: Plugin with no type" << endl; + } + } else if (is_port) { + if (data_type != DataType::UNKNOWN) { + PortModel::Direction pdir = is_output ? PortModel::OUTPUT : PortModel::INPUT; + SharedPtr p(new PortModel(path, 0, data_type, pdir)); + p->merge_properties(properties); + add_object(p); + } else { + cerr << "WARNING: Illegal port " << path << endl; + } } else { - SharedPtr n(new NodeModel(plug, path)); - add_object(n); + cerr << "WARNING: Ignoring object " << path << " with unknown type " + << is_patch << " " << is_node << " " << is_port << endl; } } -void -ClientStore::new_port(const Path& path, const URI& type, uint32_t index, bool is_output) -{ - PortModel::Direction pdir = is_output ? PortModel::OUTPUT : PortModel::INPUT; - - SharedPtr p(new PortModel(path, index, type, pdir)); - add_object(p); - /*if (p->parent()) - resolve_connection_orphans(p);*/ -} - - void ClientStore::clear_patch(const Path& path) { diff --git a/src/client/ClientStore.hpp b/src/client/ClientStore.hpp index 63949d1d..68b87889 100644 --- a/src/client/ClientStore.hpp +++ b/src/client/ClientStore.hpp @@ -69,9 +69,7 @@ public: // CommonInterface void new_plugin(const Raul::URI& uri, const Raul::URI& type_uri, const Raul::Symbol& symbol); bool new_object(const Shared::GraphObject* object); - void new_patch(const Raul::Path& path, uint32_t poly); - void new_node(const Raul::Path& path, const Raul::URI& plugin_uri); - void new_port(const Raul::Path& path, const Raul::URI& type, uint32_t index, bool is_output); + void put(const Raul::Path& path, const Shared::Resource::Properties& properties); void rename(const Raul::Path& old_path, const Raul::Path& new_path); void set_variable(const Raul::URI& subject_path, const Raul::URI& predicate, const Raul::Atom& value); void set_property(const Raul::URI& subject_path, const Raul::URI& predicate, const Raul::Atom& value); diff --git a/src/client/DeprecatedLoader.cpp b/src/client/DeprecatedLoader.cpp index 261b1e35..f593c3be 100644 --- a/src/client/DeprecatedLoader.cpp +++ b/src/client/DeprecatedLoader.cpp @@ -50,20 +50,20 @@ namespace Client { class ControlModel { public: - ControlModel(const Raul::Path& port_path, float value) + ControlModel(const Path& port_path, float value) : _port_path(port_path) , _value(value) { assert(_port_path.find("//") == string::npos); } - const Raul::Path& port_path() const { return _port_path; } + const Path& port_path() const { return _port_path; } void port_path(const string& p) { _port_path = p; } float value() const { return _value; } void value(float v) { _value = v; } private: - Raul::Path _port_path; + Path _port_path; float _value; }; @@ -171,9 +171,9 @@ DeprecatedLoader::add_variable(GraphObject::Properties& data, string old_key, st free(locale); if (endptr != c_val && *endptr == '\0') - data[key] = Atom(fval); + data.insert(make_pair(key, Atom(fval))); else - data[key] = Atom(Atom::STRING, value); + data.insert(make_pair(key, Atom(Atom::STRING, value))); free(c_val); } @@ -229,7 +229,7 @@ DeprecatedLoader::load_patch(const Glib::ustring& filename, poly = poly_param->second.get_int32(); if (initial_data.find("filename") == initial_data.end()) - initial_data["filename"] = Atom(filename.c_str()); // FIXME: URL? + initial_data.insert(make_pair("filename", Atom(filename.c_str()))); // FIXME: URL? xmlDocPtr doc = xmlParseFile(filename.c_str()); @@ -292,7 +292,10 @@ DeprecatedLoader::load_patch(const Glib::ustring& filename, // Create it, if we're not merging if (!existing && !path.is_root()) { - _engine->new_patch(path, poly); + Resource::Properties props; + props.insert(make_pair("rdf:type", Atom(Atom::URI, "ingen:Patch"))); + props.insert(make_pair("ingen:polyphony", Atom((int32_t)poly))); + _engine->put(path, props); for (GraphObject::Properties::const_iterator i = initial_data.begin(); i != initial_data.end(); ++i) _engine->set_variable(path, i->first, i->second); } @@ -450,27 +453,37 @@ DeprecatedLoader::load_node(const Path& parent, xmlDocPtr doc, const xmlNodePtr if (plugin_uri == "") { bool is_port = false; + Resource::Properties props; + props.insert(make_pair("rdf:type", Atom(Atom::URI, "ingen:Patch"))); + if (plugin_type == "Internal") { - // FIXME: indices + is_port = true; if (plugin_label == "audio_input") { - _engine->new_port(path, "lv2:AudioPort", 0, false); - is_port = true; + props.insert(make_pair("rdf:type", Atom(Atom::URI, "lv2:AudioPort"))); + props.insert(make_pair("rdf:type", Atom(Atom::URI, "lv2:InputPort"))); + _engine->put(path, props); } else if (plugin_label == "audio_output") { - _engine->new_port(path, "lv2:AudioPort", 0, true); - is_port = true; + props.insert(make_pair("rdf:type", Atom(Atom::URI, "lv2:AudioPort"))); + props.insert(make_pair("rdf:type", Atom(Atom::URI, "lv2:OutputPort"))); + _engine->put(path, props); } else if (plugin_label == "control_input") { - _engine->new_port(path, "lv2:ControlPort", 0, false); - is_port = true; + props.insert(make_pair("rdf:type", Atom(Atom::URI, "lv2:ControlPort"))); + props.insert(make_pair("rdf:type", Atom(Atom::URI, "lv2:InputPort"))); + _engine->put(path, props); } else if (plugin_label == "control_output" ) { - _engine->new_port(path, "lv2:ControlPort", 0, true); - is_port = true; + props.insert(make_pair("rdf:type", Atom(Atom::URI, "lv2:ControlPort"))); + props.insert(make_pair("rdf:type", Atom(Atom::URI, "lv2:OutputPort"))); + _engine->put(path, props); } else if (plugin_label == "midi_input") { - _engine->new_port(path, "lv2ev:EventPort", 0, false); - is_port = true; + props.insert(make_pair("rdf:type", Atom(Atom::URI, "lv2ev:EventPort"))); + props.insert(make_pair("rdf:type", Atom(Atom::URI, "lv2:InputPort"))); + _engine->put(path, props); } else if (plugin_label == "midi_output" ) { - _engine->new_port(path, "lv2ev:EventPort", 0, true); - is_port = true; + props.insert(make_pair("rdf:type", Atom(Atom::URI, "lv2ev:EventPort"))); + props.insert(make_pair("rdf:type", Atom(Atom::URI, "lv2:OutputPort"))); + _engine->put(path, props); } else { + is_port = false; cerr << "WARNING: Unknown internal plugin label \"" << plugin_label << "\"" << endl; } } @@ -491,6 +504,8 @@ DeprecatedLoader::load_node(const Path& parent, xmlDocPtr doc, const xmlNodePtr path = new_path; + _engine->put(path, props); + for (GraphObject::Properties::const_iterator i = initial_data.begin(); i != initial_data.end(); ++i) _engine->set_variable(path, i->first, i->second); @@ -510,7 +525,10 @@ DeprecatedLoader::load_node(const Path& parent, xmlDocPtr doc, const xmlNodePtr if (plugin_uri == "") plugin_uri = "om:" + plugin_type + ":" + library_name + ":" + plugin_label; - _engine->new_node(path, plugin_uri); + Resource::Properties props; + props.insert(make_pair("rdf:type", Atom(Atom::URI, "ingen:Node"))); + props.insert(make_pair("rdf:instanceOf", Atom(Atom::URI, plugin_uri))); + _engine->put(path, props); _engine->set_variable(path, "ingen:polyphonic", bool(polyphonic)); @@ -522,7 +540,10 @@ DeprecatedLoader::load_node(const Path& parent, xmlDocPtr doc, const xmlNodePtr // Not deprecated } else { - _engine->new_node(path, plugin_uri); + Resource::Properties props; + props.insert(make_pair("rdf:type", Atom(Atom::URI, "ingen:Node"))); + props.insert(make_pair("rdf:instanceOf", Atom(Atom::URI, plugin_uri))); + _engine->put(path, props); _engine->set_variable(path, "ingen:polyphonic", bool(polyphonic)); for (GraphObject::Properties::const_iterator i = initial_data.begin(); i != initial_data.end(); ++i) _engine->set_variable(path, i->first, i->second); diff --git a/src/client/HTTPEngineSender.cpp b/src/client/HTTPEngineSender.cpp index 443dcfb6..596793f9 100644 --- a/src/client/HTTPEngineSender.cpp +++ b/src/client/HTTPEngineSender.cpp @@ -102,39 +102,11 @@ HTTPEngineSender::quit() // Object commands -bool -HTTPEngineSender::new_object(const Shared::GraphObject* object) -{ - return false; -} - - -void -HTTPEngineSender::new_patch(const Path& path, - uint32_t poly) -{ -} - - -void -HTTPEngineSender::new_port(const Path& path, - const URI& type, - uint32_t index, - bool is_output) -{ - const string uri = _engine_url.str() + "/patch" + path.str(); - cout << "HTTP " << uri << " NEW PORT: " << path << endl; - SoupMessage* msg = soup_message_new("PUT", uri.c_str()); - string str = string("NEW PORT").append(path.str()).append(type.str()); - soup_message_set_request(msg, "application/x-turtle", - SOUP_MEMORY_COPY, str.c_str(), str.length()); - soup_session_send_message(_session, msg); -} void -HTTPEngineSender::new_node(const Path& path, - const URI& plugin_uri) +HTTPEngineSender::put(const Raul::Path& path, + const Shared::Resource::Properties& properties) { } diff --git a/src/client/HTTPEngineSender.hpp b/src/client/HTTPEngineSender.hpp index f30b9e37..41107cb0 100644 --- a/src/client/HTTPEngineSender.hpp +++ b/src/client/HTTPEngineSender.hpp @@ -74,18 +74,8 @@ public: // Object commands - virtual bool new_object(const Shared::GraphObject* object); - - virtual void new_patch(const Raul::Path& path, - uint32_t poly); - - virtual void new_node(const Raul::Path& path, - const Raul::URI& plugin_uri); - - virtual void new_port(const Raul::Path& path, - const Raul::URI& type, - uint32_t index, - bool is_output); + virtual void put(const Raul::Path& path, + const Shared::Resource::Properties& properties); virtual void clear_patch(const Raul::Path& path); diff --git a/src/client/OSCClientReceiver.cpp b/src/client/OSCClientReceiver.cpp index dac558f5..e8b8c33b 100644 --- a/src/client/OSCClientReceiver.cpp +++ b/src/client/OSCClientReceiver.cpp @@ -149,8 +149,8 @@ OSCClientReceiver::setup_callbacks() lo_server_thread_add_method(_st, "/ingen/rename", "ss", rename_cb, this); lo_server_thread_add_method(_st, "/ingen/new_connection", "ss", connection_cb, this); lo_server_thread_add_method(_st, "/ingen/disconnection", "ss", disconnection_cb, this); - lo_server_thread_add_method(_st, "/ingen/new_node", "ss", new_node_cb, this); lo_server_thread_add_method(_st, "/ingen/new_port", "sisi", new_port_cb, this); + lo_server_thread_add_method(_st, "/ingen/put", NULL, new_port_cb, this); lo_server_thread_add_method(_st, "/ingen/set_variable", NULL, set_variable_cb, this); lo_server_thread_add_method(_st, "/ingen/set_property", NULL, set_property_cb, this); lo_server_thread_add_method(_st, "/ingen/set_port_value", "sf", set_port_value_cb, this); @@ -169,14 +169,6 @@ OSCClientReceiver::_error_cb(const char* path, const char* types, lo_arg** argv, } -int -OSCClientReceiver::_new_patch_cb(const char* path, const char* types, lo_arg** argv, int argc, lo_message msg) -{ - _target->new_patch(&argv[0]->s, argv[1]->i); // path, poly - return 0; -} - - int OSCClientReceiver::_destroyed_cb(const char* path, const char* types, lo_arg** argv, int argc, lo_message msg) { @@ -225,36 +217,6 @@ OSCClientReceiver::_disconnection_cb(const char* path, const char* types, lo_arg } -/** Notification of a new node creation. - */ -int -OSCClientReceiver::_new_node_cb(const char* path, const char* types, lo_arg** argv, int argc, lo_message msg) -{ - const char* uri = &argv[0]->s; - const char* node_path = &argv[1]->s; - - _target->new_node(uri, node_path); - - return 0; -} - - -/** Notification of a new port creation. - */ -int -OSCClientReceiver::_new_port_cb(const char* path, const char* types, lo_arg** argv, int argc, lo_message msg) -{ - const char* port_path = &argv[0]->s; - const uint32_t index = argv[1]->i; - const char* type = &argv[2]->s; - const bool is_output = (argv[3]->i == 1); - - _target->new_port(port_path, type, index, is_output); - - return 0; -} - - /** Notification of a new or updated variable. */ int diff --git a/src/client/OSCClientReceiver.hpp b/src/client/OSCClientReceiver.hpp index 7608fff3..58f66836 100644 --- a/src/client/OSCClientReceiver.hpp +++ b/src/client/OSCClientReceiver.hpp @@ -89,8 +89,8 @@ private: LO_HANDLER(rename); LO_HANDLER(connection); LO_HANDLER(disconnection); - LO_HANDLER(new_node); LO_HANDLER(new_port); + LO_HANDLER(put); LO_HANDLER(set_variable); LO_HANDLER(set_property); LO_HANDLER(set_port_value); diff --git a/src/client/OSCEngineSender.cpp b/src/client/OSCEngineSender.cpp index 86e9e8a8..23a98934 100644 --- a/src/client/OSCEngineSender.cpp +++ b/src/client/OSCEngineSender.cpp @@ -132,71 +132,11 @@ OSCEngineSender::quit() // Object commands -bool -OSCEngineSender::new_object(const Shared::GraphObject* object) -{ - using namespace Shared; - - const Patch* patch = dynamic_cast(object); - if (patch) { - new_patch(patch->path(), patch->internal_polyphony()); - return true; - } - - const Node* node = dynamic_cast(object); - if (node) { - new_node(node->path(), node->plugin()->uri()); - return true; - } - - const Port* port = dynamic_cast(object); - if (port) { - new_port(port->path(), port->type().uri(), port->index(), !port->is_input()); - return true; - } - - return false; -} - - void -OSCEngineSender::new_patch(const Path& path, - uint32_t poly) +OSCEngineSender::put(const Raul::Path& path, + const Shared::Resource::Properties& properties) { - send("/ingen/new_patch", "isi", - next_id(), - path.c_str(), - poly, - LO_ARGS_END); -} - - -void -OSCEngineSender::new_port(const Path& path, - const URI& type, - uint32_t index, - bool is_output) -{ - // FIXME: use index - send("/ingen/new_port", "issi", - next_id(), - path.c_str(), - type.c_str(), - (is_output ? 1 : 0), - LO_ARGS_END); -} - - -void -OSCEngineSender::new_node(const Path& path, - const URI& plugin_uri) -{ - - send("/ingen/new_node", "iss", - next_id(), - path.c_str(), - plugin_uri.c_str(), - LO_ARGS_END); + cerr << "OSC ENGINE PUT " << path << endl; } diff --git a/src/client/OSCEngineSender.hpp b/src/client/OSCEngineSender.hpp index 8383dd53..2b02ca6e 100644 --- a/src/client/OSCEngineSender.hpp +++ b/src/client/OSCEngineSender.hpp @@ -77,18 +77,8 @@ public: // Object commands - virtual bool new_object(const Shared::GraphObject* object); - - virtual void new_patch(const Raul::Path& path, - uint32_t poly); - - virtual void new_node(const Raul::Path& path, - const Raul::URI& plugin_uri); - - virtual void new_port(const Raul::Path& path, - const Raul::URI& type, - uint32_t index, - bool is_output); + virtual void put(const Raul::Path& path, + const Shared::Resource::Properties& properties); virtual void clear_patch(const Raul::Path& path); diff --git a/src/client/ObjectModel.cpp b/src/client/ObjectModel.cpp index ef4884e1..2d3251c6 100644 --- a/src/client/ObjectModel.cpp +++ b/src/client/ObjectModel.cpp @@ -105,7 +105,7 @@ ObjectModel::set(SharedPtr o) Properties::const_iterator mine = _variables.find(v->first); if (mine != _variables.end()) cerr << "WARNING: " << _path << "Client/Server variable mismatch: " << v->first << endl; - _variables[v->first] = v->second; + _variables.insert(make_pair(v->first, v->second)); signal_variable.emit(v->first, v->second); } } diff --git a/src/client/ObjectModel.hpp b/src/client/ObjectModel.hpp index e30ef2b2..8c7c631d 100644 --- a/src/client/ObjectModel.hpp +++ b/src/client/ObjectModel.hpp @@ -62,8 +62,10 @@ public: signal_property.emit(key, value); } - virtual void set_variable(const Raul::URI& key, const Raul::Atom& value) - { _variables[key] = value; signal_variable.emit(key, value); } + virtual void set_variable(const Raul::URI& key, const Raul::Atom& value) { + _variables.insert(make_pair(key, value)); + signal_variable.emit(key, value); + } const Properties& variables() const { return _variables; } Properties& variables() { return _variables; } diff --git a/src/client/PluginModel.cpp b/src/client/PluginModel.cpp index 9a470346..4db79091 100644 --- a/src/client/PluginModel.cpp +++ b/src/client/PluginModel.cpp @@ -43,7 +43,7 @@ PluginModel::PluginModel(const URI& uri, const URI& type_uri) { Glib::Mutex::Lock lock(_rdf_world->mutex()); assert(_rdf_world); - set_property("rdf:type", Raul::Atom(Raul::Atom::URI, this->type_uri())); + add_property("rdf:type", Raul::Atom(Raul::Atom::URI, this->type_uri())); #ifdef HAVE_SLV2 SLV2Value plugin_uri = slv2_value_new_uri(_slv2_world, uri.c_str()); _slv2_plugin = slv2_plugins_get_by_uri(_slv2_plugins, plugin_uri); diff --git a/src/client/SigClientInterface.hpp b/src/client/SigClientInterface.hpp index 128fddf0..7c3bee05 100644 --- a/src/client/SigClientInterface.hpp +++ b/src/client/SigClientInterface.hpp @@ -45,9 +45,6 @@ public: Raul::URI uri() const { return "ingen:internal"; } - // Signal parameters match up directly with ClientInterface calls - sigc::signal signal_new_object; - sigc::signal signal_response_ok; sigc::signal signal_response_error; sigc::signal signal_bundle_begin; @@ -55,8 +52,8 @@ public: sigc::signal signal_error; sigc::signal signal_new_plugin; sigc::signal signal_new_patch; - sigc::signal signal_new_node; sigc::signal signal_new_port; + sigc::signal signal_put; sigc::signal signal_clear_patch; sigc::signal signal_object_renamed; sigc::signal signal_object_destroyed; @@ -101,17 +98,8 @@ protected: void new_plugin(const Raul::URI& uri, const Raul::URI& type_uri, const Raul::Symbol& symbol) { if (_enabled) signal_new_plugin.emit(uri, type_uri, symbol); } - bool new_object(const Shared::GraphObject* object) - { if (_enabled) signal_new_object.emit(object); return false; } - - void new_patch(const Raul::Path& path, uint32_t poly) - { if (_enabled) signal_new_patch.emit(path, poly); } - - void new_node(const Raul::Path& path, const Raul::URI& plugin_uri) - { if (_enabled) signal_new_node.emit(path, plugin_uri); } - - void new_port(const Raul::Path& path, const Raul::URI& type, uint32_t index, bool is_output) - { if (_enabled) signal_new_port.emit(path, type, index, is_output); } + void put(const Raul::Path& path, const Shared::Resource::Properties& properties) + { if (_enabled) signal_put.emit(path, properties); } void connect(const Raul::Path& src_port_path, const Raul::Path& dst_port_path) { if (_enabled) signal_connection.emit(src_port_path, dst_port_path); } diff --git a/src/client/ThreadedSigClientInterface.cpp b/src/client/ThreadedSigClientInterface.cpp index c6ddd09e..5bd7e8b3 100644 --- a/src/client/ThreadedSigClientInterface.cpp +++ b/src/client/ThreadedSigClientInterface.cpp @@ -77,31 +77,5 @@ ThreadedSigClientInterface::emit_signals() } -bool -ThreadedSigClientInterface::new_object(const Shared::GraphObject* object) -{ - using namespace Shared; - const Patch* patch = dynamic_cast(object); - if (patch) { - new_patch(patch->path(), patch->internal_polyphony()); - return true; - } - - const Node* node = dynamic_cast(object); - if (node) { - new_node(node->path(), node->plugin()->uri()); - return true; - } - - const Port* port = dynamic_cast(object); - if (port) { - new_port(port->path(), port->type().uri(), port->index(), !port->is_input()); - return true; - } - - return false; -} - - } // namespace Client } // namespace Ingen diff --git a/src/client/ThreadedSigClientInterface.hpp b/src/client/ThreadedSigClientInterface.hpp index 029a30c1..7b7d11e2 100644 --- a/src/client/ThreadedSigClientInterface.hpp +++ b/src/client/ThreadedSigClientInterface.hpp @@ -51,9 +51,8 @@ public: , response_error_slot(signal_response_error.make_slot()) , error_slot(signal_error.make_slot()) , new_plugin_slot(signal_new_plugin.make_slot()) - , new_patch_slot(signal_new_patch.make_slot()) - , new_node_slot(signal_new_node.make_slot()) , new_port_slot(signal_new_port.make_slot()) + , put_slot(signal_put.make_slot()) , connection_slot(signal_connection.make_slot()) , clear_patch_slot(signal_clear_patch.make_slot()) , object_destroyed_slot(signal_object_destroyed.make_slot()) @@ -93,16 +92,8 @@ public: void new_plugin(const Raul::URI& uri, const Raul::URI& type_uri, const Raul::Symbol& symbol) { push_sig(sigc::bind(new_plugin_slot, uri, type_uri, symbol)); } - bool new_object(const Shared::GraphObject* object); - - void new_patch(const Raul::Path& path, uint32_t poly) - { push_sig(sigc::bind(new_patch_slot, path, poly)); } - - void new_node(const Raul::Path& path, const Raul::URI& plugin_uri) - { push_sig(sigc::bind(new_node_slot, path, plugin_uri)); } - - void new_port(const Raul::Path& path, const Raul::URI& type, uint32_t index, bool is_output) - { push_sig(sigc::bind(new_port_slot, path, type, index, is_output)); } + void put(const Raul::Path& path, const Shared::Resource::Properties& properties) + { push_sig(sigc::bind(put_slot, path, properties)); } void connect(const Raul::Path& src_port_path, const Raul::Path& dst_port_path) { push_sig(sigc::bind(connection_slot, src_port_path, dst_port_path)); } @@ -152,9 +143,8 @@ private: sigc::slot response_error_slot; sigc::slot error_slot; sigc::slot new_plugin_slot; - sigc::slot new_patch_slot; - sigc::slot new_node_slot; sigc::slot new_port_slot; + sigc::slot put_slot; sigc::slot connection_slot; sigc::slot clear_patch_slot; sigc::slot object_destroyed_slot; diff --git a/src/common/interface/CommonInterface.hpp b/src/common/interface/CommonInterface.hpp index b0676ac7..3c81a4a3 100644 --- a/src/common/interface/CommonInterface.hpp +++ b/src/common/interface/CommonInterface.hpp @@ -45,18 +45,8 @@ public: /** End (and send) an atomic bundle */ virtual void bundle_end() = 0; - virtual bool new_object(const GraphObject* object) = 0; - - virtual void new_patch(const Raul::Path& path, - uint32_t poly) = 0; - - virtual void new_node(const Raul::Path& path, - const Raul::URI& plugin_uri) = 0; - - virtual void new_port(const Raul::Path& path, - const Raul::URI& type, - uint32_t index, - bool is_output) = 0; + virtual void put(const Raul::Path& path, + const Resource::Properties& properties) = 0; virtual void rename(const Raul::Path& old_path, const Raul::Path& new_path) = 0; diff --git a/src/common/interface/Resource.hpp b/src/common/interface/Resource.hpp index 9fac8d0b..7512bfe7 100644 --- a/src/common/interface/Resource.hpp +++ b/src/common/interface/Resource.hpp @@ -30,11 +30,11 @@ namespace Shared { class Resource { public: - typedef std::map Properties; + 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 const Properties& properties() const = 0; + virtual Properties& properties() = 0; virtual void set_property(const Raul::URI& uri, const Raul::Atom& value) = 0; diff --git a/src/engine/Engine.cpp b/src/engine/Engine.cpp index 5da8ca56..4d697b5e 100644 --- a/src/engine/Engine.cpp +++ b/src/engine/Engine.cpp @@ -190,6 +190,9 @@ Engine::activate(size_t parallelism) if (!root_patch) { root_patch = new PatchImpl(*this, "", 1, NULL, _audio_driver->sample_rate(), _audio_driver->buffer_size(), 1); + root_patch->add_property("rdf:type", Raul::Atom(Raul::Atom::URI, "ingen:Patch")); + root_patch->add_property("rdf:type", Raul::Atom(Raul::Atom::URI, "ingen:Node")); + root_patch->set_property("ingen:polyphony", Raul::Atom(int32_t(1))); root_patch->activate(); _world->store->add(root_patch); root_patch->compiled_patch(root_patch->compile()); diff --git a/src/engine/GraphObjectImpl.cpp b/src/engine/GraphObjectImpl.cpp index 71730202..ef4e2cd4 100644 --- a/src/engine/GraphObjectImpl.cpp +++ b/src/engine/GraphObjectImpl.cpp @@ -30,7 +30,14 @@ using namespace Shared; void GraphObjectImpl::set_variable(const Raul::URI& key, const Atom& value) { - _variables[key] = value; + // Ignore duplicate statements + typedef Resource::Properties::const_iterator iterator; + const std::pair range = _variables.equal_range(key); + for (iterator i = range.first; i != range.second; ++i) + if (i->second == value) + return; + + _variables.insert(make_pair(key, value)); } diff --git a/src/engine/HTTPClientSender.cpp b/src/engine/HTTPClientSender.cpp index 5804ce43..b3fd1bc0 100644 --- a/src/engine/HTTPClientSender.cpp +++ b/src/engine/HTTPClientSender.cpp @@ -49,20 +49,11 @@ HTTPClientSender::error(const std::string& msg) } -void HTTPClientSender::new_node(const Raul::Path& node_path, - const Raul::URI& plugin_uri) -{ - //send("/ingen/new_node", "ss", node_path.c_str(), plugin_uri.c_str(), LO_ARGS_END); -} - - void -HTTPClientSender::new_port(const Raul::Path& path, - const Raul::URI& type, - uint32_t index, - bool is_output) +HTTPClientSender::put(const Raul::Path& path, + const Shared::Resource::Properties& properties) { - //send("/ingen/new_port", "sisi", path.c_str(), index, type.c_str(), is_output, LO_ARGS_END); + cerr << "HTTP CLIENT PUT " << path << endl; } @@ -163,6 +154,7 @@ HTTPClientSender::activity(const Raul::Path& path) send_chunk(msg); } +#if 0 static void null_deleter(const Shared::GraphObject*) {} bool @@ -178,6 +170,7 @@ HTTPClientSender::new_object(const Shared::GraphObject* object) send_chunk(str); return true; } +#endif void @@ -194,13 +187,6 @@ HTTPClientSender::new_plugin(const Raul::URI& uri, } -void -HTTPClientSender::new_patch(const Raul::Path& path, uint32_t poly) -{ - //send_chunk(string("<").append(path.str()).append("> a ingen:Patch")); -} - - void HTTPClientSender::rename(const Raul::Path& old_path, const Raul::Path& new_path) { diff --git a/src/engine/HTTPClientSender.hpp b/src/engine/HTTPClientSender.hpp index 2cfe6098..e4a88112 100644 --- a/src/engine/HTTPClientSender.hpp +++ b/src/engine/HTTPClientSender.hpp @@ -72,22 +72,14 @@ public: void error(const std::string& msg); - virtual bool new_object(const Shared::GraphObject* object); + //virtual bool new_object(const Shared::GraphObject* object); virtual void new_plugin(const Raul::URI& uri, const Raul::URI& type_uri, const Raul::Symbol& symbol); - virtual void new_patch(const Raul::Path& path, - uint32_t poly); - - virtual void new_node(const Raul::Path& path, - const Raul::URI& plugin_uri); - - virtual void new_port(const Raul::Path& path, - const Raul::URI& type, - uint32_t index, - bool is_output); + virtual void put(const Raul::Path& path, + const Shared::Resource::Properties& properties); virtual void clear_patch(const Raul::Path& path); diff --git a/src/engine/InputPort.cpp b/src/engine/InputPort.cpp index c8b373c1..9b10580f 100644 --- a/src/engine/InputPort.cpp +++ b/src/engine/InputPort.cpp @@ -19,11 +19,12 @@ #include #include #include +#include "interface/Patch.hpp" #include "AudioBuffer.hpp" -#include "EventBuffer.hpp" #include "ConnectionImpl.hpp" -#include "OutputPort.hpp" +#include "EventBuffer.hpp" #include "NodeImpl.hpp" +#include "OutputPort.hpp" #include "ProcessContext.hpp" #include "util.hpp" @@ -31,6 +32,7 @@ using namespace std; namespace Ingen { +namespace Shared { class Patch; } using namespace Shared; InputPort::InputPort(NodeImpl* parent, @@ -42,6 +44,8 @@ InputPort::InputPort(NodeImpl* parent, size_t buffer_size) : PortImpl(parent, name, index, poly, type, value, buffer_size) { + if (!dynamic_cast(parent)) + add_property("rdf:type", Raul::Atom(Raul::Atom::URI, "lv2:InputPort")); } diff --git a/src/engine/OSCClientSender.cpp b/src/engine/OSCClientSender.cpp index 5f351b87..55a42e9f 100644 --- a/src/engine/OSCClientSender.cpp +++ b/src/engine/OSCClientSender.cpp @@ -120,45 +120,11 @@ OSCClientSender::error(const std::string& msg) } -/** \page client_osc_namespace - *

\b /ingen/new_node - Notification of a new node's creation. - * \arg \b plug-uri (string) - URI of the plugin new node is an instance of - * \arg \b path (string) - Path of the new node - * \arg \b polyphonic (boolean) - Node is polyphonic\n\n - * \li New nodes are sent as a bundle. The first message in the bundle will be - * this one (/ingen/new_node), followed by a series of /ingen/new_port commands, - * followed by /ingen/new_node_end.

\n \n - */ -void OSCClientSender::new_node(const Path& node_path, - const URI& plugin_uri) -{ - send("/ingen/new_node", "ss", node_path.c_str(), plugin_uri.c_str(), LO_ARGS_END); -} - - - -/** \page client_osc_namespace - *

\b /ingen/new_port - Notification of a new port's creation. - * \arg \b path (string) - Path of new port - * \arg \b index (integer) - Index (or sort key) of port on parent - * \arg \b data-type (string) - Type of port (ingen:AudioPort, ingen:ControlPort, ingen:EventPort) - * \arg \b direction ("is-output") (integer) - Direction of data flow (Input = 0, Output = 1) - * - * \li Note that in the event of loading a patch, this message could be - * followed immediately by a control change, meaning the default-value is - * not actually the current value of the port. - * \li The minimum and maximum values are suggestions only, they are not - * enforced in any way, and going outside them is perfectly fine. Also note - * that the port ranges in om_gtk are not these ones! Those ranges are set - * as variable.

\n \n - */ void -OSCClientSender::new_port(const Path& path, - const URI& type, - uint32_t index, - bool is_output) +OSCClientSender::put(const Raul::Path& path, + const Shared::Resource::Properties& properties) { - send("/ingen/new_port", "sisi", path.c_str(), index, type.c_str(), is_output, LO_ARGS_END); + cerr << "OSC CLIENT PUT " << path << endl; } @@ -307,47 +273,6 @@ OSCClientSender::new_plugin(const URI& uri, } -bool -OSCClientSender::new_object(const Shared::GraphObject* object) -{ -#if 0 - using namespace Shared; - - const Patch* patch = dynamic_cast(object); - if (patch) { - new_patch(patch->path(), patch->internal_polyphony()); - return true; - } - - const Node* node = dynamic_cast(object); - if (node) { - new_node(node->path(), node->plugin()->uri()); - return true; - } - - const Port* port = dynamic_cast(object); - if (port) { - new_port(port->path(), port->type().uri(), port->index(), !port->is_input()); - return true; - } -#endif - - return false; -} - - -/** \page client_osc_namespace - *

\b /ingen/new_patch - Notification of a new patch - * \arg \b path (string) - Path of new patch - * \arg \b poly (int) - Polyphony of new patch (\em not a boolean like new_node)

\n \n - */ -void -OSCClientSender::new_patch(const Path& path, uint32_t poly) -{ - send("/ingen/new_patch", "si", path.c_str(), poly, LO_ARGS_END); -} - - /** \page client_osc_namespace *

\b /ingen/rename - Notification of an object's renaming * \arg \b old-path (string) - Old path of object diff --git a/src/engine/OSCClientSender.hpp b/src/engine/OSCClientSender.hpp index 404bdee7..b66ff59d 100644 --- a/src/engine/OSCClientSender.hpp +++ b/src/engine/OSCClientSender.hpp @@ -71,22 +71,12 @@ public: void error(const std::string& msg); - virtual bool new_object(const Shared::GraphObject* object); - virtual void new_plugin(const Raul::URI& uri, const Raul::URI& type_uri, const Raul::Symbol& symbol); - virtual void new_patch(const Raul::Path& path, - uint32_t poly); - - virtual void new_node(const Raul::Path& path, - const Raul::URI& plugin_uri); - - virtual void new_port(const Raul::Path& path, - const Raul::URI& type, - uint32_t index, - bool is_output); + virtual void put(const Raul::Path& path, + const Shared::Resource::Properties& properties); virtual void clear_patch(const Raul::Path& path); diff --git a/src/engine/OSCEngineReceiver.cpp b/src/engine/OSCEngineReceiver.cpp index 8fa92803..37a8132a 100644 --- a/src/engine/OSCEngineReceiver.cpp +++ b/src/engine/OSCEngineReceiver.cpp @@ -94,7 +94,7 @@ OSCEngineReceiver::OSCEngineReceiver(Engine& engine, size_t queue_size, uint16_t lo_server_add_method(_server, "/ingen/set_polyphonic", "isT", set_polyphonic_cb, this); lo_server_add_method(_server, "/ingen/set_polyphonic", "isF", set_polyphonic_cb, this); lo_server_add_method(_server, "/ingen/new_port", "issi", new_port_cb, this); - lo_server_add_method(_server, "/ingen/new_node", "iss", new_node_by_uri_cb, this); + lo_server_add_method(_server, "/ingen/put", NULL, new_port_cb, this); lo_server_add_method(_server, "/ingen/destroy", "is", destroy_cb, this); lo_server_add_method(_server, "/ingen/rename", "iss", rename_cb, this); lo_server_add_method(_server, "/ingen/connect", "iss", connect_cb, this); @@ -365,23 +365,6 @@ OSCEngineReceiver::_engine_deactivate_cb(const char* path, const char* types, lo } -/** \page engine_osc_namespace - *

\b /ingen/new_patch - Creates a new, empty, toplevel patch. - * \arg \b response-id (integer) - * \arg \b patch-path (string) - Patch path (complete, ie /master/parent/new_patch) - * \arg \b poly (integer) - Patch's (internal) polyphony

\n \n - */ -int -OSCEngineReceiver::_new_patch_cb(const char* path, const char* types, lo_arg** argv, int argc, lo_message msg) -{ - const char* patch_path = &argv[1]->s; - const int32_t poly = argv[2]->i; - - new_patch(patch_path, poly); - return 0; -} - - /** \page engine_osc_namespace *

\b /ingen/rename - Rename an Object (only Nodes, for now) * \arg \b response-id (integer) @@ -414,42 +397,6 @@ OSCEngineReceiver::_clear_patch_cb(const char* path, const char* types, lo_arg** } -// FIXME: add index -/** \page engine_osc_namespace - *

\b /ingen/new_port - Add a port into a given patch (load a plugin by URI) - * \arg \b response-id (integer) - * \arg \b path (string) - Full path of the new port (ie. /patch2/subpatch/newport) - * \arg \b data-type (string) - Type of port (lv2:AudioPort, lv2:ControlPort, lv2ev:EventPort) - * \arg \b direction ("is-output") (integer) - Direction of data flow (Input = 0, Output = 1)

\n \n - */ -int -OSCEngineReceiver::_new_port_cb(const char* path, const char* types, lo_arg** argv, int argc, lo_message msg) -{ - const char* port_path = &argv[1]->s; - const char* data_type = &argv[2]->s; - const int32_t direction = argv[3]->i; - - new_port(port_path, data_type, 0, (direction == 1)); - return 0; -} - -/** \page engine_osc_namespace - *

\b /ingen/new_node - Add a node into a given patch (load a plugin by URI) - * \arg \b response-id (integer) - * \arg \b node-path (string) - Full path of the new node (ie. /patch2/subpatch/newnode) - * \arg \b plug-uri (string) - URI of the plugin to load \n \n - */ -int -OSCEngineReceiver::_new_node_by_uri_cb(const char* path, const char* types, lo_arg** argv, int argc, lo_message msg) -{ - const char* node_path = &argv[1]->s; - const char* plug_uri = &argv[2]->s; - - new_node(node_path, plug_uri); - return 0; -} - - /** \page engine_osc_namespace *

\b /ingen/destroy - Removes (destroys) a Patch or a Node * \arg \b response-id (integer) diff --git a/src/engine/OSCEngineReceiver.hpp b/src/engine/OSCEngineReceiver.hpp index 04fc357a..fada5a17 100644 --- a/src/engine/OSCEngineReceiver.hpp +++ b/src/engine/OSCEngineReceiver.hpp @@ -92,7 +92,7 @@ private: LO_HANDLER(new_patch); LO_HANDLER(rename); LO_HANDLER(new_port); - LO_HANDLER(new_node_by_uri); + LO_HANDLER(put); LO_HANDLER(clear_patch); LO_HANDLER(set_polyphony); LO_HANDLER(set_polyphonic); diff --git a/src/engine/ObjectSender.cpp b/src/engine/ObjectSender.cpp index 01fa3f3b..9bf70cbf 100644 --- a/src/engine/ObjectSender.cpp +++ b/src/engine/ObjectSender.cpp @@ -27,6 +27,7 @@ #include "AudioBuffer.hpp" using namespace std; +using namespace Raul; namespace Ingen { @@ -35,9 +36,6 @@ using namespace Shared; void ObjectSender::send_object(ClientInterface* client, const GraphObjectImpl* object, bool recursive) { - if (client->new_object(object)) - return; - const PatchImpl* patch = dynamic_cast(object); if (patch) { send_patch(client, patch, recursive); @@ -64,20 +62,16 @@ ObjectSender::send_patch(ClientInterface* client, const PatchImpl* patch, bool r if (bundle) client->transfer_begin(); - client->new_patch(patch->path(), patch->internal_polyphony()); - client->set_variable(patch->path(), "ingen:polyphonic", bool(patch->polyphonic())); - - // Send variable - const GraphObjectImpl::Properties& data = patch->variables(); - for (GraphObjectImpl::Properties::const_iterator j = data.begin(); j != data.end(); ++j) - client->set_variable(patch->path(), (*j).first, (*j).second); - - client->set_variable(patch->path(), "ingen:enabled", (bool)patch->enabled()); + client->put(patch->path(), patch->properties()); if (recursive) { + // Send variables + const GraphObjectImpl::Properties& data = patch->variables(); + for (GraphObjectImpl::Properties::const_iterator j = data.begin(); j != data.end(); ++j) + client->set_variable(patch->path(), (*j).first, (*j).second); // Send nodes - for (Raul::List::const_iterator j = patch->nodes().begin(); + for (List::const_iterator j = patch->nodes().begin(); j != patch->nodes().end(); ++j) { const NodeImpl* const node = (*j); send_node(client, node, true, false); @@ -119,18 +113,12 @@ ObjectSender::send_node(ClientInterface* client, const NodeImpl* node, bool recu if (bundle) client->transfer_begin(); - client->new_node(node->path(), node->plugin()->uri()); - client->set_variable(node->path(), "ingen:polyphonic", bool(node->polyphonic())); + client->put(node->path(), node->variables()); // Send variables - const GraphObjectImpl::Properties& data = node->variables(); - for (GraphObjectImpl::Properties::const_iterator j = data.begin(); j != data.end(); ++j) - client->set_variable(node->path(), (*j).first, (*j).second); - - // Send properties - const GraphObjectImpl::Properties& prop = node->properties(); + const GraphObjectImpl::Properties& prop = node->variables(); for (GraphObjectImpl::Properties::const_iterator j = prop.begin(); j != prop.end(); ++j) - client->set_property(node->path(), (*j).first, (*j).second); + client->set_variable(node->path(), (*j).first, (*j).second); if (recursive) { // Send ports @@ -151,12 +139,13 @@ ObjectSender::send_port(ClientInterface* client, const PortImpl* port, bool bund if (bundle) client->bundle_begin(); - client->new_port(port->path(), port->type().uri(), port->index(), port->is_output()); + client->put(port->path(), port->properties()); + PatchImpl* graph_parent = dynamic_cast(port->parent_node()); if (graph_parent && graph_parent->internal_polyphony() > 1) client->set_variable(port->path(), "ingen:polyphonic", bool(port->polyphonic())); - // Send variable + // Send variables const GraphObjectImpl::Properties& data = port->variables(); for (GraphObjectImpl::Properties::const_iterator j = data.begin(); j != data.end(); ++j) client->set_variable(port->path(), (*j).first, (*j).second); diff --git a/src/engine/OutputPort.cpp b/src/engine/OutputPort.cpp index aa3007b0..020ea6bb 100644 --- a/src/engine/OutputPort.cpp +++ b/src/engine/OutputPort.cpp @@ -16,14 +16,17 @@ */ #include -#include "OutputPort.hpp" +#include "interface/Patch.hpp" #include "Buffer.hpp" +#include "NodeImpl.hpp" +#include "OutputPort.hpp" #include "ProcessContext.hpp" using namespace std; namespace Ingen { +namespace Shared { class Patch; } using namespace Shared; OutputPort::OutputPort(NodeImpl* parent, @@ -35,6 +38,9 @@ OutputPort::OutputPort(NodeImpl* parent, size_t buffer_size) : PortImpl(parent, name, index, poly, type, value, buffer_size) { + if (!dynamic_cast(parent)) + add_property("rdf:type", Raul::Atom(Raul::Atom::URI, "lv2:OutputPort")); + if (type == DataType::CONTROL) _broadcast = true; } diff --git a/src/engine/PortImpl.cpp b/src/engine/PortImpl.cpp index 15a44355..c81e797a 100644 --- a/src/engine/PortImpl.cpp +++ b/src/engine/PortImpl.cpp @@ -28,19 +28,20 @@ #include "events/SendPortActivityEvent.hpp" using namespace std; +using namespace Raul; namespace Ingen { using namespace Shared; -PortImpl::PortImpl(NodeImpl* const node, - const string& name, - uint32_t index, - uint32_t poly, - DataType type, - const Raul::Atom& value, - size_t buffer_size) +PortImpl::PortImpl(NodeImpl* const node, + const string& name, + uint32_t index, + uint32_t poly, + DataType type, + const Atom& value, + size_t buffer_size) : GraphObjectImpl(node, name, (type == DataType::AUDIO || type == DataType::CONTROL)) , _index(index) , _poly(poly) @@ -50,9 +51,9 @@ PortImpl::PortImpl(NodeImpl* const node, , _fixed_buffers(false) , _broadcast(false) , _set_by_user(false) - , _last_broadcasted_value(_value.type() == Raul::Atom::FLOAT ? _value.get_float() : 0.0f) // default? + , _last_broadcasted_value(_value.type() == Atom::FLOAT ? _value.get_float() : 0.0f) // default? , _context(Context::AUDIO) - , _buffers(new Raul::Array(poly)) + , _buffers(new Array(poly)) , _prepared_buffers(NULL) { assert(node != NULL); @@ -65,8 +66,16 @@ PortImpl::PortImpl(NodeImpl* const node, else _polyphonic = true; - if (type == DataType::EVENT) + if (type == DataType::AUDIO) + add_property("rdf:type", Atom(Atom::URI, "lv2:AudioPort")); + + if (type == DataType::CONTROL) + add_property("rdf:type", Atom(Atom::URI, "lv2:ControlPort")); + + if (type == DataType::EVENT) { + add_property("rdf:type", Atom(Atom::URI, "lv2ev:EventPort")); _broadcast = true; // send activity blips + } assert(_buffers->size() > 0); } @@ -83,7 +92,7 @@ PortImpl::~PortImpl() bool -PortImpl::set_polyphonic(Raul::Maid& maid, bool p) +PortImpl::set_polyphonic(Maid& maid, bool p) { if (_type == DataType::CONTROL || _type == DataType::AUDIO) return GraphObjectImpl::set_polyphonic(maid, p); @@ -100,7 +109,7 @@ PortImpl::prepare_poly(uint32_t poly) /* FIXME: poly never goes down, harsh on memory.. */ if (poly > _poly) { - _prepared_buffers = new Raul::Array(poly, *_buffers); + _prepared_buffers = new Array(poly, *_buffers); for (uint32_t i = _poly; i < _prepared_buffers->size(); ++i) _prepared_buffers->at(i) = Buffer::create(_type, _buffer_size); } @@ -110,7 +119,7 @@ PortImpl::prepare_poly(uint32_t poly) bool -PortImpl::apply_poly(Raul::Maid& maid, uint32_t poly) +PortImpl::apply_poly(Maid& maid, uint32_t poly) { if (!_polyphonic || !_parent->polyphonic()) return true; diff --git a/src/engine/QueuedEngineInterface.cpp b/src/engine/QueuedEngineInterface.cpp index e19261f7..a1192c03 100644 --- a/src/engine/QueuedEngineInterface.cpp +++ b/src/engine/QueuedEngineInterface.cpp @@ -23,6 +23,7 @@ #include "Engine.hpp" #include "AudioDriver.hpp" +using namespace std; using namespace Raul; namespace Ingen { @@ -149,36 +150,36 @@ QueuedEngineInterface::bundle_end() // Object commands -bool -QueuedEngineInterface::new_object(const GraphObject* object) -{ - return false; -} - - -void -QueuedEngineInterface::new_patch(const Path& path, - uint32_t poly) -{ - push_queued(new CreatePatchEvent(_engine, _responder, now(), path, poly)); -} - - -// FIXME: use index -void QueuedEngineInterface::new_port(const Path& path, - const URI& type, - uint32_t index, - bool direction) -{ - push_queued(new CreatePortEvent(_engine, _responder, now(), path, type, direction, this)); -} - void -QueuedEngineInterface::new_node(const Path& path, - const URI& plugin_uri) -{ - push_queued(new CreateNodeEvent(_engine, _responder, now(), path, plugin_uri, true)); +QueuedEngineInterface::put(const Path& path, + const Resource::Properties& properties) +{ + typedef Resource::Properties::const_iterator iterator; + cerr << "ENGINE PUT " << path << " {" << endl; + for (iterator i = properties.begin(); i != properties.end(); ++i) + cerr << "\t" << i->first << " = " << i->second << " :: " << i->second.type() << endl; + cerr << "}" << endl; + + bool is_patch = false, is_node = false, is_port = false, is_output = false; + DataType data_type(DataType::UNKNOWN); + ResourceImpl::type(properties, is_patch, is_node, is_port, is_output, data_type); + + if (is_patch) { + uint32_t poly = 1; + iterator p = properties.find("ingen:polyphony"); + if (p != properties.end() && p->second.is_valid() && p->second.type() == Atom::INT) + poly = p->second.get_int32(); + push_queued(new CreatePatchEvent( + _engine, _responder, now(), path, poly, properties)); + } else if (is_node) { + const iterator p = properties.find("rdf:instanceOf"); + push_queued(new CreateNodeEvent( + _engine, _responder, now(), path, p->second.get_uri(), true, properties)); + } else if (is_port) { + push_queued(new CreatePortEvent( + _engine, _responder, now(), path, data_type.uri(), is_output, this, properties)); + } } diff --git a/src/engine/QueuedEngineInterface.hpp b/src/engine/QueuedEngineInterface.hpp index 1263c225..f12a1b23 100644 --- a/src/engine/QueuedEngineInterface.hpp +++ b/src/engine/QueuedEngineInterface.hpp @@ -22,12 +22,13 @@ #include #include #include "raul/SharedPtr.hpp" -#include "types.hpp" -#include "tuning.hpp" -#include "interface/EngineInterface.hpp" #include "interface/ClientInterface.hpp" -#include "Responder.hpp" +#include "interface/EngineInterface.hpp" +#include "interface/Resource.hpp" #include "QueuedEventSource.hpp" +#include "Responder.hpp" +#include "tuning.hpp" +#include "types.hpp" namespace Ingen { @@ -70,18 +71,8 @@ public: // CommonInterface object commands - virtual bool new_object(const Shared::GraphObject* object); - - virtual void new_patch(const Raul::Path& path, - uint32_t poly); - - virtual void new_node(const Raul::Path& path, - const Raul::URI& plugin_uri); - - virtual void new_port(const Raul::Path& path, - const Raul::URI& type, - uint32_t index, - bool is_output); + virtual void put(const Raul::Path& path, + const Shared::Resource::Properties& properties); virtual void rename(const Raul::Path& old_path, const Raul::Path& new_path); diff --git a/src/engine/events/CreateNodeEvent.cpp b/src/engine/events/CreateNodeEvent.cpp index fea858f1..6f3ed834 100644 --- a/src/engine/events/CreateNodeEvent.cpp +++ b/src/engine/events/CreateNodeEvent.cpp @@ -38,8 +38,16 @@ using namespace Raul; namespace Ingen { - -CreateNodeEvent::CreateNodeEvent(Engine& engine, SharedPtr responder, SampleCount timestamp, const Path& path, const URI& plugin_uri, bool polyphonic) +using namespace Shared; + +CreateNodeEvent::CreateNodeEvent( + Engine& engine, + SharedPtr responder, + SampleCount timestamp, + const Path& path, + const URI& plugin_uri, + bool polyphonic, + const Resource::Properties& properties) : QueuedEvent(engine, responder, timestamp) , _path(path) , _plugin_uri(plugin_uri) @@ -48,6 +56,7 @@ CreateNodeEvent::CreateNodeEvent(Engine& engine, SharedPtr responder, , _node(NULL) , _compiled_patch(NULL) , _node_already_exists(false) + , _properties(properties) { string uri = _plugin_uri.str(); if (uri.substr(0, 3) == "om:") { @@ -80,6 +89,7 @@ CreateNodeEvent::pre_process() if (_patch && plugin) { _node = plugin->instantiate(_path.name(), _polyphonic, _patch, _engine); + _node->variables().insert(_properties.begin(), _properties.end()); if (_node != NULL) { _node->activate(); diff --git a/src/engine/events/CreateNodeEvent.hpp b/src/engine/events/CreateNodeEvent.hpp index 7065cb84..b8dbf082 100644 --- a/src/engine/events/CreateNodeEvent.hpp +++ b/src/engine/events/CreateNodeEvent.hpp @@ -20,6 +20,7 @@ #include #include "QueuedEvent.hpp" +#include "interface/Resource.hpp" namespace Ingen { @@ -35,12 +36,14 @@ class CompiledPatch; class CreateNodeEvent : public QueuedEvent { public: - CreateNodeEvent(Engine& engine, - SharedPtr responder, - SampleCount timestamp, - const Raul::Path& node_path, - const Raul::URI& plugin_uri, - bool poly); + CreateNodeEvent( + Engine& engine, + SharedPtr responder, + SampleCount timestamp, + const Raul::Path& node_path, + const Raul::URI& plugin_uri, + bool poly, + const Shared::Resource::Properties& properties); void pre_process(); void execute(ProcessContext& context); @@ -57,6 +60,8 @@ private: NodeImpl* _node; CompiledPatch* _compiled_patch; ///< Patch's new process order bool _node_already_exists; + + Shared::Resource::Properties _properties; }; diff --git a/src/engine/events/CreatePatchEvent.cpp b/src/engine/events/CreatePatchEvent.cpp index 574d909b..f4a60760 100644 --- a/src/engine/events/CreatePatchEvent.cpp +++ b/src/engine/events/CreatePatchEvent.cpp @@ -32,8 +32,16 @@ using namespace Raul; namespace Ingen { +using namespace Shared; -CreatePatchEvent::CreatePatchEvent(Engine& engine, SharedPtr responder, SampleCount timestamp, const Raul::Path& path, int poly) + +CreatePatchEvent::CreatePatchEvent( + Engine& engine, + SharedPtr responder, + SampleCount timestamp, + const Raul::Path& path, + int poly, + const Resource::Properties& properties) : QueuedEvent(engine, responder, timestamp) , _path(path) , _patch(NULL) @@ -41,6 +49,7 @@ CreatePatchEvent::CreatePatchEvent(Engine& engine, SharedPtr responde , _compiled_patch(NULL) , _poly(poly) , _error(NO_ERROR) + , _properties(properties) { } @@ -74,6 +83,7 @@ CreatePatchEvent::pre_process() poly = _poly; _patch = new PatchImpl(_engine, path.name(), poly, _parent, _engine.audio_driver()->sample_rate(), _engine.audio_driver()->buffer_size(), _poly); + _patch->properties().insert(_properties.begin(), _properties.end()); if (_parent != NULL) { _parent->add_node(new PatchImpl::Nodes::Node(_patch)); diff --git a/src/engine/events/CreatePatchEvent.hpp b/src/engine/events/CreatePatchEvent.hpp index 796306f8..44b47d8c 100644 --- a/src/engine/events/CreatePatchEvent.hpp +++ b/src/engine/events/CreatePatchEvent.hpp @@ -19,6 +19,7 @@ #define CREATEPATCHEVENT_H #include "QueuedEvent.hpp" +#include "interface/Resource.hpp" namespace Ingen { @@ -33,7 +34,13 @@ class CompiledPatch; class CreatePatchEvent : public QueuedEvent { public: - CreatePatchEvent(Engine& engine, SharedPtr responder, SampleCount timestamp, const Raul::Path& path, int poly); + CreatePatchEvent( + Engine& engine, + SharedPtr responder, + SampleCount timestamp, + const Raul::Path& path, + int poly, + const Shared::Resource::Properties& properties); void pre_process(); void execute(ProcessContext& context); @@ -48,6 +55,8 @@ private: CompiledPatch* _compiled_patch; int _poly; ErrorType _error; + + Shared::Resource::Properties _properties; }; diff --git a/src/engine/events/CreatePortEvent.cpp b/src/engine/events/CreatePortEvent.cpp index 69ef7364..38c3587c 100644 --- a/src/engine/events/CreatePortEvent.cpp +++ b/src/engine/events/CreatePortEvent.cpp @@ -41,13 +41,15 @@ namespace Ingen { using namespace Shared; -CreatePortEvent::CreatePortEvent(Engine& engine, - SharedPtr responder, - SampleCount timestamp, - const Raul::Path& path, - const Raul::URI& type, - bool is_output, - QueuedEventSource* source) +CreatePortEvent::CreatePortEvent( + Engine& engine, + SharedPtr responder, + SampleCount timestamp, + const Raul::Path& path, + const Raul::URI& type, + bool is_output, + QueuedEventSource* source, + const Resource::Properties& properties) : QueuedEvent(engine, responder, timestamp, true, source) , _error(NO_ERROR) , _path(path) @@ -57,6 +59,7 @@ CreatePortEvent::CreatePortEvent(Engine& engine, , _patch(NULL) , _patch_port(NULL) , _driver_port(NULL) + , _properties(properties) { /* This is blocking because of the two different sets of Patch ports, the array used in the * audio thread (inherited from NodeBase), and the arrays used in the pre processor thread. @@ -93,6 +96,7 @@ CreatePortEvent::pre_process() const uint32_t old_num_ports = _patch->num_ports(); _patch_port = _patch->create_port(_path.name(), _data_type, buffer_size, _is_output); + _patch_port->properties().insert(_properties.begin(), _properties.end()); if (_patch_port) { diff --git a/src/engine/events/CreatePortEvent.hpp b/src/engine/events/CreatePortEvent.hpp index 4304e362..ab65eabd 100644 --- a/src/engine/events/CreatePortEvent.hpp +++ b/src/engine/events/CreatePortEvent.hpp @@ -22,8 +22,7 @@ #include "raul/Path.hpp" #include "raul/Array.hpp" #include "interface/DataType.hpp" - -template class Array; +#include "interface/Resource.hpp" namespace Ingen { @@ -39,7 +38,15 @@ class DriverPort; class CreatePortEvent : public QueuedEvent { public: - CreatePortEvent(Engine& engine, SharedPtr responder, SampleCount timestamp, const Raul::Path& path, const Raul::URI& type, bool is_output, QueuedEventSource* source); + CreatePortEvent( + Engine& engine, + SharedPtr responder, + SampleCount timestamp, + const Raul::Path& path, + const Raul::URI& type, + bool is_output, + QueuedEventSource* source, + const Shared::Resource::Properties& properties); void pre_process(); void execute(ProcessContext& context); @@ -63,6 +70,8 @@ private: Raul::Array* _ports_array; ///< New (external) ports array for Patch DriverPort* _driver_port; ///< Driver (eg Jack) port if this is a toplevel port bool _succeeded; + + Shared::Resource::Properties _properties; }; diff --git a/src/gui/LoadPluginWindow.cpp b/src/gui/LoadPluginWindow.cpp index b9f0cc03..2382cac0 100644 --- a/src/gui/LoadPluginWindow.cpp +++ b/src/gui/LoadPluginWindow.cpp @@ -343,7 +343,10 @@ LoadPluginWindow::add_clicked() dialog.run(); } else { Path path = _patch->path().base() + Path::nameify(name); - App::instance().engine()->new_node(path, plugin->uri()); + Resource::Properties props; + props.insert(make_pair("rdf:type", Atom(Atom::URI, "ingen:Node"))); + props.insert(make_pair("rdf:instanceOf", Atom(Atom::URI, plugin->uri().str()))); + App::instance().engine()->put(path, props); App::instance().engine()->set_variable(path, "ingen:polyphonic", bool(polyphonic)); for (GraphObject::Properties::const_iterator i = _initial_data.begin(); i != _initial_data.end(); ++i) @@ -351,9 +354,9 @@ LoadPluginWindow::add_clicked() _node_name_entry->set_text(generate_module_name(++_plugin_name_offset)); // Cascade - Atom& x = _initial_data["ingenuity:canvas-x"]; + Atom& x = _initial_data.find("ingenuity:canvas-x")->second; x = Atom(x.get_float() + 20.0f); - Atom& y = _initial_data["ingenuity:canvas-y"]; + Atom& y = _initial_data.find("ingenuity:canvas-y")->second; y = Atom(y.get_float() + 20.0f); } } @@ -453,9 +456,9 @@ LoadPluginWindow::on_key_press_event(GdkEventKey* event) } void -LoadPluginWindow::plugin_property_changed(const Raul::URI& plugin, - const Raul::URI& predicate, - const Raul::Atom& value) +LoadPluginWindow::plugin_property_changed(const URI& plugin, + const URI& predicate, + const Atom& value) { Rows::const_iterator i = _rows.find(plugin); if (i != _rows.end() && value.type() == Atom::STRING) diff --git a/src/gui/LoadSubpatchWindow.cpp b/src/gui/LoadSubpatchWindow.cpp index 17544cbd..848e7643 100644 --- a/src/gui/LoadSubpatchWindow.cpp +++ b/src/gui/LoadSubpatchWindow.cpp @@ -166,9 +166,9 @@ LoadSubpatchWindow::ok_clicked() std::list uris = get_uris(); for (std::list::iterator i = uris.begin(); i != uris.end(); ++i) { // Cascade - Atom& x = _initial_data["ingenuity:canvas-x"]; + Atom& x = _initial_data.find("ingenuity:canvas-x")->second; x = Atom(x.get_float() + 20.0f); - Atom& y = _initial_data["ingenuity:canvas-y"]; + Atom& y = _initial_data.find("ingenuity:canvas-y")->second; y = Atom(y.get_float() + 20.0f); App::instance().loader()->load_patch(false, *i, Path("/"), diff --git a/src/gui/NewSubpatchWindow.cpp b/src/gui/NewSubpatchWindow.cpp index 82b80a05..46663f2c 100644 --- a/src/gui/NewSubpatchWindow.cpp +++ b/src/gui/NewSubpatchWindow.cpp @@ -91,10 +91,14 @@ NewSubpatchWindow::name_changed() void NewSubpatchWindow::ok_clicked() { - const Path path = _patch->path().base() + Path::nameify(_name_entry->get_text()); + const Path path = _patch->path().base() + Path::nameify(_name_entry->get_text()); const uint32_t poly = _poly_spinbutton->get_value_as_int(); - App::instance().engine()->new_patch(path, poly); + Resource::Properties props; + props.insert(make_pair("rdf:type", Atom(Atom::URI, "ingen:Patch"))); + props.insert(make_pair("ingen:polyphony", Atom(int32_t(poly)))); + App::instance().engine()->put(path, props); + for (GraphObject::Properties::const_iterator i = _initial_data.begin(); i != _initial_data.end(); ++i) App::instance().engine()->set_variable(path, i->first, i->second); diff --git a/src/gui/NodeModule.cpp b/src/gui/NodeModule.cpp index 97932814..74276301 100644 --- a/src/gui/NodeModule.cpp +++ b/src/gui/NodeModule.cpp @@ -52,7 +52,8 @@ NodeModule::NodeModule(boost::shared_ptr canvas, SharedPtrsignal_new_port.connect(sigc::bind(sigc::mem_fun(this, &NodeModule::add_port), true)); node->signal_removed_port.connect(sigc::hide_return(sigc::mem_fun(this, &NodeModule::remove_port))); - node->signal_variable.connect(sigc::mem_fun(this, &NodeModule::set_variable)); + node->signal_variable.connect(sigc::mem_fun(this, &NodeModule::set_property)); + node->signal_property.connect(sigc::mem_fun(this, &NodeModule::set_property)); node->signal_renamed.connect(sigc::mem_fun(this, &NodeModule::rename)); } @@ -93,11 +94,13 @@ NodeModule::create(boost::shared_ptr canvas, SharedPtr n ret = boost::shared_ptr(new NodeModule(canvas, node)); for (GraphObject::Properties::const_iterator m = node->variables().begin(); m != node->variables().end(); ++m) - ret->set_variable(m->first, m->second); + ret->set_property(m->first, m->second); - for (NodeModel::Ports::const_iterator p = node->ports().begin(); p != node->ports().end(); ++p) { + for (GraphObject::Properties::const_iterator m = node->properties().begin(); m != node->properties().end(); ++m) + ret->set_property(m->first, m->second); + + for (NodeModel::Ports::const_iterator p = node->ports().begin(); p != node->ports().end(); ++p) ret->add_port(*p, false); - } ret->set_stacked_border(node->polyphonic()); @@ -371,7 +374,7 @@ NodeModule::store_location() void -NodeModule::set_variable(const URI& key, const Atom& value) +NodeModule::set_property(const URI& key, const Atom& value) { switch (value.type()) { case Atom::FLOAT: diff --git a/src/gui/NodeModule.hpp b/src/gui/NodeModule.hpp index 171f1142..a1a76e71 100644 --- a/src/gui/NodeModule.hpp +++ b/src/gui/NodeModule.hpp @@ -77,7 +77,7 @@ protected: void set_selected(bool b); void rename(); - void set_variable(const Raul::URI& predicate, const Raul::Atom& value); + void set_property(const Raul::URI& predicate, const Raul::Atom& value); void add_port(SharedPtr port, bool resize=true); diff --git a/src/gui/PatchCanvas.cpp b/src/gui/PatchCanvas.cpp index e6f4e65c..9f676303 100644 --- a/src/gui/PatchCanvas.cpp +++ b/src/gui/PatchCanvas.cpp @@ -105,12 +105,6 @@ PatchCanvas::PatchCanvas(SharedPtr patch, int width, int height) sigc::bind(sigc::mem_fun(this, &PatchCanvas::menu_add_port), "event_out", "Event Out", "lv2ev:EventPort", true)); - // Add control menu items - /*_menu_add_number_control->signal_activate().connect( - sigc::bind(sigc::mem_fun(this, &PatchCanvas::menu_add_control), NUMBER)); - _menu_add_button_control->signal_activate().connect( - sigc::bind(sigc::mem_fun(this, &PatchCanvas::menu_add_control), BUTTON));*/ - // Connect to model signals to track state _patch->signal_new_node.connect(sigc::mem_fun(this, &PatchCanvas::add_node)); _patch->signal_removed_node.connect(sigc::mem_fun(this, &PatchCanvas::remove_node)); @@ -673,18 +667,21 @@ PatchCanvas::paste() // mkdir -p string to_create = _patch->path().chop_scheme().substr(1); string created = "/"; - clipboard.new_patch("/", _patch->poly()); + Resource::Properties props; + props.insert(make_pair("rdf:type", Raul::Atom(Raul::Atom::URI, "ingen:Patch"))); + props.insert(make_pair("ingen:polyphony", Raul::Atom(int32_t(_patch->poly())))); + clipboard.put("/", props); size_t first_slash; while (to_create != "/" && to_create != "" && (first_slash = to_create.find("/")) != string::npos) { created += to_create.substr(0, first_slash); assert(Path::is_valid(created)); - clipboard.new_patch(created, _patch->poly()); + clipboard.put(created, props); to_create = to_create.substr(first_slash + 1); } if (!_patch->path().is_root()) - clipboard.new_patch(_patch->path(), _patch->poly()); + clipboard.put(_patch->path(), props); boost::optional data_path; boost::optional parent; @@ -759,20 +756,6 @@ PatchCanvas::generate_port_name( name.append(" ").append(num_buf); } -void -PatchCanvas::menu_add_control(ControlType type) -{ - // FIXME: bundleify - - GraphObject::Properties data = get_initial_data(); - float x = data["ingenuity:canvas-x"].get_float(); - float y = data["ingenuity:canvas-y"].get_float(); - - cerr << "ADD CONTROL: " << (unsigned)type << " @ " << x << ", " << y << endl; - - add_item(boost::shared_ptr( - new FlowCanvas::Ellipse(shared_from_this(), "control", x, y, 20, 20, true))); -} void PatchCanvas::menu_add_port(const string& sym_base, const string& name_base, @@ -781,13 +764,14 @@ PatchCanvas::menu_add_port(const string& sym_base, const string& name_base, string sym, name; generate_port_name(sym_base, sym, name_base, name); const Path& path = _patch->path().base() + sym; - App::instance().engine()->bundle_begin(); - App::instance().engine()->new_port(path, type, _patch->num_ports(), is_output); - GraphObject::Properties data = get_initial_data(); - App::instance().engine()->set_property(path, "lv2:name", Atom(name.c_str())); - for (GraphObject::Properties::const_iterator i = data.begin(); i != data.end(); ++i) - App::instance().engine()->set_property(path, i->first, i->second); - App::instance().engine()->bundle_end(); + + Resource::Properties props = get_initial_data(); + props.insert(make_pair("rdf:type", Atom(Atom::URI, type))); + props.insert(make_pair("rdf:type", + Atom(Atom::URI, is_output ? "lv2:OutputPort" : "lv2:InputPort"))); + props.insert(make_pair("lv2:index", Atom(int32_t(_patch->num_ports())))); + props.insert(make_pair("lv2:name", Atom(name.c_str()))); + App::instance().engine()->put(path, props); } @@ -808,10 +792,10 @@ PatchCanvas::load_plugin(WeakPtr weak_plugin) const Path path = _patch->path().base() + name; // FIXME: polyphony? - App::instance().engine()->new_node(path, plugin->uri()); - GraphObject::Properties data = get_initial_data(); - for (GraphObject::Properties::const_iterator i = data.begin(); i != data.end(); ++i) - App::instance().engine()->set_variable(path, i->first, i->second); + GraphObject::Properties props = get_initial_data(); + props.insert(make_pair("rdf:type", Raul::Atom(Raul::Atom::URI, "ingen:Node"))); + props.insert(make_pair("rdf:instanceOf", Raul::Atom(Raul::Atom::URI, plugin->uri().str()))); + App::instance().engine()->put(path, props); } @@ -832,10 +816,8 @@ GraphObject::Properties PatchCanvas::get_initial_data() { GraphObject::Properties result; - - result["ingenuity:canvas-x"] = Atom((float)_last_click_x); - result["ingenuity:canvas-y"] = Atom((float)_last_click_y); - + result.insert(make_pair("ingenuity:canvas-x", Atom((float)_last_click_x))); + result.insert(make_pair("ingenuity:canvas-y", Atom((float)_last_click_y))); return result; } diff --git a/src/gui/PatchCanvas.hpp b/src/gui/PatchCanvas.hpp index ca08a281..66db49fd 100644 --- a/src/gui/PatchCanvas.hpp +++ b/src/gui/PatchCanvas.hpp @@ -87,8 +87,6 @@ public: private: enum ControlType { NUMBER, BUTTON }; - void menu_add_control(ControlType type); - void generate_port_name( const string& sym_base, string& sym, const string& name_base, string& name); diff --git a/src/gui/PatchPortModule.cpp b/src/gui/PatchPortModule.cpp index 0b88746c..09b7dd4a 100644 --- a/src/gui/PatchPortModule.cpp +++ b/src/gui/PatchPortModule.cpp @@ -48,7 +48,7 @@ PatchPortModule::PatchPortModule(boost::shared_ptr canvas, SharedPt set_stacked_border(model->polyphonic()); - model->signal_variable.connect(sigc::mem_fun(this, &PatchPortModule::set_variable)); + model->signal_variable.connect(sigc::mem_fun(this, &PatchPortModule::set_property)); model->signal_property.connect(sigc::mem_fun(this, &PatchPortModule::set_property)); } @@ -65,7 +65,7 @@ PatchPortModule::create(boost::shared_ptr canvas, SharedPtrvariables().begin(); m != model->variables().end(); ++m) - ret->set_variable(m->first, m->second); + ret->set_property(m->first, m->second); for (GraphObject::Properties::const_iterator m = model->properties().begin(); m != model->properties().end(); ++m) @@ -131,24 +131,6 @@ PatchPortModule::set_name(const std::string& n) } -void -PatchPortModule::set_variable(const URI& key, const Atom& value) -{ - if (value.type() == Atom::BOOL) { - if (key.str() == "ingen:polyphonic") { - set_stacked_border(value.get_bool()); - } else if (key.str() == "ingen:selected") { - if (value.get_bool() != selected()) { - if (value.get_bool()) - _canvas.lock()->select_item(shared_from_this()); - else - _canvas.lock()->unselect_item(shared_from_this()); - } - } - } -} - - void PatchPortModule::set_property(const URI& key, const Atom& value) { @@ -166,6 +148,18 @@ PatchPortModule::set_property(const URI& key, const Atom& value) } else if (key.str() == "lv2:symbol" && !_human_name_visible) { set_name(value.get_string()); } + case Atom::BOOL: + if (key.str() == "ingen:polyphonic") { + set_stacked_border(value.get_bool()); + } else if (key.str() == "ingen:selected") { + if (value.get_bool() != selected()) { + if (value.get_bool()) { + _canvas.lock()->select_item(shared_from_this()); + } else { + _canvas.lock()->unselect_item(shared_from_this()); + } + } + } default: break; } } diff --git a/src/gui/PatchPortModule.hpp b/src/gui/PatchPortModule.hpp index 4275df44..060c3950 100644 --- a/src/gui/PatchPortModule.hpp +++ b/src/gui/PatchPortModule.hpp @@ -69,7 +69,6 @@ protected: void set_port(SharedPtr port) { _port = port; } - void set_variable(const Raul::URI& predicate, const Raul::Atom& value); void set_property(const Raul::URI& predicate, const Raul::Atom& value); SharedPtr _model; diff --git a/src/gui/PatchView.cpp b/src/gui/PatchView.cpp index 09bf94fa..e0c97bcf 100644 --- a/src/gui/PatchView.cpp +++ b/src/gui/PatchView.cpp @@ -87,10 +87,10 @@ PatchView::set_patch(SharedPtr patch) for (GraphObject::Properties::const_iterator i = patch->variables().begin(); i != patch->variables().end(); ++i) - variable_changed(i->first, i->second); + property_changed(i->first, i->second); // Connect model signals to track state - patch->signal_variable.connect(sigc::mem_fun(this, &PatchView::variable_changed)); + patch->signal_variable.connect(sigc::mem_fun(this, &PatchView::property_changed)); patch->signal_property.connect(sigc::mem_fun(this, &PatchView::property_changed)); // Connect widget signals to do things @@ -230,12 +230,6 @@ PatchView::refresh_clicked() void PatchView::property_changed(const Raul::URI& predicate, const Raul::Atom& value) -{ -} - - -void -PatchView::variable_changed(const Raul::URI& predicate, const Raul::Atom& value) { _enable_signal = false; if (predicate.str() == "ingen:enabled") { diff --git a/src/gui/PatchView.hpp b/src/gui/PatchView.hpp index 26954298..15fcc0e4 100644 --- a/src/gui/PatchView.hpp +++ b/src/gui/PatchView.hpp @@ -85,7 +85,6 @@ private: void canvas_item_left(Gnome::Canvas::Item* item); void property_changed(const Raul::URI& predicate, const Raul::Atom& value); - void variable_changed(const Raul::URI& predicate, const Raul::Atom& value); void zoom_full(); diff --git a/src/gui/UploadPatchWindow.cpp b/src/gui/UploadPatchWindow.cpp index 96b1e2c1..0057ec18 100644 --- a/src/gui/UploadPatchWindow.cpp +++ b/src/gui/UploadPatchWindow.cpp @@ -239,8 +239,8 @@ UploadPatchWindow::upload_clicked() Glib::ustring short_name = _short_name_entry->get_text(); GraphObject::Properties extra_rdf; - extra_rdf["lv2:symbol"] = Atom(Atom::STRING, symbol); - extra_rdf["doap:name"] = Atom(Atom::STRING, short_name); + extra_rdf.insert(make_pair("lv2:symbol", Atom(Atom::STRING, symbol))); + extra_rdf.insert(make_pair("doap:name", Atom(Atom::STRING, short_name))); _response = 0; _progress_pct = 0; diff --git a/src/serialisation/Parser.cpp b/src/serialisation/Parser.cpp index 732307b5..f290de5f 100644 --- a/src/serialisation/Parser.cpp +++ b/src/serialisation/Parser.cpp @@ -424,7 +424,10 @@ Parser::parse_patch( /* Create patch */ Path patch_path(patch_path_str); - target->new_patch(patch_path, patch_poly); + Resource::Properties props; + props.insert(make_pair("rdf:type", Raul::Atom(Raul::Atom::URI, "ingen:Patch"))); + props.insert(make_pair("ingen:polyphony", Raul::Atom(int32_t(patch_poly)))); + target->put(patch_path, props); /* Find patches in document */ @@ -521,7 +524,10 @@ Parser::parse_patch( if (type_i == types.end()) continue; const Path node_path(relative_uri(base_uri, i->first, true)); - target->new_node(node_path, type_i->second); + 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))); + 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); @@ -572,7 +578,8 @@ Parser::parse_patch( Redland::Node& port = (*i)["port"]; Redland::Node& type = (*i)["type"]; if (port.type() == Redland::Node::RESOURCE && type.type() == Redland::Node::RESOURCE) { - types.insert(make_pair(port.to_string(), type.to_string())); + types.insert(make_pair(port.to_string(), + world->rdf_world->prefixes().qualify(type.to_string()))); patch_ports.insert(make_pair(port.to_string(), Properties())); } } @@ -599,16 +606,16 @@ Parser::parse_patch( for (Objects::iterator i = patch_ports.begin(); i != patch_ports.end(); ++i) { Glib::Mutex::Lock lock(world->rdf_world->mutex()); const Path port_path(relative_uri(base_uri, i->first, true)); - Properties::iterator types_begin = i->second.find("rdf:type"); - if (types_begin == i->second.end()) { + std::pair types_range + = i->second.equal_range("rdf:type"); + if (types_range.first == i->second.end()) { cerr << "WARNING: Patch port has no types" << endl; continue; } - Properties::iterator types_end = i->second.upper_bound("rdf:type"); bool is_input = false; bool is_output = false; Redland::Node* type = 0; - for (Properties::iterator t = types_begin; t != types_end; ++t) { + for (Properties::iterator t = types_range.first; t != types_range.second; ++t) { if (t->second.to_string() == NS_LV2 "InputPort") { is_input = true; } else if (t->second.to_string() == NS_LV2 "OutputPort") { @@ -624,11 +631,9 @@ Parser::parse_patch( cerr << "ERROR: Corrupt patch port" << endl; continue; } - const string type_str = world->rdf_world->prefixes().qualify(type->to_string()); - target->new_port(port_path, type_str, 0, is_output); - for (Properties::iterator j = i->second.begin(); j != i->second.end(); ++j) { - target->set_property(port_path, j->first, AtomRDF::node_to_atom(j->second)); - } + + cerr << "FIXME: PARSE PATCH" << endl; + //target->put(port_path, i->second); } parse_connections(world, target, model, subject, "/"); @@ -685,7 +690,12 @@ Parser::parse_node( return boost::optional(); } - target->new_node(path, world->rdf_world->expand_uri(plugin_node.to_c_string())); + const string plugin_uri = world->rdf_world->expand_uri(plugin_node.to_c_string()); + 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, plugin_uri))); + target->put(path, props); + parse_variables(world, target, model, subject, path, data); return path; } @@ -700,6 +710,7 @@ Parser::parse_port( const Raul::Path& path, boost::optional data) { +#if 0 const Glib::ustring subject = subject_node.to_turtle_token(); Redland::Query query(*world->rdf_world, Glib::ustring( @@ -728,6 +739,9 @@ Parser::parse_port( parse_variables(world, target, model, subject_node, path, data); return path; +#endif + cerr << "PARSE PORT" << endl; + return boost::optional(); } diff --git a/src/serialisation/Serialiser.cpp b/src/serialisation/Serialiser.cpp index 286873e8..ac18455e 100644 --- a/src/serialisation/Serialiser.cpp +++ b/src/serialisation/Serialiser.cpp @@ -56,6 +56,9 @@ namespace Ingen { namespace Serialisation { +#define META_PREFIX "#" + + Serialiser::Serialiser(Shared::World& world, SharedPtr store) : _root_path("/") , _store(store) @@ -247,7 +250,7 @@ Serialiser::class_rdf_node(const Path& path) return Redland::Resource(_model->world(), _base_uri); else return Redland::Resource(_model->world(), - string("#") + path.substr(_root_path.base().length())); + string(META_PREFIX) + path.relative_to_base(_root_path).chop_start("/")); } @@ -263,7 +266,8 @@ Serialiser::serialise(SharedPtr object) throw (std::logic_error) const Redland::Resource patch_id(_model->world(), _base_uri); serialise_patch(patch, patch_id); } else { - const Redland::Resource patch_id(_model->world(), string("#") + patch->path().substr(1)); + const Redland::Resource patch_id(_model->world(), + string(META_PREFIX) + patch->path().chop_start("/")); serialise_patch(patch, patch_id); serialise_node(patch, patch_id, instance_rdf_node(patch->path())); } @@ -323,7 +327,8 @@ Serialiser::serialise_patch(SharedPtr patch, const Redland::Node& SharedPtr patch = PtrCast(n->second); SharedPtr node = PtrCast(n->second); if (patch) { - const Redland::Resource class_id(_model->world(),string("#") + patch->path().substr(1)); + const Redland::Resource class_id(_model->world(), + string(META_PREFIX) + patch->path().chop_start("/")); const Redland::Node node_id(instance_rdf_node(n->second->path())); _model->add_statement(patch_id, "ingen:node", node_id); serialise_patch(patch, class_id); diff --git a/src/shared/Builder.cpp b/src/shared/Builder.cpp index 45c4badf..ba26d962 100644 --- a/src/shared/Builder.cpp +++ b/src/shared/Builder.cpp @@ -25,6 +25,7 @@ #include "common/interface/Plugin.hpp" using namespace std; +using namespace Raul; namespace Ingen { namespace Shared { @@ -41,8 +42,12 @@ Builder::build(SharedPtr object) { SharedPtr patch = PtrCast(object); if (patch) { - if (!object->path().is_root()) - _interface.new_patch(object->path(), patch->internal_polyphony()); + if (!object->path().is_root()) { + Resource::Properties props; + props.insert(make_pair("rdf:type", Atom(Atom::URI, "ingen:Patch"))); + props.insert(make_pair("ingen:polyphony", Atom(int32_t(patch->internal_polyphony())))); + _interface.put(object->path(), props); + } build_object(object); /*for (Patch::Connections::const_iterator i = patch->connections().begin(); @@ -54,16 +59,17 @@ Builder::build(SharedPtr object) SharedPtr node = PtrCast(object); if (node) { - Raul::Path path = node->path(); - _interface.new_node(path, node->plugin()->uri()); + Resource::Properties props; + props.insert(make_pair("rdf:type", Atom(Atom::URI, "ingen:Node"))); + props.insert(make_pair("rdf:instanceOf", Atom(Atom::URI, node->plugin()->uri().str()))); + _interface.put(node->path(), props); build_object(object); return; } SharedPtr port = PtrCast(object); if (port) { - Raul::Path path = port->path(); - _interface.new_port(path, port->type().uri(), port->index(), !port->is_input()); + _interface.put(port->path(), port->properties()); build_object(object); return; } diff --git a/src/shared/ClashAvoider.cpp b/src/shared/ClashAvoider.cpp index 1fd2124c..e553364b 100644 --- a/src/shared/ClashAvoider.cpp +++ b/src/shared/ClashAvoider.cpp @@ -142,37 +142,11 @@ ClashAvoider::exists(const Raul::Path& path) const } -bool -ClashAvoider::new_object(const GraphObject* object) -{ - return false; -} - - -void -ClashAvoider::new_patch(const Raul::Path& path, - uint32_t poly) -{ - if (!path.is_root()) - _target.new_patch(map_path(path), poly); -} - - -void -ClashAvoider::new_node(const Raul::Path& path, - const Raul::URI& plugin_uri) -{ - _target.new_node(map_path(path), plugin_uri); -} - - void -ClashAvoider::new_port(const Raul::Path& path, - const Raul::URI& type, - uint32_t index, - bool is_output) +ClashAvoider::put(const Raul::Path& path, + const Shared::Resource::Properties& properties) { - _target.new_port(map_path(path), type, index, is_output); + _target.put(map_path(path), properties); } diff --git a/src/shared/ClashAvoider.hpp b/src/shared/ClashAvoider.hpp index 376738a3..007331bc 100644 --- a/src/shared/ClashAvoider.hpp +++ b/src/shared/ClashAvoider.hpp @@ -48,18 +48,8 @@ public: // Object commands - virtual bool new_object(const GraphObject* object); - - virtual void new_patch(const Raul::Path& path, - uint32_t poly); - - virtual void new_node(const Raul::Path& path, - const Raul::URI& plugin_uri); - - virtual void new_port(const Raul::Path& path, - const Raul::URI& type, - uint32_t index, - bool is_output); + virtual void put(const Raul::Path& path, + const Resource::Properties& properties); virtual void rename(const Raul::Path& old_path, const Raul::Path& new_path); diff --git a/src/shared/ResourceImpl.cpp b/src/shared/ResourceImpl.cpp index 20a44167..27a33e07 100644 --- a/src/shared/ResourceImpl.cpp +++ b/src/shared/ResourceImpl.cpp @@ -18,18 +18,36 @@ #include "raul/Atom.hpp" #include "ResourceImpl.hpp" +using namespace std; +using namespace Raul; + namespace Ingen { namespace Shared { void -ResourceImpl::set_property(const Raul::URI& uri, const Raul::Atom& value) +ResourceImpl::add_property(const Raul::URI& uri, const Raul::Atom& value) { - _properties[uri] = value; + // Ignore duplicate statements + typedef Resource::Properties::const_iterator iterator; + const std::pair range = _properties.equal_range(uri); + for (iterator i = range.first; i != range.second; ++i) + if (i->second == value) + return; + + _properties.insert(make_pair(uri, value)); signal_property.emit(uri, value); } +void +ResourceImpl::set_property(const Raul::URI& uri, const Raul::Atom& value) +{ + _properties.erase(uri); + _properties.insert(make_pair(uri, value)); +} + + const Raul::Atom& ResourceImpl::get_property(const Raul::URI& uri) const { @@ -39,5 +57,73 @@ ResourceImpl::get_property(const Raul::URI& uri) const } +bool +ResourceImpl::type( + const Properties& properties, + bool& patch, + bool& node, + bool& port, bool& is_output, DataType& data_type) +{ + typedef Resource::Properties::const_iterator iterator; + const std::pair types_range = properties.equal_range("rdf:type"); + + patch = node = port = is_output = false; + data_type = DataType::UNKNOWN; + for (iterator i = types_range.first; i != types_range.second; ++i) { + const Atom& atom = i->second; + if (atom.type() == Atom::URI) { + if (!strncmp(atom.get_uri(), "ingen:", 6)) { + const char* suffix = atom.get_uri() + 6; + if (!strcmp(suffix, "Patch")) { + patch = true; + } else if (!strcmp(suffix, "Node")) { + node = true; + } + } else if (!strncmp(atom.get_uri(), "lv2:", 4)) { + const char* suffix = atom.get_uri() + 4; + port = true; + if (!strcmp(suffix, "InputPort")) { + is_output = false; + port = true; + } else if (!strcmp(suffix, "OutputPort")) { + is_output = true; + port = true; + } else if (!strcmp(suffix, "AudioPort")) { + data_type = DataType::AUDIO; + port = true; + } else if (!strcmp(suffix, "ControlPort")) { + data_type = DataType::CONTROL; + port = true; + } + } else if (!strcmp(atom.get_uri(), "lv2ev:EventPort")) { + data_type = DataType::EVENT; + port = true; + } + } + } + + if (patch && node && !port) { // => patch + node = false; + return true; + } else if (port && (patch || node)) { // nonsense + port = false; + return false; + } else if (patch || node || port) { // recognized type + return true; + } else { // unknown + return false; + } +} + + +void +ResourceImpl::merge_properties(const Properties& p) +{ + typedef Resource::Properties::const_iterator iterator; + for (iterator i = p.begin(); i != p.end(); ++i) + set_property(i->first, i->second); +} + + } // namespace Shared } // namespace Ingen diff --git a/src/shared/ResourceImpl.hpp b/src/shared/ResourceImpl.hpp index 059e3844..b436ddc9 100644 --- a/src/shared/ResourceImpl.hpp +++ b/src/shared/ResourceImpl.hpp @@ -22,11 +22,11 @@ #include #include "raul/URI.hpp" #include "interface/Resource.hpp" +#include "interface/DataType.hpp" namespace Ingen { namespace Shared { - class ResourceImpl : virtual public Resource { public: @@ -39,6 +39,19 @@ 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); + + /** Get the ingen type from a set of Properties. + * If some coherent ingen type is found, true is returned and the appropriate + * output parameter set to true. Otherwise false is returned. + */ + static bool type( + const Properties& properties, + bool& patch, + bool& node, + bool& port, bool& is_output, DataType& data_type); + + void merge_properties(const Properties& p); sigc::signal signal_property; -- cgit v1.2.1