From f02ac2f82a0342c3e548a81950734b4bce383b7d Mon Sep 17 00:00:00 2001 From: David Robillard Date: Fri, 29 Jan 2010 07:58:13 +0000 Subject: Improved/quicker/easier handling of control port ranges. * Add "Set minimum to current value", "Set maximum to current value", and "Reset range" to control port context menu. * Only serialise properties (e.g. lv2:minimum) if they differ from the meta object's (prototype's, e.g. plugin) value. git-svn-id: http://svn.drobilla.net/lad/trunk/ingen@2395 a436a847-0d15-0410-975c-d299462d15a1 --- src/client/DeprecatedLoader.cpp | 4 +-- src/client/NodeModel.cpp | 19 ++++++++++-- src/client/NodeModel.hpp | 1 + src/common/interface/Resource.hpp | 2 +- src/engine/ControlBindings.cpp | 3 +- src/engine/HTTPClientSender.cpp | 6 ++-- src/engine/InputPort.cpp | 6 ++++ src/engine/LV2Node.cpp | 10 ++++-- src/gui/LoadPluginWindow.cpp | 4 +-- src/gui/LoadSubpatchWindow.cpp | 4 +-- src/gui/NodeMenu.cpp | 17 +++++----- src/gui/NodeModule.cpp | 12 ++++---- src/gui/PatchCanvas.cpp | 8 ++--- src/gui/PatchPortModule.cpp | 12 ++++---- src/gui/PortMenu.cpp | 65 ++++++++++++++++++++++++++++++++++++++- src/gui/PortMenu.hpp | 8 +++++ src/gui/PropertiesWindow.cpp | 8 +---- src/gui/PropertiesWindow.hpp | 3 ++ src/gui/ingen_gui.glade | 26 ++++++++++++++++ src/ingen/main.cpp | 22 ++++++------- src/serialisation/Serialiser.cpp | 28 +++++++++-------- src/serialisation/Serialiser.hpp | 5 ++- src/shared/ResourceImpl.cpp | 4 +-- src/shared/ResourceImpl.hpp | 2 +- 24 files changed, 204 insertions(+), 75 deletions(-) (limited to 'src') diff --git a/src/client/DeprecatedLoader.cpp b/src/client/DeprecatedLoader.cpp index 0b3243d1..32dd8059 100644 --- a/src/client/DeprecatedLoader.cpp +++ b/src/client/DeprecatedLoader.cpp @@ -152,9 +152,9 @@ DeprecatedLoader::add_variable(GraphObject::Properties& data, string old_key, st { string key = ""; if (old_key == "module-x") - key = "ingen-ui:canvas-x"; + key = "ingenui:canvas-x"; else if (old_key == "module-y") - key = "ingen-ui:canvas-y"; + key = "ingenui:canvas-y"; if (key != "") { // FIXME: should this overwrite existing values? diff --git a/src/client/NodeModel.cpp b/src/client/NodeModel.cpp index 07bdccf8..ea419e3a 100644 --- a/src/client/NodeModel.cpp +++ b/src/client/NodeModel.cpp @@ -170,12 +170,14 @@ NodeModel::port(uint32_t index) const void -NodeModel::port_value_range(SharedPtr port, float& min, float& max) const +NodeModel::default_port_value_range(SharedPtr port, float& min, float& max) const { - assert(port->parent().get() == this); + // Default control values + min = 0.0; + max = 1.0; + // Get range from client-side LV2 data #ifdef HAVE_SLV2 - // Plugin value first if (_plugin && _plugin->type() == PluginModel::LV2) { if (!_min_values) { @@ -196,6 +198,17 @@ NodeModel::port_value_range(SharedPtr port, float& min, float& max) c } #endif + // TODO: LADSPA support +} + + +void +NodeModel::port_value_range(SharedPtr port, float& min, float& max) const +{ + assert(port->parent().get() == this); + + default_port_value_range(port, min, max); + // Possibly overriden const Atom& min_atom = port->get_property("lv2:minimum"); const Atom& max_atom = port->get_property("lv2:maximum"); diff --git a/src/client/NodeModel.hpp b/src/client/NodeModel.hpp index b1dbb616..3c150700 100644 --- a/src/client/NodeModel.hpp +++ b/src/client/NodeModel.hpp @@ -60,6 +60,7 @@ public: uint32_t num_ports() const { return _ports.size(); } const Ports& ports() const { return _ports; } + void default_port_value_range(SharedPtr port, float& min, float& max) const; void port_value_range(SharedPtr port, float& min, float& max) const; // Signals diff --git a/src/common/interface/Resource.hpp b/src/common/interface/Resource.hpp index 4f3e6128..bc7ea7dd 100644 --- a/src/common/interface/Resource.hpp +++ b/src/common/interface/Resource.hpp @@ -45,7 +45,7 @@ public: virtual const Raul::Atom& get_property(const Raul::URI& uri) const = 0; - virtual bool has_property(const Raul::URI& uri, const Raul::Atom& value) = 0; + virtual bool has_property(const Raul::URI& uri, const Raul::Atom& value) const = 0; }; diff --git a/src/engine/ControlBindings.cpp b/src/engine/ControlBindings.cpp index 2c2a1888..2874fa05 100644 --- a/src/engine/ControlBindings.cpp +++ b/src/engine/ControlBindings.cpp @@ -75,8 +75,7 @@ ControlBindings::remove(const Raul::Path& path) { ThreadManager::assert_thread(THREAD_PRE_PROCESS); - SharedPtr old_bindings = _bindings; - + SharedPtr old_bindings(_bindings); SharedPtr copy(new Bindings(*_bindings.get())); for (Bindings::iterator i = copy->begin(); i != copy->end();) { diff --git a/src/engine/HTTPClientSender.cpp b/src/engine/HTTPClientSender.cpp index 0c14b06f..aacf9479 100644 --- a/src/engine/HTTPClientSender.cpp +++ b/src/engine/HTTPClientSender.cpp @@ -104,9 +104,9 @@ HTTPClientSender::set_property(const URI& subject, const URI& key, const Atom& v { Redland::Node node = AtomRDF::atom_to_node(*_engine.world()->rdf_world, value); const string msg = string( - "@prefix rdf: .\n" - "@prefix ingen: .\n" - "@prefix ingen-ui: .\n").append( + "@prefix rdf: .\n" + "@prefix ingen: .\n" + "@prefix ingenui: .\n").append( subject.str()).append("> ingen:property [\n" "rdf:predicate ").append(key.str()).append(" ;\n" "rdf:value ").append(node.to_string()).append("\n] .\n"); diff --git a/src/engine/InputPort.cpp b/src/engine/InputPort.cpp index 010fdd93..80ae836d 100644 --- a/src/engine/InputPort.cpp +++ b/src/engine/InputPort.cpp @@ -49,6 +49,12 @@ InputPort::InputPort(BufferFactory& bufs, { if (!dynamic_cast(parent)) add_property("rdf:type", Raul::Atom(Raul::Atom::URI, "lv2:InputPort")); + + // Set default control range + if (type == PortType::CONTROL) { + set_property("lv2:minimum", 0.0f); + set_property("lv2:maximum", 1.0f); + } } diff --git a/src/engine/LV2Node.cpp b/src/engine/LV2Node.cpp index 003a6284..574a4eeb 100644 --- a/src/engine/LV2Node.cpp +++ b/src/engine/LV2Node.cpp @@ -280,8 +280,14 @@ LV2Node::instantiate(BufferFactory& bufs) if (direction == INPUT && data_type == PortType::CONTROL) { ((AudioBuffer*)port->buffer(0).get())->set_value(val.get_float(), 0, 0); - port->set_property("lv2:minimum", min_values[j]); - port->set_property("lv2:maximum", max_values[j]); + if (!isnan(min_values[j])) { + port->meta().set_property("lv2:minimum", min_values[j]); + port->set_property("lv2:minimum", min_values[j]); + } + if (!isnan(max_values[j])) { + port->meta().set_property("lv2:maximum", max_values[j]); + port->set_property("lv2:maximum", max_values[j]); + } } SLV2Values contexts = slv2_port_get_value(plug, id, context_pred); diff --git a/src/gui/LoadPluginWindow.cpp b/src/gui/LoadPluginWindow.cpp index 07605f3c..a72277b3 100644 --- a/src/gui/LoadPluginWindow.cpp +++ b/src/gui/LoadPluginWindow.cpp @@ -350,9 +350,9 @@ LoadPluginWindow::load_plugin(const Gtk::TreeModel::iterator& iter) _node_name_entry->set_text(generate_module_name(plugin, _plugin_name_offset + 1)); // Cascade next node - Atom& x = _initial_data.find("ingen-ui:canvas-x")->second; + Atom& x = _initial_data.find("ingenui:canvas-x")->second; x = Atom(x.get_float() + 20.0f); - Atom& y = _initial_data.find("ingen-ui:canvas-y")->second; + Atom& y = _initial_data.find("ingenui:canvas-y")->second; y = Atom(y.get_float() + 20.0f); } } diff --git a/src/gui/LoadSubpatchWindow.cpp b/src/gui/LoadSubpatchWindow.cpp index b2066ff6..e580fa49 100644 --- a/src/gui/LoadSubpatchWindow.cpp +++ b/src/gui/LoadSubpatchWindow.cpp @@ -165,9 +165,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.find("ingen-ui:canvas-x")->second; + Atom& x = _initial_data.find("ingenui:canvas-x")->second; x = Atom(x.get_float() + 20.0f); - Atom& y = _initial_data.find("ingen-ui:canvas-y")->second; + Atom& y = _initial_data.find("ingenui:canvas-y")->second; y = Atom(y.get_float() + 20.0f); App::instance().loader()->load_patch(false, *i, Path("/"), diff --git a/src/gui/NodeMenu.cpp b/src/gui/NodeMenu.cpp index f676ed79..887ef06a 100644 --- a/src/gui/NodeMenu.cpp +++ b/src/gui/NodeMenu.cpp @@ -42,16 +42,19 @@ NodeMenu::NodeMenu(BaseObjectType* cobject, const Glib::RefPtrget_widget("node_embed_gui_menuitem", _embed_gui_menuitem); xml->get_widget("node_randomize_menuitem", _randomize_menuitem); - node_menu->remove(*_controls_menuitem); - node_menu->remove(*_popup_gui_menuitem); - node_menu->remove(*_embed_gui_menuitem); - node_menu->remove(*_randomize_menuitem); + items().push_front(Gtk::Menu_Helpers::SeparatorElem()); + node_menu->remove(*_randomize_menuitem); insert(*_randomize_menuitem, 0); - items().push_front(Gtk::Menu_Helpers::SeparatorElem()); - insert(*_controls_menuitem, 0); - insert(*_popup_gui_menuitem, 0); + + node_menu->remove(*_embed_gui_menuitem); insert(*_embed_gui_menuitem, 0); + + node_menu->remove(*_popup_gui_menuitem); + insert(*_popup_gui_menuitem, 0); + + node_menu->remove(*_controls_menuitem); + insert(*_controls_menuitem, 0); } diff --git a/src/gui/NodeModule.cpp b/src/gui/NodeModule.cpp index 69b8eb55..d9680237 100644 --- a/src/gui/NodeModule.cpp +++ b/src/gui/NodeModule.cpp @@ -379,14 +379,14 @@ NodeModule::store_location() const float x = static_cast(property_x()); const float y = static_cast(property_y()); - const Atom& existing_x = _node->get_property("ingen-ui:canvas-x"); - const Atom& existing_y = _node->get_property("ingen-ui:canvas-y"); + const Atom& existing_x = _node->get_property("ingenui:canvas-x"); + const Atom& existing_y = _node->get_property("ingenui:canvas-y"); if (existing_x.type() != Atom::FLOAT || existing_y.type() != Atom::FLOAT || existing_x.get_float() != x || existing_y.get_float() != y) { Shared::Resource::Properties props; - props.insert(make_pair("ingen-ui:canvas-x", Atom(x))); - props.insert(make_pair("ingen-ui:canvas-y", Atom(y))); + props.insert(make_pair("ingenui:canvas-x", Atom(x))); + props.insert(make_pair("ingenui:canvas-y", Atom(y))); App::instance().engine()->put(_node->path(), props); } } @@ -397,9 +397,9 @@ NodeModule::set_property(const URI& key, const Atom& value) { switch (value.type()) { case Atom::FLOAT: - if (key.str() == "ingen-ui:canvas-x") { + if (key.str() == "ingenui:canvas-x") { move_to(value.get_float(), property_y()); - } else if (key.str() == "ingen-ui:canvas-y") { + } else if (key.str() == "ingenui:canvas-y") { move_to(property_x(), value.get_float()); } break; diff --git a/src/gui/PatchCanvas.cpp b/src/gui/PatchCanvas.cpp index c56c965a..6e7374d0 100644 --- a/src/gui/PatchCanvas.cpp +++ b/src/gui/PatchCanvas.cpp @@ -685,10 +685,10 @@ PatchCanvas::paste() for (Store::iterator i = clipboard.begin(); i != clipboard.end(); ++i) { if (_patch->path().is_root() && i->first.is_root()) continue; - GraphObject::Properties::iterator x = i->second->properties().find("ingen-ui:canvas-x"); + GraphObject::Properties::iterator x = i->second->properties().find("ingenui:canvas-x"); if (x != i->second->properties().end()) x->second = x->second.get_float() + (20.0f * _paste_count); - GraphObject::Properties::iterator y = i->second->properties().find("ingen-ui:canvas-y"); + GraphObject::Properties::iterator y = i->second->properties().find("ingenui:canvas-y"); if (y != i->second->properties().end()) y->second = y->second.get_float() + (20.0f * _paste_count); if (i->first.parent().is_root()) { @@ -794,8 +794,8 @@ GraphObject::Properties PatchCanvas::get_initial_data() { GraphObject::Properties result; - result.insert(make_pair("ingen-ui:canvas-x", Atom((float)_last_click_x))); - result.insert(make_pair("ingen-ui:canvas-y", Atom((float)_last_click_y))); + result.insert(make_pair("ingenui:canvas-x", Atom((float)_last_click_x))); + result.insert(make_pair("ingenui:canvas-y", Atom((float)_last_click_y))); return result; } diff --git a/src/gui/PatchPortModule.cpp b/src/gui/PatchPortModule.cpp index 236a6250..6981f2ef 100644 --- a/src/gui/PatchPortModule.cpp +++ b/src/gui/PatchPortModule.cpp @@ -97,14 +97,14 @@ PatchPortModule::store_location() const float x = static_cast(property_x()); const float y = static_cast(property_y()); - const Atom& existing_x = _model->get_property("ingen-ui:canvas-x"); - const Atom& existing_y = _model->get_property("ingen-ui:canvas-y"); + const Atom& existing_x = _model->get_property("ingenui:canvas-x"); + const Atom& existing_y = _model->get_property("ingenui:canvas-y"); if (existing_x.type() != Atom::FLOAT || existing_y.type() != Atom::FLOAT || existing_x.get_float() != x || existing_y.get_float() != y) { Shared::Resource::Properties props; - props.insert(make_pair("ingen-ui:canvas-x", Atom(x))); - props.insert(make_pair("ingen-ui:canvas-y", Atom(y))); + props.insert(make_pair("ingenui:canvas-x", Atom(x))); + props.insert(make_pair("ingenui:canvas-y", Atom(y))); App::instance().engine()->put(_model->meta_uri(), props); } } @@ -138,9 +138,9 @@ PatchPortModule::set_property(const URI& key, const Atom& value) { switch (value.type()) { case Atom::FLOAT: - if (key.str() == "ingen-ui:canvas-x") { + if (key.str() == "ingenui:canvas-x") { move_to(value.get_float(), property_y()); - } else if (key.str() == "ingen-ui:canvas-y") { + } else if (key.str() == "ingenui:canvas-y") { move_to(property_x(), value.get_float()); } break; diff --git a/src/gui/PortMenu.cpp b/src/gui/PortMenu.cpp index 3cb8c071..4a6ce582 100644 --- a/src/gui/PortMenu.cpp +++ b/src/gui/PortMenu.cpp @@ -32,6 +32,10 @@ PortMenu::PortMenu(BaseObjectType* cobject, const Glib::RefPtrget_widget("port_menu", _port_menu); + xml->get_widget("port_set_min_menuitem", _set_min_menuitem); + xml->get_widget("port_set_max_menuitem", _set_max_menuitem); + xml->get_widget("port_reset_range_menuitem", _reset_range_menuitem); } @@ -41,6 +45,15 @@ PortMenu::init(SharedPtr port, bool patch_port) ObjectMenu::init(port); _patch_port = patch_port; + _set_min_menuitem->signal_activate().connect(sigc::mem_fun(this, + &PortMenu::on_menu_set_min)); + + _set_max_menuitem->signal_activate().connect(sigc::mem_fun(this, + &PortMenu::on_menu_set_max)); + + _reset_range_menuitem->signal_activate().connect(sigc::mem_fun(this, + &PortMenu::on_menu_reset_range)); + if ( ! PtrCast(port->parent()) ) { _polyphonic_menuitem->set_sensitive(false); _rename_menuitem->hide(); @@ -50,9 +63,21 @@ PortMenu::init(SharedPtr port, bool patch_port) if (port->type() == PortType::EVENTS) _polyphonic_menuitem->hide(); - if (port->type() == PortType::CONTROL) + if (port->type() == PortType::CONTROL) { _learn_menuitem->show(); + items().push_front(Gtk::Menu_Helpers::SeparatorElem()); + + _port_menu->remove(*_reset_range_menuitem); + insert(*_reset_range_menuitem, 0); + + _port_menu->remove(*_set_max_menuitem); + insert(*_set_max_menuitem, 0); + + _port_menu->remove(*_set_min_menuitem); + insert(*_set_min_menuitem, 0); + } + _enable_signal = true; } @@ -70,6 +95,44 @@ PortMenu::on_menu_disconnect() } +void +PortMenu::on_menu_set_min() +{ + SharedPtr model = PtrCast(_object); + const Raul::Atom& value = model->get_property("ingen:value"); + std::cout << model->path() << " SET MIN " << value << std::endl; + if (value.is_valid()) + App::instance().engine()->set_property(_object->path(), "lv2:minimum", value); +} + + +void +PortMenu::on_menu_set_max() +{ + SharedPtr model = PtrCast(_object); + const Raul::Atom& value = model->get_property("ingen:value"); + if (value.is_valid()) + App::instance().engine()->set_property(_object->path(), "lv2:maximum", value); +} + + +void +PortMenu::on_menu_reset_range() +{ + SharedPtr model = PtrCast(_object); + SharedPtr parent = PtrCast(_object->parent()); + + float min, max; + parent->default_port_value_range(model, min, max); + + if (!isnan(min)) + App::instance().engine()->set_property(_object->path(), "lv2:minimum", min); + + if (!isnan(max)) + App::instance().engine()->set_property(_object->path(), "lv2:maximum", max); +} + + } // namespace GUI } // namespace Ingen diff --git a/src/gui/PortMenu.hpp b/src/gui/PortMenu.hpp index 44c6d5b6..61ff1cc5 100644 --- a/src/gui/PortMenu.hpp +++ b/src/gui/PortMenu.hpp @@ -43,8 +43,16 @@ public: private: void on_menu_disconnect(); + void on_menu_set_min(); + void on_menu_set_max(); + void on_menu_reset_range(); bool _patch_port; + + Gtk::Menu* _port_menu; + Gtk::MenuItem* _set_min_menuitem; + Gtk::MenuItem* _set_max_menuitem; + Gtk::MenuItem* _reset_range_menuitem; }; diff --git a/src/gui/PropertiesWindow.cpp b/src/gui/PropertiesWindow.cpp index 95ca1d7c..51ca4817 100644 --- a/src/gui/PropertiesWindow.cpp +++ b/src/gui/PropertiesWindow.cpp @@ -99,18 +99,12 @@ PropertiesWindow::set_object(SharedPtr model) align->add(*combo); _table->attach(*align, 1, 2, n_rows, n_rows + 1, Gtk::FILL|Gtk::SHRINK, Gtk::SHRINK); - Record record; - record.value = value; - record.type_widget = combo; - // Column 2: Value align = manage(new Gtk::Alignment(0.0, 0.5, 1.0, 0.0)); Gtk::Widget* value_widget = create_value_widget(i->first, value); align->add(*value_widget); _table->attach(*align, 2, 3, n_rows, n_rows + 1, Gtk::FILL|Gtk::EXPAND, Gtk::SHRINK); - record.value_widget = align; - record.row = n_rows; - _records.insert(make_pair(i->first, record)); + _records.insert(make_pair(i->first, Record(value, combo, align, n_rows))); } _table->show_all(); diff --git a/src/gui/PropertiesWindow.hpp b/src/gui/PropertiesWindow.hpp index d2f619f9..2511e78a 100644 --- a/src/gui/PropertiesWindow.hpp +++ b/src/gui/PropertiesWindow.hpp @@ -47,6 +47,9 @@ public: private: /** Record of a property (row in the table) */ struct Record { + Record(const Raul::Atom& v, Gtk::ComboBox* tw, Gtk::Alignment* vw, int r) + : value(v), type_widget(tw), value_widget(vw), row(r) + {} Raul::Atom value; Gtk::ComboBox* type_widget; Gtk::Alignment* value_widget; diff --git a/src/gui/ingen_gui.glade b/src/gui/ingen_gui.glade index ad84483f..1e297c12 100644 --- a/src/gui/ingen_gui.glade +++ b/src/gui/ingen_gui.glade @@ -3262,4 +3262,30 @@ Thank you for contributing. + + True + GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK + + + True + Set m_inimum to current value + True + + + + + True + Set m_aximum to current value + True + + + + + True + Reset range to plugin defaults + R_eset Range + True + + + diff --git a/src/ingen/main.cpp b/src/ingen/main.cpp index 7a6586c8..52d36c70 100644 --- a/src/ingen/main.cpp +++ b/src/ingen/main.cpp @@ -123,17 +123,17 @@ main(int argc, char** argv) world->conf = &conf; // Set up RDF namespaces - world->rdf_world->add_prefix("dc", "http://purl.org/dc/elements/1.1/"); - world->rdf_world->add_prefix("doap", "http://usefulinc.com/ns/doap#"); - world->rdf_world->add_prefix("ingen", "http://drobilla.net/ns/ingen#"); - world->rdf_world->add_prefix("ingen-ui", "http://drobilla.net/ns/ingenuity#"); - world->rdf_world->add_prefix("lv2", "http://lv2plug.in/ns/lv2core#"); - world->rdf_world->add_prefix("lv2ev", "http://lv2plug.in/ns/ext/event#"); - world->rdf_world->add_prefix("lv2midi", "http://lv2plug.in/ns/ext/midi#"); - world->rdf_world->add_prefix("owl", "http://www.w3.org/2002/07/owl#"); - world->rdf_world->add_prefix("rdfs", "http://www.w3.org/2000/01/rdf-schema#"); - world->rdf_world->add_prefix("sp", "http://lv2plug.in/ns/dev/string-port#"); - world->rdf_world->add_prefix("xsd", "http://www.w3.org/2001/XMLSchema#"); + world->rdf_world->add_prefix("dc", "http://purl.org/dc/elements/1.1/"); + world->rdf_world->add_prefix("doap", "http://usefulinc.com/ns/doap#"); + world->rdf_world->add_prefix("ingen", "http://drobilla.net/ns/ingen#"); + world->rdf_world->add_prefix("ingenui", "http://drobilla.net/ns/ingenuity#"); + world->rdf_world->add_prefix("lv2", "http://lv2plug.in/ns/lv2core#"); + world->rdf_world->add_prefix("lv2ev", "http://lv2plug.in/ns/ext/event#"); + world->rdf_world->add_prefix("lv2midi", "http://lv2plug.in/ns/ext/midi#"); + world->rdf_world->add_prefix("owl", "http://www.w3.org/2002/07/owl#"); + world->rdf_world->add_prefix("rdfs", "http://www.w3.org/2000/01/rdf-schema#"); + world->rdf_world->add_prefix("sp", "http://lv2plug.in/ns/dev/string-port#"); + world->rdf_world->add_prefix("xsd", "http://www.w3.org/2001/XMLSchema#"); // Run engine if (conf.option("engine").get_bool()) { diff --git a/src/serialisation/Serialiser.cpp b/src/serialisation/Serialiser.cpp index 18a6d9d9..97b84e4e 100644 --- a/src/serialisation/Serialiser.cpp +++ b/src/serialisation/Serialiser.cpp @@ -44,6 +44,7 @@ #include "interface/Node.hpp" #include "interface/Port.hpp" #include "interface/Connection.hpp" +#include "shared/ResourceImpl.hpp" #include "Serialiser.hpp" #define LOG(s) s << "[Serialiser] " @@ -318,7 +319,7 @@ Serialiser::serialise_patch(SharedPtr patch, const Redland::Node& LOG(warn) << "Patch has no lv2:symbol" << endl; } - serialise_properties(patch_id, patch->meta().properties()); + serialise_properties(patch_id, NULL, patch->meta().properties()); for (Store::const_iterator n = _store->children_begin(patch); n != _store->children_end(patch); ++n) { @@ -358,7 +359,7 @@ Serialiser::serialise_patch(SharedPtr patch, const Redland::Node& _model->add_statement(patch_id, "lv2:port", port_id); serialise_port_meta(p, port_id); if (root) - serialise_properties(port_id, p->properties()); + serialise_properties(port_id, &p->meta(), p->properties()); } for (Shared::Patch::Connections::const_iterator c = patch->connections().begin(); @@ -391,7 +392,7 @@ Serialiser::serialise_node(SharedPtr node, _model->add_statement(node_id, "lv2:symbol", Redland::Literal(_model->world(), node->path().name())); - serialise_properties(node_id, node->properties()); + serialise_properties(node_id, &node->meta(), node->properties()); for (uint32_t i=0; i < node->num_ports(); ++i) { Port* p = node->port(i); @@ -424,7 +425,7 @@ Serialiser::serialise_port(const Port* port, const Redland::Node& port_id) _model->add_statement(port_id, "ingen:value", AtomRDF::atom_to_node(_model->world(), port->value())); - serialise_properties(port_id, port->properties()); + serialise_properties(port_id, &port->meta(), port->properties()); } @@ -456,7 +457,7 @@ Serialiser::serialise_port_meta(const Port* port, const Redland::Node& port_id) } } - serialise_properties(port_id, port->meta().properties()); + serialise_properties(port_id, NULL, port->meta().properties()); } @@ -491,17 +492,20 @@ Serialiser::serialise_connection(SharedPtr parent, void Serialiser::serialise_properties( Redland::Node subject, + const Shared::Resource* meta, const GraphObject::Properties& properties) { for (GraphObject::Properties::const_iterator v = properties.begin(); v != properties.end(); ++v) { if (v->second.is_valid()) { - const Redland::Resource key(_model->world(), v->first.str()); - const Redland::Node value = AtomRDF::atom_to_node(_model->world(), v->second); - if (value.is_valid()) { - _model->add_statement(subject, key, value); - } else { - LOG(warn) << "Can not serialise variable '" << v->first << "' :: " - << (int)v->second.type() << endl; + if (!meta || !meta->has_property(v->first.str(), v->second)) { + const Redland::Resource key(_model->world(), v->first.str()); + const Redland::Node value(AtomRDF::atom_to_node(_model->world(), v->second)); + if (value.is_valid()) { + _model->add_statement(subject, key, value); + } else { + LOG(warn) << "Can not serialise variable '" << v->first << "' :: " + << (int)v->second.type() << endl; + } } } else { LOG(warn) << "Property '" << v->first << "' has no value" << endl; diff --git a/src/serialisation/Serialiser.hpp b/src/serialisation/Serialiser.hpp index 4264f05e..2515417e 100644 --- a/src/serialisation/Serialiser.hpp +++ b/src/serialisation/Serialiser.hpp @@ -100,7 +100,10 @@ private: void serialise_port_meta(const Shared::Port* p, const Redland::Node& id); void serialise_meta_properties(Redland::Node subject, const Properties& properties); - void serialise_properties(Redland::Node subject, const Properties& variables); + void serialise_properties( + Redland::Node subject, + const Shared::Resource* meta, + const Properties& properties); Redland::Node instance_rdf_node(const Raul::Path& path); Redland::Node class_rdf_node(const Raul::Path& path); diff --git a/src/shared/ResourceImpl.cpp b/src/shared/ResourceImpl.cpp index 949a8b36..625e8c17 100644 --- a/src/shared/ResourceImpl.cpp +++ b/src/shared/ResourceImpl.cpp @@ -63,10 +63,10 @@ ResourceImpl::set_property(const Raul::URI& uri, const Raul::Atom& value) bool -ResourceImpl::has_property(const Raul::URI& uri, const Raul::Atom& value) +ResourceImpl::has_property(const Raul::URI& uri, const Raul::Atom& value) const { Properties::const_iterator i = _properties.find(uri); - for (; i->first == uri; ++i) { + for (; (i != _properties.end()) && (i->first == uri); ++i) { if (i->second == value) { return true; } diff --git a/src/shared/ResourceImpl.hpp b/src/shared/ResourceImpl.hpp index 7ff88f6a..9cb40521 100644 --- a/src/shared/ResourceImpl.hpp +++ b/src/shared/ResourceImpl.hpp @@ -40,7 +40,7 @@ public: const Raul::Atom& get_property(const Raul::URI& uri) const; Raul::Atom& set_property(const Raul::URI& uri, const Raul::Atom& value); - bool has_property(const Raul::URI& uri, const Raul::Atom& value); + bool has_property(const Raul::URI& uri, const Raul::Atom& value) const; void add_property(const Raul::URI& uri, const Raul::Atom& value); void set_properties(const Properties& p); void add_properties(const Properties& p); -- cgit v1.2.1