From af759288a2517f9acf4c28f79d9c43be0086a221 Mon Sep 17 00:00:00 2001 From: David Robillard Date: Mon, 18 Aug 2008 03:49:35 +0000 Subject: More copy/paste and serialisation work. Don't die on invalid path for set_property and set_variable (return error to client). Working paste to subpatches, paste of connected patch ports and modules. git-svn-id: http://svn.drobilla.net/lad/ingen@1428 a436a847-0d15-0410-975c-d299462d15a1 --- src/libs/shared/Builder.cpp | 39 ++++++++++++++++++++++------------ src/libs/shared/Builder.hpp | 8 +++++-- src/libs/shared/ClashAvoider.cpp | 45 +++++++++++++++++++++++++++++----------- src/libs/shared/ClashAvoider.hpp | 12 +++++++---- src/libs/shared/Store.cpp | 5 +++-- src/libs/shared/Store.hpp | 3 ++- 6 files changed, 78 insertions(+), 34 deletions(-) (limited to 'src/libs/shared') diff --git a/src/libs/shared/Builder.cpp b/src/libs/shared/Builder.cpp index bc8fb21c..7065e0b4 100644 --- a/src/libs/shared/Builder.cpp +++ b/src/libs/shared/Builder.cpp @@ -36,46 +36,59 @@ Builder::Builder(CommonInterface& interface) void -Builder::build(SharedPtr object) +Builder::build(const Raul::Path& prefix, SharedPtr object) { SharedPtr patch = PtrCast(object); if (patch) { - if (patch->path() != "/") - _interface.new_patch(patch->path(), patch->internal_polyphony()); - build_object(object); + if (object->path() != "/") { + const std::string path_str = prefix + object->path(); + //cout << "BUILDING PATCH " << path_str << endl; + _interface.new_patch(path_str, patch->internal_polyphony()); + } + + build_object(prefix, object); for (Patch::Connections::const_iterator i = patch->connections().begin(); i != patch->connections().end(); ++i) { - _interface.connect((*i)->src_port_path(), (*i)->dst_port_path()); + _interface.connect(prefix.base() + (*i)->src_port_path().substr(1), + prefix.base() + (*i)->dst_port_path().substr(1)); } return; } SharedPtr node = PtrCast(object); if (node) { - _interface.new_node(node->path(), node->plugin()->uri()); - build_object(object); + Raul::Path path = prefix.base() + node->path().substr(1); + //cout << "BUILDING NODE " << path << endl; + _interface.new_node(path, node->plugin()->uri()); + build_object(prefix, object); return; } SharedPtr port = PtrCast(object); if (port) { - _interface.new_port(port->path(), port->index(), port->type().uri(), !port->is_input()); - build_object(object); + Raul::Path path = prefix.base() + port->path().substr(1); + //cout << "BUILDING PORT " << path << endl; + _interface.new_port(path, port->index(), port->type().uri(), !port->is_input()); + build_object(prefix, object); return; } } void -Builder::build_object(SharedPtr object) +Builder::build_object(const Raul::Path& prefix, SharedPtr object) { for (GraphObject::Variables::const_iterator i = object->variables().begin(); i != object->variables().end(); ++i) - _interface.set_variable(object->path(), i->first, i->second); + _interface.set_variable(prefix.base() + object->path().substr(1), i->first, i->second); for (GraphObject::Properties::const_iterator i = object->properties().begin(); - i != object->properties().end(); ++i) - _interface.set_property(object->path(), i->first, i->second); + i != object->properties().end(); ++i) { + if (object->path() == "/") + continue; + string path_str = prefix.base() + object->path().substr(1); + _interface.set_property(prefix.base() + object->path().substr(1), i->first, i->second); + } } diff --git a/src/libs/shared/Builder.hpp b/src/libs/shared/Builder.hpp index 01d3b7e5..a980bad2 100644 --- a/src/libs/shared/Builder.hpp +++ b/src/libs/shared/Builder.hpp @@ -20,6 +20,8 @@ #include +namespace Raul { class Path; } + namespace Ingen { namespace Shared { @@ -37,10 +39,12 @@ public: Builder(CommonInterface& interface); virtual ~Builder() {} - void build(SharedPtr object); + void build(const Raul::Path& prefix, + SharedPtr object); private: - void build_object(SharedPtr object); + void build_object(const Raul::Path& prefix, + SharedPtr object); CommonInterface& _interface; }; diff --git a/src/libs/shared/ClashAvoider.cpp b/src/libs/shared/ClashAvoider.cpp index bd169d4b..75f46bf6 100644 --- a/src/libs/shared/ClashAvoider.cpp +++ b/src/libs/shared/ClashAvoider.cpp @@ -28,12 +28,20 @@ namespace Shared { const Raul::Path& ClashAvoider::map_path(const Raul::Path& in) { + unsigned offset = 0; + bool has_offset = false; + size_t pos = in.find_last_of("_"); + if (pos != string::npos && pos != (in.length()-1)) { + const std::string trailing = in.substr(in.find_last_of("_")+1); + has_offset = (sscanf(trailing.c_str(), "%u", &offset) > 0); + } + SymbolMap::iterator m = _symbol_map.find(in); if (m != _symbol_map.end()) { return m->second; } else { typedef std::pair InsertRecord; - Store::iterator s = _store.find(in); + Store::iterator s = _store.find(_prefix.base() + in.substr(1)); // No clash, use symbol unmodified if (s == _store.end()) { @@ -54,18 +62,31 @@ ClashAvoider::map_path(const Raul::Path& in) // Append _2 _3 etc until an unused symbol is found string base_name = in.name(); - unsigned offset = 0; - if (sscanf(base_name.c_str(), "%*s_%u", &offset) == 1) + if (has_offset) base_name = base_name.substr(0, base_name.find_last_of("_")); - else - offset = _store.child_name_offset(in.parent(), in.name()); - - assert(offset != 0); // shouldn't have been a clash, then... - std::stringstream ss; - ss << in << "_" << offset; - InsertRecord i = _symbol_map.insert(make_pair(in, ss.str())); - assert(_store.find(i.first->second) == _store.end()); - return i.first->second; + + while (true) { + Offsets::iterator o = _offsets.find(base_name); + if (o != _offsets.end()) { + offset = ++o->second; + } else { + offset = _store.child_name_offset( + _prefix.base() + in.parent().base().substr(1), + base_name, + false); + _offsets.insert(make_pair(base_name, offset)); + } + + assert(offset != 0); // shouldn't have been a clash, then... + std::stringstream ss; + ss << in.parent().base() << base_name << "_" << offset; + if (_store.find(ss.str()) == _store.end()) { + InsertRecord i = _symbol_map.insert(make_pair(in, ss.str())); + return i.first->second; + } else { + cout << "MISSED OFFSET: " << in << " => " << ss.str() << endl; + } + } } } } diff --git a/src/libs/shared/ClashAvoider.hpp b/src/libs/shared/ClashAvoider.hpp index 05b2cd6c..f70e839a 100644 --- a/src/libs/shared/ClashAvoider.hpp +++ b/src/libs/shared/ClashAvoider.hpp @@ -37,8 +37,8 @@ class Store; class ClashAvoider : public CommonInterface { public: - ClashAvoider(Store& store, CommonInterface& target) - : _store(store), _target(target) {} + ClashAvoider(Store& store, const Raul::Path& prefix, CommonInterface& target) + : _prefix(prefix), _store(store), _target(target) {} // Bundles void bundle_begin() { _target.bundle_begin(); } @@ -81,8 +81,12 @@ public: private: const Raul::Path& map_path(const Raul::Path& in); - Store& _store; - CommonInterface& _target; + const Raul::Path& _prefix; + Store& _store; + CommonInterface& _target; + + typedef std::map Offsets; + Offsets _offsets; typedef std::map SymbolMap; SymbolMap _symbol_map; diff --git a/src/libs/shared/Store.cpp b/src/libs/shared/Store.cpp index fea18b6d..9f0f3624 100644 --- a/src/libs/shared/Store.cpp +++ b/src/libs/shared/Store.cpp @@ -82,7 +82,8 @@ Store::find_child(SharedPtr parent, const string& child_nam unsigned Store::child_name_offset(const Raul::Path& parent, - const Raul::Symbol& symbol) + const Raul::Symbol& symbol, + bool allow_zero) { unsigned offset = 0; @@ -91,7 +92,7 @@ Store::child_name_offset(const Raul::Path& parent, ss << symbol; if (offset > 0) ss << "_" << offset; - if (find(parent.base() + ss.str()) == end()) + if (find(parent.base() + ss.str()) == end() && (allow_zero || offset > 0)) break; else if (offset == 0) offset = 2; diff --git a/src/libs/shared/Store.hpp b/src/libs/shared/Store.hpp index bbefdc5c..27754345 100644 --- a/src/libs/shared/Store.hpp +++ b/src/libs/shared/Store.hpp @@ -44,7 +44,8 @@ public: const std::string& child_name) const; unsigned child_name_offset(const Raul::Path& parent, - const Raul::Symbol& symbol); + const Raul::Symbol& symbol, + bool allow_zero=true); Glib::RWLock& lock() { return _lock; } -- cgit v1.2.1