diff options
author | David Robillard <d@drobilla.net> | 2008-08-17 23:00:34 +0000 |
---|---|---|
committer | David Robillard <d@drobilla.net> | 2008-08-17 23:00:34 +0000 |
commit | 14401d11e598651e7caf39cce884362e58ef5941 (patch) | |
tree | 05b2c57b1f55640149ba850a2f9f1fda175dccb8 /src/libs/shared | |
parent | 9938fac4b15f8939c9056c16a3a7662575af52e1 (diff) | |
download | ingen-14401d11e598651e7caf39cce884362e58ef5941.tar.gz ingen-14401d11e598651e7caf39cce884362e58ef5941.tar.bz2 ingen-14401d11e598651e7caf39cce884362e58ef5941.zip |
Copy/paste of connections.
git-svn-id: http://svn.drobilla.net/lad/ingen@1426 a436a847-0d15-0410-975c-d299462d15a1
Diffstat (limited to 'src/libs/shared')
-rw-r--r-- | src/libs/shared/Builder.cpp | 15 | ||||
-rw-r--r-- | src/libs/shared/ClashAvoider.cpp | 154 | ||||
-rw-r--r-- | src/libs/shared/ClashAvoider.hpp | 96 | ||||
-rw-r--r-- | src/libs/shared/Makefile.am | 2 | ||||
-rw-r--r-- | src/libs/shared/Store.cpp | 23 | ||||
-rw-r--r-- | src/libs/shared/Store.hpp | 3 |
6 files changed, 287 insertions, 6 deletions
diff --git a/src/libs/shared/Builder.cpp b/src/libs/shared/Builder.cpp index 83e0f3d2..2b5e954c 100644 --- a/src/libs/shared/Builder.cpp +++ b/src/libs/shared/Builder.cpp @@ -41,24 +41,27 @@ Builder::build(SharedPtr<const GraphObject> object) SharedPtr<const Patch> patch = PtrCast<const Patch>(object); if (patch) { if (patch->path() != "/") - _interface.new_patch(patch->path() + "_copy", patch->internal_polyphony()); + _interface.new_patch(patch->path(), patch->internal_polyphony()); build_object(object); for (Patch::Connections::const_iterator i = patch->connections().begin(); - i != patch->connections().end(); ++i) + i != patch->connections().end(); ++i) { + cout << "BUILDER CONNECTION: " <<(*i)->src_port_path() + << " -> " << (*i)->dst_port_path() << endl; _interface.connect((*i)->src_port_path(), (*i)->dst_port_path()); + } return; } SharedPtr<const Node> node = PtrCast<const Node>(object); if (node) { - _interface.new_node(node->path() + "_copy", node->plugin()->uri()); + _interface.new_node(node->path(), node->plugin()->uri()); build_object(object); return; } SharedPtr<const Port> port = PtrCast<const Port>(object); if (port) { - _interface.new_port(port->path() + "_copy", port->index(), port->type().uri(), !port->is_input()); + _interface.new_port(port->path(), port->index(), port->type().uri(), !port->is_input()); build_object(object); return; } @@ -70,11 +73,11 @@ Builder::build_object(SharedPtr<const GraphObject> object) { for (GraphObject::Variables::const_iterator i = object->variables().begin(); i != object->variables().end(); ++i) - _interface.set_variable(object->path() + "_copy", i->first, i->second); + _interface.set_variable(object->path(), i->first, i->second); for (GraphObject::Properties::const_iterator i = object->properties().begin(); i != object->properties().end(); ++i) - _interface.set_property(object->path() + "_copy", i->first, i->second); + _interface.set_property(object->path(), i->first, i->second); } diff --git a/src/libs/shared/ClashAvoider.cpp b/src/libs/shared/ClashAvoider.cpp new file mode 100644 index 00000000..3647f023 --- /dev/null +++ b/src/libs/shared/ClashAvoider.cpp @@ -0,0 +1,154 @@ +/* This file is part of Ingen. + * Copyright (C) 2008 Dave Robillard <http://drobilla.net> + * + * Ingen is free software; you can redistribute it and/or modify it under the + * terms of the GNU General Public License as published by the Free Software + * Foundation; either version 2 of the License, or (at your option) any later + * version. + * + * Ingen is distributed in the hope that it will be useful, but WITHOUT ANY + * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS + * FOR A PARTICULAR PURPOSE. See the GNU General Public License for details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include "ClashAvoider.hpp" +#include "Store.hpp" + +using namespace std; +using namespace Raul; + +namespace Ingen { +namespace Shared { + + +const Raul::Path& +ClashAvoider::map_path(const Raul::Path& in) +{ + SymbolMap::iterator m = _symbol_map.find(in); + if (m != _symbol_map.end()) { + return m->second; + } else { + typedef std::pair<SymbolMap::iterator, bool> InsertRecord; + Store::iterator s = _store.find(in); + + // No clash, use symbol unmodified + if (s == _store.end()) { + InsertRecord i = _symbol_map.insert(make_pair(in, in)); + cout << i.first->second << endl; + return i.first->second; + } else { + + // See if the parent is mapped + Path parent = in.parent(); + do { + SymbolMap::iterator p = _symbol_map.find(parent); + if (p != _symbol_map.end()) { + const Path mapped = p->second.base() + in.substr(parent.base().length()); + InsertRecord i = _symbol_map.insert(make_pair(in, mapped)); + return i.first->second; + } + } while (parent != "/"); + + // 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) + 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()); + cout << i.first->second << endl; + return i.first->second; + } + } +} + + +void +ClashAvoider::new_patch(const std::string& path, + uint32_t poly) +{ + _target.new_patch(map_path(path), poly); +} + + +void +ClashAvoider::new_node(const std::string& path, + const std::string& plugin_uri) +{ + _target.new_node(map_path(path), plugin_uri); +} + + +void +ClashAvoider::new_port(const std::string& path, + uint32_t index, + const std::string& data_type, + bool is_output) +{ + _target.new_port(map_path(path), index, data_type, is_output); +} + + +void +ClashAvoider::connect(const std::string& src_port_path, + const std::string& dst_port_path) +{ + _target.connect(map_path(src_port_path), map_path(dst_port_path)); +} + + +void +ClashAvoider::disconnect(const std::string& src_port_path, + const std::string& dst_port_path) +{ + _target.disconnect(map_path(src_port_path), map_path(dst_port_path)); +} + + +void +ClashAvoider::set_variable(const std::string& subject_path, + const std::string& predicate, + const Raul::Atom& value) +{ + _target.set_variable(map_path(subject_path), predicate, value); +} + + +void +ClashAvoider::set_property(const std::string& subject_path, + const std::string& predicate, + const Raul::Atom& value) +{ + _target.set_property(map_path(subject_path), predicate, value); +} + + +void +ClashAvoider::set_port_value(const std::string& port_path, + const Raul::Atom& value) +{ + _target.set_port_value(map_path(port_path), value); +} + + +void +ClashAvoider::set_voice_value(const std::string& port_path, + uint32_t voice, + const Raul::Atom& value) +{ + _target.set_voice_value(map_path(port_path), voice, value); +} + + +} // namespace Shared +} // namespace Ingen diff --git a/src/libs/shared/ClashAvoider.hpp b/src/libs/shared/ClashAvoider.hpp new file mode 100644 index 00000000..05b2cd6c --- /dev/null +++ b/src/libs/shared/ClashAvoider.hpp @@ -0,0 +1,96 @@ +/* This file is part of Ingen. + * Copyright (C) 2008 Dave Robillard <http://drobilla.net> + * + * Ingen is free software; you can redistribute it and/or modify it under the + * terms of the GNU General Public License as published by the Free Software + * Foundation; either version 2 of the License, or (at your option) any later + * version. + * + * Ingen is distributed in the hope that it will be useful, but WITHOUT ANY + * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS + * FOR A PARTICULAR PURPOSE. See the GNU General Public License for details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#ifndef CLASHAVOIDER_H +#define CLASHAVOIDER_H + +#include <inttypes.h> +#include <string> +#include <map> +#include <raul/Atom.hpp> +#include <raul/Path.hpp> +#include "interface/CommonInterface.hpp" + +namespace Ingen { +namespace Shared { + +class Store; + + +/** A wrapper for a CommonInterface that creates objects but possibly maps + * symbol names to avoid clashes with the existing objects in a store. + */ +class ClashAvoider : public CommonInterface +{ +public: + ClashAvoider(Store& store, CommonInterface& target) + : _store(store), _target(target) {} + + // Bundles + void bundle_begin() { _target.bundle_begin(); } + void bundle_end() { _target.bundle_end(); } + + // Object commands + + void new_patch(const std::string& path, + uint32_t poly); + + void new_node(const std::string& path, + const std::string& plugin_uri); + + void new_port(const std::string& path, + uint32_t index, + const std::string& data_type, + bool is_output); + + void connect(const std::string& src_port_path, + const std::string& dst_port_path); + + void disconnect(const std::string& src_port_path, + const std::string& dst_port_path); + + void set_variable(const std::string& subject_path, + const std::string& predicate, + const Raul::Atom& value); + + void set_property(const std::string& subject_path, + const std::string& predicate, + const Raul::Atom& value); + + void set_port_value(const std::string& port_path, + const Raul::Atom& value); + + void set_voice_value(const std::string& port_path, + uint32_t voice, + const Raul::Atom& value); + +private: + const Raul::Path& map_path(const Raul::Path& in); + + Store& _store; + CommonInterface& _target; + + typedef std::map<Raul::Path, Raul::Path> SymbolMap; + SymbolMap _symbol_map; +}; + + +} // namespace Shared +} // namespace Ingen + +#endif // CLASHAVOIDER_H + diff --git a/src/libs/shared/Makefile.am b/src/libs/shared/Makefile.am index fcb261c8..c26c98a2 100644 --- a/src/libs/shared/Makefile.am +++ b/src/libs/shared/Makefile.am @@ -10,6 +10,8 @@ libingen_shared_la_CXXFLAGS = \ libingen_shared_la_SOURCES = \ Builder.cpp \ Builder.hpp \ + ClashAvoider.cpp \ + ClashAvoider.hpp \ LV2Features.cpp \ LV2Features.hpp \ LV2URIMap.cpp \ diff --git a/src/libs/shared/Store.cpp b/src/libs/shared/Store.cpp index f77be312..fea18b6d 100644 --- a/src/libs/shared/Store.cpp +++ b/src/libs/shared/Store.cpp @@ -78,6 +78,29 @@ Store::find_child(SharedPtr<Shared::GraphObject> parent, const string& child_nam else return SharedPtr<Shared::GraphObject>(); } + + +unsigned +Store::child_name_offset(const Raul::Path& parent, + const Raul::Symbol& symbol) +{ + unsigned offset = 0; + + while (true) { + std::stringstream ss; + ss << symbol; + if (offset > 0) + ss << "_" << offset; + if (find(parent.base() + ss.str()) == end()) + break; + else if (offset == 0) + offset = 2; + else + ++offset; + } + + return offset; +} } // namespace Shared diff --git a/src/libs/shared/Store.hpp b/src/libs/shared/Store.hpp index 573c4837..bbefdc5c 100644 --- a/src/libs/shared/Store.hpp +++ b/src/libs/shared/Store.hpp @@ -42,6 +42,9 @@ public: SharedPtr<Shared::GraphObject> find_child(SharedPtr<Shared::GraphObject> parent, const std::string& child_name) const; + + unsigned child_name_offset(const Raul::Path& parent, + const Raul::Symbol& symbol); Glib::RWLock& lock() { return _lock; } |