From a645d2b8be4d7d31f6eef1649156b166a01e0c31 Mon Sep 17 00:00:00 2001 From: David Robillard Date: Tue, 2 Feb 2010 20:37:50 +0000 Subject: Use Glib string interning (quarks) to make Path/URI operator== very fast. This avoids a ton of string comparison overhead in Ingen when setting various properties (e.g. "ingen:value" was compared several times every time a port value was changed, now this is just a single pointer comparison and the full round trip of a value change does no string comparison at all, but is still property based and RDFey). git-svn-id: http://svn.drobilla.net/lad/trunk/ingen@2408 a436a847-0d15-0410-975c-d299462d15a1 --- src/client/ClientStore.cpp | 11 ++++++++--- src/client/DeprecatedLoader.cpp | 6 +++--- src/client/HTTPClientReceiver.cpp | 2 +- src/client/NodeModel.cpp | 9 ++++----- src/client/NodeModel.hpp | 13 +++++++------ src/client/ObjectModel.cpp | 11 ++++++++--- src/client/ObjectModel.hpp | 12 ++++++++---- src/client/PatchModel.cpp | 8 +++++--- src/client/PluginModel.cpp | 22 ++++++++++++---------- src/client/PluginUI.cpp | 15 +++++++-------- src/client/PortModel.cpp | 17 +++++++++++++++++ src/client/PortModel.hpp | 13 ++----------- 12 files changed, 82 insertions(+), 57 deletions(-) (limited to 'src/client') diff --git a/src/client/ClientStore.cpp b/src/client/ClientStore.cpp index 762bb2e6..eb42f6a9 100644 --- a/src/client/ClientStore.cpp +++ b/src/client/ClientStore.cpp @@ -313,9 +313,14 @@ ClientStore::put(const URI& uri, const Resource::Properties& properties) } else if (is_port) { if (data_type != PortType::UNKNOWN) { PortModel::Direction pdir = is_output ? PortModel::OUTPUT : PortModel::INPUT; - SharedPtr p(new PortModel(path, 0, data_type, pdir)); - p->set_properties(properties); - add_object(p); + const Resource::Properties::const_iterator i = properties.find("lv2:index"); + if (i != properties.end() && i->second.type() == Atom::INT) { + SharedPtr p(new PortModel(path, i->second.get_int32(), data_type, pdir)); + p->set_properties(properties); + add_object(p); + } else { + LOG(error) << "Port " << path << " has no index" << endl; + } } else { LOG(warn) << "Port " << path << " has no type" << endl; } diff --git a/src/client/DeprecatedLoader.cpp b/src/client/DeprecatedLoader.cpp index 9af1a781..ec603760 100644 --- a/src/client/DeprecatedLoader.cpp +++ b/src/client/DeprecatedLoader.cpp @@ -174,7 +174,7 @@ DeprecatedLoader::add_variable(GraphObject::Properties& data, string old_key, st if (endptr != c_val && *endptr == '\0') data.insert(make_pair(key, Atom(fval))); else - data.insert(make_pair(key, Atom(Atom::STRING, value))); + data.insert(make_pair(key, value)); free(c_val); } @@ -210,7 +210,7 @@ DeprecatedLoader::load_patch(const Glib::ustring& filename, bool merge, boost::optional parent_path, boost::optional name, - GraphObject::Properties initial_data, + GraphObject::Properties initial_data, bool existing) { LOG(info) << "Loading patch " << filename << " under " @@ -220,7 +220,7 @@ DeprecatedLoader::load_patch(const Glib::ustring& filename, if (parent_path) path = *parent_path; if (name) - path = path.base() + *name; + path = path.child(*name); size_t poly = 0; diff --git a/src/client/HTTPClientReceiver.cpp b/src/client/HTTPClientReceiver.cpp index 308b631b..c4eb2416 100644 --- a/src/client/HTTPClientReceiver.cpp +++ b/src/client/HTTPClientReceiver.cpp @@ -181,7 +181,7 @@ HTTPClientReceiver::message_callback(SoupSession* session, SoupMessage* msg, voi return; } - if (path == Path::root_uri) { + if (path == Path::root.str()) { me->_target->response_ok(0); } else if (path == "/plugins") { diff --git a/src/client/NodeModel.cpp b/src/client/NodeModel.cpp index ea419e3a..df72c9e2 100644 --- a/src/client/NodeModel.cpp +++ b/src/client/NodeModel.cpp @@ -119,7 +119,7 @@ NodeModel::add_child(SharedPtr c) bool NodeModel::remove_child(SharedPtr c) { - assert(c->path().is_child_of(_path)); + assert(c->path().is_child_of(path())); assert(c->parent().get() == this); //bool ret = ObjectModel::remove_child(c); @@ -137,7 +137,7 @@ void NodeModel::add_port(SharedPtr pm) { assert(pm); - assert(pm->path().is_child_of(_path)); + assert(pm->path().is_child_of(path())); assert(pm->parent().get() == this); Ports::iterator existing = find(_ports.begin(), _ports.end(), pm); @@ -151,11 +151,10 @@ NodeModel::add_port(SharedPtr pm) SharedPtr -NodeModel::get_port(const string& port_name) const +NodeModel::get_port(const Raul::Symbol& symbol) const { - assert(port_name.find("/") == string::npos); for (Ports::const_iterator i = _ports.begin(); i != _ports.end(); ++i) - if ((*i)->path().name() == port_name) + if ((*i)->symbol() == symbol) return (*i); return SharedPtr(); } diff --git a/src/client/NodeModel.hpp b/src/client/NodeModel.hpp index 3b0877d1..c1eb91e7 100644 --- a/src/client/NodeModel.hpp +++ b/src/client/NodeModel.hpp @@ -50,15 +50,16 @@ public: typedef std::vector< SharedPtr > Ports; - SharedPtr get_port(const std::string& port_name) const; + SharedPtr get_port(const Raul::Symbol& symbol) const; Shared::Port* port(uint32_t index) const; - const Raul::URI& plugin_uri() const { return _plugin_uri; } - const Shared::Plugin* plugin() const { return _plugin.get(); } - Shared::Plugin* plugin() { return _plugin.get(); } - uint32_t num_ports() const { return _ports.size(); } - const Ports& ports() const { return _ports; } + const Raul::URI& plugin_uri() const { return _plugin_uri; } + const Shared::Plugin* plugin() const { return _plugin.get(); } + Shared::Plugin* plugin() { return _plugin.get(); } + SharedPtr plugin_model() const { return _plugin; } + 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; diff --git a/src/client/ObjectModel.cpp b/src/client/ObjectModel.cpp index 7949f316..69d79d1e 100644 --- a/src/client/ObjectModel.cpp +++ b/src/client/ObjectModel.cpp @@ -17,6 +17,9 @@ #include "raul/TableImpl.hpp" #include "interface/GraphObject.hpp" +#include "module/ingen_module.hpp" +#include "module/World.hpp" +#include "shared/LV2URIMap.hpp" #include "ObjectModel.hpp" using namespace std; @@ -30,6 +33,7 @@ ObjectModel::ObjectModel(const Path& path) : ResourceImpl(path) , _meta(ResourceImpl::meta_uri(path)) , _path(path) + , _symbol((path == Path::root) ? "root" : path.symbol()) { } @@ -74,7 +78,7 @@ ObjectModel::get_property(const Raul::URI& key) const bool ObjectModel::polyphonic() const { - const Raul::Atom& polyphonic = get_property("ingen:polyphonic"); + const Raul::Atom& polyphonic = get_property(ingen_get_world()->uris->ingen_polyphonic); return (polyphonic.is_valid() && polyphonic.get_bool()); } @@ -106,7 +110,8 @@ void ObjectModel::set_path(const Raul::Path& p) { _path = p; - _meta.set_uri(ResourceImpl::meta_uri(_path)); + _symbol = p.symbol(); + _meta.set_uri(ResourceImpl::meta_uri(0)); signal_moved.emit(); } @@ -114,7 +119,7 @@ ObjectModel::set_path(const Raul::Path& p) void ObjectModel::set_parent(SharedPtr p) { - assert(p); + assert(_path.is_child_of(p->path())); _parent = p; } diff --git a/src/client/ObjectModel.hpp b/src/client/ObjectModel.hpp index 7ce19e9c..2c1fd23e 100644 --- a/src/client/ObjectModel.hpp +++ b/src/client/ObjectModel.hpp @@ -61,9 +61,9 @@ public: Resource& meta() { return _meta; } const Resource& meta() const { return _meta; } - const Raul::URI meta_uri() const { return _meta.uri(); } - const Raul::Path path() const { return _path; } - const Raul::Symbol symbol() const { return _path.name(); } + const Raul::URI& meta_uri() const { return _meta.uri(); } + const Raul::Path& path() const { return _path; } + const Raul::Symbol& symbol() const { return _symbol; } SharedPtr parent() const { return _parent; } bool polyphonic() const; @@ -89,8 +89,12 @@ protected: virtual void set(SharedPtr model); ResourceImpl _meta; - Raul::Path _path; + SharedPtr _parent; + +private: + Raul::Path _path; + Raul::Symbol _symbol; }; diff --git a/src/client/PatchModel.cpp b/src/client/PatchModel.cpp index 376a6a68..7b29b3f6 100644 --- a/src/client/PatchModel.cpp +++ b/src/client/PatchModel.cpp @@ -17,6 +17,8 @@ #include #include "raul/log.hpp" +#include "module/ingen_module.hpp" +#include "shared/LV2URIMap.hpp" #include "PatchModel.hpp" #include "NodeModel.hpp" #include "ConnectionModel.hpp" @@ -49,7 +51,7 @@ PatchModel::add_child(SharedPtr c) bool PatchModel::remove_child(SharedPtr o) { - assert(o->path().is_child_of(_path)); + assert(o->path().is_child_of(path())); assert(o->parent().get() == this); // Remove any connections which referred to this object, @@ -163,7 +165,7 @@ PatchModel::remove_connection(const Path& src_port_path, const Path& dst_port_pa bool PatchModel::enabled() const { - const Raul::Atom& enabled = get_property("ingen:enabled"); + const Raul::Atom& enabled = get_property(ingen_get_world()->uris->ingen_enabled); return (enabled.is_valid() && enabled.get_bool()); } @@ -171,7 +173,7 @@ PatchModel::enabled() const Raul::Atom& PatchModel::set_meta_property(const Raul::URI& key, const Atom& value) { - if (key.str() == "ingen:polyphony") + if (key == ingen_get_world()->uris->ingen_polyphony) _poly = value.get_int32(); return NodeModel::set_meta_property(key, value); diff --git a/src/client/PluginModel.cpp b/src/client/PluginModel.cpp index c40bb7ef..d740a3c1 100644 --- a/src/client/PluginModel.cpp +++ b/src/client/PluginModel.cpp @@ -18,9 +18,11 @@ #include #include #include -#include "ingen-config.h" #include "raul/Path.hpp" #include "raul/Atom.hpp" +#include "ingen-config.h" +#include "module/ingen_module.hpp" +#include "shared/LV2URIMap.hpp" #include "PluginModel.hpp" #include "PatchModel.hpp" #include "PluginUI.hpp" @@ -54,7 +56,7 @@ PluginModel::PluginModel(const URI& uri, const URI& type_uri, const Resource::Pr slv2_value_free(plugin_uri); #endif if (_type == Internal) - set_property("doap:name", Atom(uri.substr(uri.find_last_of("#") + 1).c_str())); + set_property("doap:name", Atom(uri.substr(uri.find_last_of('#') + 1).c_str())); } @@ -67,13 +69,13 @@ PluginModel::get_property(const URI& key) const return val; // No lv2:symbol from data or engine, invent one - if (key.str() == "lv2:symbol") { + if (key == ingen_get_world()->uris->lv2_symbol) { const URI& uri = this->uri(); - size_t last_slash = uri.find_last_of("/"); - size_t last_hash = uri.find_last_of("#"); + size_t last_slash = uri.find_last_of('/'); + size_t last_hash = uri.find_last_of('#'); string symbol; if (last_slash == string::npos && last_hash == string::npos) { - size_t last_colon = uri.find_last_of(":"); + size_t last_colon = uri.find_last_of(':'); if (last_colon != string::npos) symbol = uri.substr(last_colon + 1); else @@ -90,7 +92,7 @@ PluginModel::get_property(const URI& key) const else symbol = uri.str().substr(first_delim + 1, last_delim - first_delim - 1); } - set_property("lv2:symbol", Atom(Atom::STRING, symbol)); + set_property("lv2:symbol", symbol); return get_property(key); } @@ -107,7 +109,7 @@ PluginModel::get_property(const URI& key) const ret = set_property(key, Atom(Atom::URI, slv2_value_as_uri(val))); break; } else if (slv2_value_is_string(val)) { - ret = set_property(key, Atom(Atom::STRING, slv2_value_as_string(val))); + ret = set_property(key, slv2_value_as_string(val)); break; } else if (slv2_value_is_float(val)) { ret = set_property(key, Atom(slv2_value_as_float(val))); @@ -163,10 +165,10 @@ string PluginModel::human_name() { const Atom& name_atom = get_property("doap:name"); - if (name_atom.is_valid() && name_atom.type() == Atom::STRING) + if (name_atom.type() == Atom::STRING) return name_atom.get_string(); else - return default_node_symbol(); + return default_node_symbol().c_str(); } diff --git a/src/client/PluginUI.cpp b/src/client/PluginUI.cpp index 4c8016fd..0df3b060 100644 --- a/src/client/PluginUI.cpp +++ b/src/client/PluginUI.cpp @@ -55,8 +55,7 @@ lv2_ui_write(LV2UI_Controller controller, SharedPtr port = ui->node()->ports()[port_index]; - SharedPtr map = PtrCast( - ui->world()->lv2_features->feature(LV2_URI_MAP_URI)); + SharedPtr map = ui->world()->uris; // float (special case, always 0) if (format == 0) { @@ -64,18 +63,18 @@ lv2_ui_write(LV2UI_Controller controller, if (*(float*)buffer == port->value().get_float()) return; // do nothing (handle stupid plugin UIs that feed back) - ui->world()->engine->set_property(port->path(), "ingen:value", Atom(*(float*)buffer)); + ui->world()->engine->set_property(port->path(), map->ingen_value, Atom(*(float*)buffer)); - } else if (format == map->ui_format_events) { + } else if (format == map->ui_format_events.id) { LV2_Event_Buffer* buf = (LV2_Event_Buffer*)buffer; LV2_Event_Iterator iter; uint8_t* data; lv2_event_begin(&iter, buf); while (lv2_event_is_valid(&iter)) { LV2_Event* const ev = lv2_event_get(&iter, &data); - if (ev->type == map->midi_event) { + if (ev->type == map->midi_event.id) { // FIXME: bundle multiple events by writing an entire buffer here - ui->world()->engine->set_property(port->path(), "ingen:value", + ui->world()->engine->set_property(port->path(), map->ingen_value, Atom("lv2midi:MidiEvent", ev->size, data)); } else { warn << "Unable to send event type " << ev->type << @@ -85,11 +84,11 @@ lv2_ui_write(LV2UI_Controller controller, lv2_event_increment(&iter); } - } else if (format == map->object_transfer) { + } else if (format == map->object_transfer.id) { LV2_Object* buf = (LV2_Object*)buffer; Raul::Atom val; Shared::LV2Object::to_atom(ui->world(), buf, val); - ui->world()->engine->set_property(port->path(), "ingen:value", val); + ui->world()->engine->set_property(port->path(), map->ingen_value, val); } else { warn << "Unknown value format " << format diff --git a/src/client/PortModel.cpp b/src/client/PortModel.cpp index 9d63c863..5eb578d7 100644 --- a/src/client/PortModel.cpp +++ b/src/client/PortModel.cpp @@ -15,12 +15,27 @@ * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ +#include "module/ingen_module.hpp" +#include "module/World.hpp" +#include "shared/LV2URIMap.hpp" #include "PortModel.hpp" #include "NodeModel.hpp" namespace Ingen { namespace Client { + +Raul::Atom& +PortModel::set_property(const Raul::URI& uri, + const Raul::Atom& value) +{ + Raul::Atom& ret = ObjectModel::set_property(uri, value); + if (uri == ingen_get_world()->uris->ingen_value) + this->value(value); + return ret; +} + + bool PortModel::has_hint(const std::string& qname) const { @@ -28,6 +43,7 @@ PortModel::has_hint(const std::string& qname) const return (hint.is_valid() && hint.get_bool() > 0); } + void PortModel::set(SharedPtr model) { @@ -44,5 +60,6 @@ PortModel::set(SharedPtr model) ObjectModel::set(model); } + } // namespace Client } // namespace Ingen diff --git a/src/client/PortModel.hpp b/src/client/PortModel.hpp index 58f3262e..5a944532 100644 --- a/src/client/PortModel.hpp +++ b/src/client/PortModel.hpp @@ -26,9 +26,6 @@ #include "interface/Port.hpp" #include "ObjectModel.hpp" -#include - - namespace Raul { class Path; } namespace Ingen { @@ -57,15 +54,9 @@ public: bool is_integer() const { return has_hint("lv2:integer"); } bool is_toggle() const { return has_hint("lv2:toggled"); } - inline bool operator==(const PortModel& pm) const { return (_path == pm._path); } + inline bool operator==(const PortModel& pm) const { return (path() == pm.path()); } - Raul::Atom& set_property(const Raul::URI& uri, - const Raul::Atom& value) { - Raul::Atom& ret = ObjectModel::set_property(uri, value); - if (uri.str() == "ingen:value") - this->value(value); - return ret; - } + Raul::Atom& set_property(const Raul::URI& uri, const Raul::Atom& value); inline void value(const Raul::Atom& val) { if (val != _current_val) { -- cgit v1.2.1