From e5675ebfeb93175e16762d0a078bd51d15d05f63 Mon Sep 17 00:00:00 2001 From: David Robillard Date: Wed, 13 Sep 2006 06:11:25 +0000 Subject: Heavy-duty redesign of client library and GUI (now fully signal driven with clean Model/View separation). Smarter, centralized window creation/management (should make window unification easy (panes?)). Typed metadata system, no more fugly string conversion of floats. Supports OSC fundamental types string, int, float, blob for now (though blob isn't working over the wire yet). git-svn-id: http://svn.drobilla.net/lad/ingen@131 a436a847-0d15-0410-975c-d299462d15a1 --- src/libs/client/ModelClientInterface.cpp | 12 ++--- src/libs/client/ModelEngineInterface.cpp | 4 +- src/libs/client/NodeModel.cpp | 58 ++++++--------------- src/libs/client/NodeModel.h | 67 ++++++++++++------------ src/libs/client/OSCClientReceiver.cpp | 11 ++-- src/libs/client/OSCEngineSender.cpp | 15 +++--- src/libs/client/OSCEngineSender.h | 2 +- src/libs/client/ObjectController.h | 45 ---------------- src/libs/client/ObjectModel.cpp | 32 +++++++----- src/libs/client/ObjectModel.h | 61 ++++++++++++---------- src/libs/client/PatchLibrarian.cpp | 76 ++++++++++++++++++---------- src/libs/client/PatchModel.cpp | 32 ++++++------ src/libs/client/PatchModel.h | 24 +++++---- src/libs/client/PortModel.h | 31 ++---------- src/libs/client/SigClientInterface.h | 2 +- src/libs/client/Store.cpp | 16 +++--- src/libs/client/Store.h | 3 +- src/libs/client/ThreadedSigClientInterface.h | 5 +- 18 files changed, 219 insertions(+), 277 deletions(-) delete mode 100644 src/libs/client/ObjectController.h (limited to 'src/libs/client') diff --git a/src/libs/client/ModelClientInterface.cpp b/src/libs/client/ModelClientInterface.cpp index deb37187..d29395e7 100644 --- a/src/libs/client/ModelClientInterface.cpp +++ b/src/libs/client/ModelClientInterface.cpp @@ -86,17 +86,17 @@ ModelClientInterface::new_patch(string path, uint32_t poly) void -ModelClientInterface::new_node(string plugin_type, - string plugin_uri, - string node_path, - bool is_polyphonic, - uint32_t num_ports) +ModelClientInterface::new_node(string plugin_type, + string plugin_uri, + string node_path, + bool is_polyphonic, + uint32_t num_ports) { cerr << "FIXME: NEW NODE\n"; CountedPtr plugin(new PluginModel(plugin_type, plugin_uri)); - CountedPtr nm(new NodeModel(plugin, node_path)); + CountedPtr nm(new NodeModel(plugin, node_path, is_polyphonic)); new_node_model(nm); } diff --git a/src/libs/client/ModelEngineInterface.cpp b/src/libs/client/ModelEngineInterface.cpp index ca92b1ac..7cc2ae22 100644 --- a/src/libs/client/ModelEngineInterface.cpp +++ b/src/libs/client/ModelEngineInterface.cpp @@ -65,8 +65,8 @@ ModelEngineInterface::create_patch_from_model(const PatchModel* pm) void ModelEngineInterface::set_all_metadata(const ObjectModel* m) { - for (map::const_iterator i = m->metadata().begin(); i != m->metadata().end(); ++i) - set_metadata(m->path(), (*i).first, (*i).second.c_str()); + for (MetadataMap::const_iterator i = m->metadata().begin(); i != m->metadata().end(); ++i) + set_metadata(m->path(), i->first, i->second); } diff --git a/src/libs/client/NodeModel.cpp b/src/libs/client/NodeModel.cpp index 8d9d8697..55f70130 100644 --- a/src/libs/client/NodeModel.cpp +++ b/src/libs/client/NodeModel.cpp @@ -22,22 +22,18 @@ namespace Ingen { namespace Client { -NodeModel::NodeModel(CountedPtr plugin, const Path& path) +NodeModel::NodeModel(CountedPtr plugin, const Path& path, bool polyphonic) : ObjectModel(path), - m_polyphonic(false), + m_polyphonic(polyphonic), m_plugin_uri(plugin->uri()), - m_plugin(plugin), - m_x(0.0f), - m_y(0.0f) + m_plugin(plugin) { } -NodeModel::NodeModel(const string& plugin_uri, const Path& path) +NodeModel::NodeModel(const string& plugin_uri, const Path& path, bool polyphonic) : ObjectModel(path), - m_polyphonic(false), - m_plugin_uri(plugin_uri), - m_x(0.0f), - m_y(0.0f) + m_polyphonic(polyphonic), + m_plugin_uri(plugin_uri) { } @@ -52,6 +48,7 @@ void NodeModel::remove_port(CountedPtr port) { m_ports.remove(port); + removed_port_sig.emit(port); } @@ -78,12 +75,13 @@ NodeModel::clear() void NodeModel::set_path(const Path& p) { - const string old_path = m_path; + const string old_path = _path; ObjectModel::set_path(p); - for (PortModelList::iterator i = m_ports.begin(); i != m_ports.end(); ++i) - (*i)->set_path(m_path + "/" + (*i)->path().name()); + // FIXME: rename +// for (PortModelList::iterator i = m_ports.begin(); i != m_ports.end(); ++i) +// (*i)->set_path(_path + "/" + (*i)->path().name()); //if (m_parent && old_path.length() > 0) // parent_patch()->rename_node(old_path, p); @@ -104,7 +102,7 @@ NodeModel::add_child(CountedPtr c) void NodeModel::remove_child(CountedPtr c) { - assert(c->path().is_child_of(m_path)); + assert(c->path().is_child_of(_path)); assert(c->parent().get() == this); CountedPtr pm = PtrCast(c); @@ -117,7 +115,7 @@ void NodeModel::add_port(CountedPtr pm) { assert(pm); - assert(pm->path().is_child_of(m_path)); + assert(pm->path().is_child_of(_path)); assert(pm->parent().get() == this); PortModelList::iterator existing = m_ports.end(); @@ -129,7 +127,7 @@ NodeModel::add_port(CountedPtr pm) } if (existing != m_ports.end()) { - cerr << "Warning: port clash, assimilating old port " << m_path << endl; + cerr << "Warning: port clash, assimilating old port " << _path << endl; pm->assimilate(*existing); *existing = pm; } else { @@ -140,10 +138,10 @@ NodeModel::add_port(CountedPtr pm) CountedPtr -NodeModel::get_port(const string& port_name) +NodeModel::get_port(const string& port_name) const { assert(port_name.find("/") == string::npos); - for (PortModelList::iterator i = m_ports.begin(); i != m_ports.end(); ++i) + for (PortModelList::const_iterator i = m_ports.begin(); i != m_ports.end(); ++i) if ((*i)->path().name() == port_name) return (*i); return CountedPtr(); @@ -166,29 +164,5 @@ NodeModel::remove_program(int bank, int program) } -void -NodeModel::x(float a) -{ - if (m_x != a) { - m_x = a; - char temp_buf[16]; - snprintf(temp_buf, 16, "%f", a); - set_metadata("module-x", temp_buf); - } -} - - -void -NodeModel::y(float a) -{ - if (m_y != a) { - m_y = a; - char temp_buf[16]; - snprintf(temp_buf, 16, "%f", a); - set_metadata("module-y", temp_buf); - } -} - - } // namespace Client } // namespace Ingen diff --git a/src/libs/client/NodeModel.h b/src/libs/client/NodeModel.h index 60973d95..f9c87f6e 100644 --- a/src/libs/client/NodeModel.h +++ b/src/libs/client/NodeModel.h @@ -44,55 +44,50 @@ class PluginModel; class NodeModel : public ObjectModel { public: - NodeModel(const string& plugin_uri, const Path& path); - NodeModel(CountedPtr plugin, const Path& path); + NodeModel(const string& plugin_uri, const Path& path, bool polyphonic); + NodeModel(CountedPtr plugin, const Path& path, bool polyphonic); virtual ~NodeModel(); - - void add_child(CountedPtr c); - void remove_child(CountedPtr c); - - CountedPtr get_port(const string& port_name); - void add_port(CountedPtr pm); - void remove_port(CountedPtr pm); - void remove_port(const string& port_path); - - virtual void clear(); - - const map >& get_programs() const { return m_banks; } - void add_program(int bank, int program, const string& name); - void remove_program(int bank, int program); - - string plugin_uri() { return m_plugin_uri; } - CountedPtr plugin() const { return m_plugin; } - //void plugin(CountedPtr p) { m_plugin = p; } + CountedPtr get_port(const string& port_name) const; - virtual void set_path(const Path& p); - - int num_ports() const { return m_ports.size(); } - const PortModelList& ports() const { return m_ports; } - virtual bool polyphonic() const { return m_polyphonic; } - void polyphonic(bool b) { m_polyphonic = b; } - float x() const { return m_x; } - float y() const { return m_y; } - void x(float a); - void y(float a); + const map >& get_programs() const { return m_banks; } + const string& plugin_uri() const { return m_plugin_uri; } + CountedPtr plugin() const { return m_plugin; } + int num_ports() const { return m_ports.size(); } + const PortModelList& ports() const { return m_ports; } + virtual bool polyphonic() const { return m_polyphonic; } // Signals sigc::signal > new_port_sig; + sigc::signal > removed_port_sig; protected: + friend class Store; NodeModel(const Path& path); + void add_child(CountedPtr c); + void remove_child(CountedPtr c); + void add_port(CountedPtr pm); + void remove_port(CountedPtr pm); + void remove_port(const string& port_path); + void add_program(int bank, int program, const string& name); + void remove_program(int bank, int program); + + + //void plugin(CountedPtr p) { m_plugin = p; } + virtual void clear(); + + friend class PatchModel; + void set_path(const Path& p); bool m_polyphonic; - PortModelList m_ports; ///< List of ports (instead of map to preserve order) - string m_plugin_uri; ///< Plugin URI (not redundant if PluginModel unknown - CountedPtr m_plugin; ///< The plugin this node is an instance of - float m_x; ///< Just metadata, here as an optimization for GUI - float m_y; ///< Just metadata, here as an optimization for GUI - map > m_banks; ///< DSSI banks + PortModelList m_ports; ///< List of ports (not a map to preserve order) + string m_plugin_uri; ///< Plugin URI (if PluginModel is unknown) + CountedPtr m_plugin; ///< The plugin this node is an instance of + map > m_banks; ///< DSSI banks private: + friend class PatchLibrarian; // FIXME: remove + // Prevent copies (undefined) NodeModel(const NodeModel& copy); NodeModel& operator=(const NodeModel& copy); diff --git a/src/libs/client/OSCClientReceiver.cpp b/src/libs/client/OSCClientReceiver.cpp index ae607af1..4c715c76 100644 --- a/src/libs/client/OSCClientReceiver.cpp +++ b/src/libs/client/OSCClientReceiver.cpp @@ -15,8 +15,7 @@ */ #include "OSCClientReceiver.h" -//#include "NodeModel.h" -//#include "PluginModel.h" +#include "util/LibloAtom.h" #include #include #include @@ -154,7 +153,7 @@ OSCClientReceiver::setup_callbacks() lo_server_thread_add_method(_st, "/om/disconnection", "ss", disconnection_cb, this); lo_server_thread_add_method(_st, "/om/new_node", "sssii", new_node_cb, this); lo_server_thread_add_method(_st, "/om/new_port", "ssi", new_port_cb, this); - lo_server_thread_add_method(_st, "/om/metadata/update", "sss", metadata_update_cb, this); + lo_server_thread_add_method(_st, "/om/metadata/update", NULL, metadata_update_cb, this); lo_server_thread_add_method(_st, "/om/control_change", "sf", control_change_cb, this); lo_server_thread_add_method(_st, "/om/program_add", "siis", program_add_cb, this); lo_server_thread_add_method(_st, "/om/program_remove", "sii", program_remove_cb, this); @@ -337,9 +336,13 @@ OSCClientReceiver::m_new_port_cb(const char* path, const char* types, lo_arg** a int OSCClientReceiver::m_metadata_update_cb(const char* path, const char* types, lo_arg** argv, int argc, lo_message msg) { + if (argc != 3 || types[0] != 's' || types[1] != 's') + return 1; + const char* obj_path = &argv[0]->s; const char* key = &argv[1]->s; - const char* value = &argv[2]->s; + + Atom value = LibloAtom::lo_arg_to_atom(types[2], argv[2]); metadata_update(obj_path, key, value); diff --git a/src/libs/client/OSCEngineSender.cpp b/src/libs/client/OSCEngineSender.cpp index 10d9ab2e..447fa934 100644 --- a/src/libs/client/OSCEngineSender.cpp +++ b/src/libs/client/OSCEngineSender.cpp @@ -17,6 +17,7 @@ #include #include "OSCEngineSender.h" #include "interface/ClientKey.h" +#include "util/LibloAtom.h" using std::cout; using std::cerr; using std::endl; namespace Ingen { @@ -374,14 +375,16 @@ OSCEngineSender::midi_learn(const string& node_path) void OSCEngineSender::set_metadata(const string& obj_path, const string& predicate, - const string& value) + const Atom& value) { + assert(_engine_addr); - lo_send(_engine_addr, "/om/metadata/set", "isss", - next_id(), - obj_path.c_str(), - predicate.c_str(), - value.c_str()); + lo_message m = lo_message_new(); + lo_message_add_int32(m, next_id()); + lo_message_add_string(m, obj_path.c_str()); + lo_message_add_string(m, predicate.c_str()); + LibloAtom::lo_message_add_atom(m, value); + lo_send_message(_engine_addr, "/om/metadata/set", m); } diff --git a/src/libs/client/OSCEngineSender.h b/src/libs/client/OSCEngineSender.h index 2603667a..f514097d 100644 --- a/src/libs/client/OSCEngineSender.h +++ b/src/libs/client/OSCEngineSender.h @@ -126,7 +126,7 @@ public: void set_metadata(const string& obj_path, const string& predicate, - const string& value); + const Atom& value); // Requests // diff --git a/src/libs/client/ObjectController.h b/src/libs/client/ObjectController.h deleted file mode 100644 index fca59a80..00000000 --- a/src/libs/client/ObjectController.h +++ /dev/null @@ -1,45 +0,0 @@ -/* This file is part of Ingen. Copyright (C) 2006 Dave Robillard. - * - * 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 OBJECTCONTROLLER_H -#define OBJECTCONTROLLER_H - -namespace Ingen { -namespace Client { - - -/** A trivial base class for controllers of an ObjectModel. - * - * This is so ObjectModels can have pointers to app-specified controllers, - * and the pointer relationships in models (ie PatchModel has pointers to - * all it's NodeModel children, etc) can be used to find controllers of - * Models, rather than having a parallel structure of pointers in the - * app's controllers. - * - * \ingroup IngenClient - */ -class ObjectController -{ -public: - virtual ~ObjectController() {} -}; - - -} // namespace Client -} // namespace Ingen - - -#endif // OBJECTCONTROLLER_H diff --git a/src/libs/client/ObjectModel.cpp b/src/libs/client/ObjectModel.cpp index 4a0eca0d..6e18e680 100644 --- a/src/libs/client/ObjectModel.cpp +++ b/src/libs/client/ObjectModel.cpp @@ -21,34 +21,38 @@ namespace Client { ObjectModel::ObjectModel(const Path& path) -: m_path(path) +: _path(path) { } + ObjectModel::~ObjectModel() { - m_controller.reset(); } -/** Get a piece of metadata for this objeect. +/** Get a piece of metadata for this object. * * @return Metadata value with key @a key, empty string otherwise. */ -string +const Atom& ObjectModel::get_metadata(const string& key) const { - map::const_iterator i = m_metadata.find(key); - if (i != m_metadata.end()) + static const Atom null_atom; + + MetadataMap::const_iterator i = _metadata.find(key); + if (i != _metadata.end()) return i->second; else - return ""; + return null_atom; } void -ObjectModel::set_controller(CountedPtr c) +ObjectModel::add_metadata(const MetadataMap& data) { - m_controller = c; + for (MetadataMap::const_iterator i = data.begin(); i != data.end(); ++i) { + _metadata[i->first] = i->second; + } } @@ -60,13 +64,13 @@ ObjectModel::set_controller(CountedPtr c) void ObjectModel::assimilate(CountedPtr model) { - assert(m_path == model->path()); + assert(_path == model->path()); - for (map::const_iterator i = model->metadata().begin(); + for (MetadataMap::const_iterator i = model->metadata().begin(); i != model->metadata().end(); ++i) { - map::const_iterator i = m_metadata.find(i->first); - if (i == m_metadata.end()) - m_metadata[i->first] = i->second; + MetadataMap::const_iterator i = _metadata.find(i->first); + if (i == _metadata.end()) + _metadata[i->first] = i->second; } } diff --git a/src/libs/client/ObjectModel.h b/src/libs/client/ObjectModel.h index da3764d1..79d551f5 100644 --- a/src/libs/client/ObjectModel.h +++ b/src/libs/client/ObjectModel.h @@ -24,19 +24,26 @@ #include #include #include +#include "util/Atom.h" #include "util/Path.h" #include "util/CountedPtr.h" -#include "ObjectController.h" using std::string; using std::map; using std::find; using std::cout; using std::cerr; using std::endl; namespace Ingen { namespace Client { -class ObjectController; +typedef map MetadataMap; + - /** Base class for all GraphObject models (NodeModel, PatchModel, PortModel). + * + * There are no non-const public methods intentionally, models are not allowed + * to be manipulated directly by anything (but the Store) because of the + * asynchronous nature of engine control. To change something, use the + * controller (which the model probably shouldn't have a reference to but oh + * well, it reduces Collection Hell) and wait for the result (as a signal + * from this Model). * * \ingroup IngenClient */ @@ -44,39 +51,39 @@ class ObjectModel { public: ObjectModel(const Path& path); - ObjectModel() : m_path("/UNINITIALIZED") {} // FIXME: remove virtual ~ObjectModel(); - - const map& metadata() const { return m_metadata; } - string get_metadata(const string& key) const; - void set_metadata(const string& key, const string& value) - { assert(value.length() > 0); m_metadata[key] = value; metadata_update_sig.emit(key, value); } - - inline const Path& path() const { return m_path; } - virtual void set_path(const Path& p) { m_path = p; } - - CountedPtr parent() const { return m_parent; } - virtual void set_parent(CountedPtr p) { m_parent = p; } - - virtual void add_child(CountedPtr c) = 0; - virtual void remove_child(CountedPtr c) = 0; - CountedPtr controller() const { return m_controller; } - - void set_controller(CountedPtr c); + const Atom& get_metadata(const string& key) const; + void add_metadata(const MetadataMap& data); + + const MetadataMap& metadata() const { return _metadata; } + inline const Path& path() const { return _path; } + CountedPtr parent() const { return _parent; } void assimilate(CountedPtr model); // Signals - sigc::signal metadata_update_sig; - sigc::signal destroyed_sig; + sigc::signal metadata_update_sig; + sigc::signal destroyed_sig; + + // FIXME: make private + void set_metadata(const string& key, const Atom& value) + { _metadata[key] = value; metadata_update_sig.emit(key, value); } + + protected: - Path m_path; - CountedPtr m_parent; - CountedPtr m_controller; + friend class Store; + friend class PatchLibrarian; // FIXME: remove + virtual void set_path(const Path& p) { _path = p; } + virtual void set_parent(CountedPtr p) { _parent = p; } + virtual void add_child(CountedPtr c) = 0; + virtual void remove_child(CountedPtr c) = 0; + + Path _path; + CountedPtr _parent; - map m_metadata; + MetadataMap _metadata; private: // Prevent copies (undefined) diff --git a/src/libs/client/PatchLibrarian.cpp b/src/libs/client/PatchLibrarian.cpp index 07a98526..4db47b5b 100644 --- a/src/libs/client/PatchLibrarian.cpp +++ b/src/libs/client/PatchLibrarian.cpp @@ -136,7 +136,7 @@ PatchLibrarian::save_patch(CountedPtr patch_model, const string& fil xmlNodePtr xml_root_node = NULL; xmlNodePtr xml_node = NULL; xmlNodePtr xml_child_node = NULL; - xmlNodePtr xml_grandchild_node = NULL; + //xmlNodePtr xml_grandchild_node = NULL; xml_doc = xmlNewDoc((xmlChar*)"1.0"); xml_root_node = xmlNewNode(NULL, (xmlChar*)"patch"); @@ -164,13 +164,14 @@ PatchLibrarian::save_patch(CountedPtr patch_model, const string& fil xml_node = xmlNewChild(xml_root_node, NULL, (xmlChar*)"polyphony", (xmlChar*)temp_buf); // Write metadata - for (map::const_iterator i = patch_model->metadata().begin(); + for (MetadataMap::const_iterator i = patch_model->metadata().begin(); i != patch_model->metadata().end(); ++i) { + cerr << "FIXME: metadata save" << endl; // Dirty hack, don't save coordinates in patch file - if ((*i).first != "module-x" && (*i).first != "module-y" - && (*i).first != "filename") - xml_node = xmlNewChild(xml_root_node, NULL, - (xmlChar*)(*i).first.c_str(), (xmlChar*)(*i).second.c_str()); + //if (i->first != "module-x" && i->first != "module-y" + // && i->first != "filename") + // xml_node = xmlNewChild(xml_root_node, NULL, + // (xmlChar*)(*i).first.c_str(), (xmlChar*)(*i).second.c_str()); assert((*i).first != "node"); assert((*i).first != "subpatch"); @@ -215,13 +216,14 @@ PatchLibrarian::save_patch(CountedPtr patch_model, const string& fil xml_child_node = xmlNewChild(xml_node, NULL, (xmlChar*)"polyphony", (xmlChar*)temp_buf); // Write metadata - for (map::const_iterator i = nm->metadata().begin(); + for (MetadataMap::const_iterator i = nm->metadata().begin(); i != nm->metadata().end(); ++i) { + cerr << "FIXME: save metadata\n"; // Dirty hack, don't save metadata that would be in patch file - if ((*i).first != "polyphony" && (*i).first != "filename" + /*if ((*i).first != "polyphony" && (*i).first != "filename" && (*i).first != "author" && (*i).first != "description") xml_child_node = xmlNewChild(xml_node, NULL, - (xmlChar*)(*i).first.c_str(), (xmlChar*)(*i).second.c_str()); + (xmlChar*)(*i).first.c_str(), (xmlChar*)(*i).second.c_str());*/ } if (recursive) @@ -251,7 +253,9 @@ PatchLibrarian::save_patch(CountedPtr patch_model, const string& fil (xmlChar*)(nm->plugin()->uri().c_str())); // Write metadata - for (map::const_iterator i = nm->metadata().begin(); i != nm->metadata().end(); ++i) { + for (MetadataMap::const_iterator i = nm->metadata().begin(); i != nm->metadata().end(); ++i) { + cerr << "FIXME: Save metadata\n"; + /* // DSSI _hack_ (FIXME: fix OSC to be more like this and not smash DSSI into metadata?) if ((*i).first.substr(0, 16) == "dssi-configure--") { xml_child_node = xmlNewChild(xml_node, NULL, (xmlChar*)"dssi-configure", NULL); @@ -269,11 +273,14 @@ PatchLibrarian::save_patch(CountedPtr patch_model, const string& fil xml_child_node = xmlNewChild(xml_node, NULL, (xmlChar*)(*i).first.c_str(), (xmlChar*)(*i).second.c_str()); } + */ } // Write port metadata, if necessary for (PortModelList::const_iterator i = nm->ports().begin(); i != nm->ports().end(); ++i) { - const PortModel* const pm = (*i).get(); + cerr << "FIXME: save metadata\n"; + /* + const PortModel* const pm = i->get(); if (pm->is_input() && pm->user_min() != pm->min_val() || pm->user_max() != pm->max_val()) { xml_child_node = xmlNewChild(xml_node, NULL, (xmlChar*)"port", NULL); xml_grandchild_node = xmlNewChild(xml_child_node, NULL, (xmlChar*)"name", @@ -282,7 +289,7 @@ PatchLibrarian::save_patch(CountedPtr patch_model, const string& fil xml_grandchild_node = xmlNewChild(xml_child_node, NULL, (xmlChar*)"user-min", (xmlChar*)temp_buf); snprintf(temp_buf, temp_buf_length, "%f", pm->user_max()); xml_grandchild_node = xmlNewChild(xml_child_node, NULL, (xmlChar*)"user-max", (xmlChar*)temp_buf); - } + }*/ } } } @@ -385,8 +392,8 @@ PatchLibrarian::load_patch(CountedPtr pm, bool wait, bool existing) //cerr << "[PatchLibrarian] Loading patch " << filename << "" << endl; - const size_t temp_buf_length = 255; - char temp_buf[temp_buf_length]; + //const size_t temp_buf_length = 255; + //char temp_buf[temp_buf_length]; bool load_name = (pm->path() == ""); bool load_poly = (poly == 0); @@ -447,8 +454,11 @@ PatchLibrarian::load_patch(CountedPtr pm, bool wait, bool existing) // Don't know what this tag is, add it as metadata without overwriting // (so caller can set arbitrary parameters which will be preserved) if (key != NULL) + cerr << "FIXME: save metadata\n"; + /* if (pm->get_metadata((const char*)cur->name) == "") pm->set_metadata((const char*)cur->name, (const char*)key); + */ } xmlFree(key); @@ -483,7 +493,7 @@ PatchLibrarian::load_patch(CountedPtr pm, bool wait, bool existing) // This isn't so good, considering multiple clients on multiple machines, and // absolute filesystem paths obviously aren't going to be correct. But for now // this is all I can figure out to have Save/Save As work properly for subpatches - _engine->set_metadata(pm->path(), "filename", pm->filename()); + _engine->set_metadata(pm->path(), "filename", Atom(pm->filename().c_str())); // Load nodes cur = xmlDocGetRootElement(doc)->xmlChildrenNode; @@ -494,13 +504,15 @@ PatchLibrarian::load_patch(CountedPtr pm, bool wait, bool existing) if (nm) { _engine->create_node_from_model(nm.get()); _engine->set_all_metadata(nm.get()); - for (PortModelList::const_iterator j = nm->ports().begin(); j != nm->ports().end(); ++j) { + cerr << "FIXME: max min\n"; + /* + //for (PortModelList::const_iterator j = nm->ports().begin(); j != nm->ports().end(); ++j) { // FIXME: ew snprintf(temp_buf, temp_buf_length, "%f", (*j)->user_min()); _engine->set_metadata((*j)->path(), "user-min", temp_buf); snprintf(temp_buf, temp_buf_length, "%f", (*j)->user_max()); _engine->set_metadata((*j)->path(), "user-max", temp_buf); - } + }*/ } } cur = cur->next; @@ -562,19 +574,23 @@ PatchLibrarian::load_patch(CountedPtr pm, bool wait, bool existing) CountedPtr PatchLibrarian::parse_node(const CountedPtr parent, xmlDocPtr doc, const xmlNodePtr node) { +cerr << "FIXME: load node\n"; +#if 0 CountedPtr plugin(new PluginModel()); - CountedPtr nm(new NodeModel(plugin, "/UNINITIALIZED")); // FIXME: ew xmlChar* key; xmlNodePtr cur = node->xmlChildrenNode; + string path = ""' + bool polyphonic = false; + while (cur != NULL) { key = xmlNodeListGetString(doc, cur->xmlChildrenNode, 1); if ((!xmlStrcmp(cur->name, (const xmlChar*)"name"))) { - nm->set_path(parent->path().base() + Path::nameify((char*)key)); + path = parent->path().base() + Path::nameify((char*)key)); } else if ((!xmlStrcmp(cur->name, (const xmlChar*)"polyphonic"))) { - nm->polyphonic(!strcmp((char*)key, "true")); + polyphonic = !strcmp((char*)key, "true"); } else if ((!xmlStrcmp(cur->name, (const xmlChar*)"type"))) { plugin->set_type((const char*)key); } else if ((!xmlStrcmp(cur->name, (const xmlChar*)"library-name"))) { @@ -586,7 +602,7 @@ PatchLibrarian::parse_node(const CountedPtr parent, xmlDocPtr } else if ((!xmlStrcmp(cur->name, (const xmlChar*)"port"))) { xmlNodePtr child = cur->xmlChildrenNode; - string path; + string port_name; float user_min = 0.0; float user_max = 0.0; @@ -594,7 +610,7 @@ PatchLibrarian::parse_node(const CountedPtr parent, xmlDocPtr key = xmlNodeListGetString(doc, child->xmlChildrenNode, 1); if ((!xmlStrcmp(child->name, (const xmlChar*)"name"))) { - path = nm->path().base() + Path::nameify((char*)key); + port_name = Path::nameify((char*)key); } else if ((!xmlStrcmp(child->name, (const xmlChar*)"user-min"))) { user_min = atof((char*)key); } else if ((!xmlStrcmp(child->name, (const xmlChar*)"user-max"))) { @@ -607,11 +623,14 @@ PatchLibrarian::parse_node(const CountedPtr parent, xmlDocPtr child = child->next; } - // FIXME: nasty assumptions - CountedPtr pm(new PortModel(path, + assert(path.length() > 0); + assert(Path::is_valid(path)); + + // FIXME: /nasty/ assumptions + CountedPtr pm(new PortModel(Path(path).base() + port_name, PortModel::CONTROL, PortModel::INPUT, PortModel::NONE, 0.0, user_min, user_max)); - pm->set_parent(nm); + //pm->set_parent(nm); nm->add_port(pm); // DSSI hacks. Stored in the patch files as special elements, but sent to @@ -637,7 +656,7 @@ PatchLibrarian::parse_node(const CountedPtr parent, xmlDocPtr key = NULL; // Avoid a (possible?) double free child = child->next; } - nm->set_metadata("dssi-program", bank +"/"+ program); + nm->set_metadata("dssi-program", Atom(bank.append("/").append(program).c_str())); } else if ((!xmlStrcmp(cur->name, (const xmlChar*)"dssi-configure"))) { xmlNodePtr child = cur->xmlChildrenNode; @@ -659,7 +678,7 @@ PatchLibrarian::parse_node(const CountedPtr parent, xmlDocPtr child = child->next; } - nm->set_metadata(string("dssi-configure--").append(dssi_key), dssi_value); + nm->set_metadata(string("dssi-configure--").append(dssi_key), Atom(dssi_value.c_str())); } else { // Don't know what this tag is, add it as metadata if (key != NULL) @@ -729,7 +748,10 @@ PatchLibrarian::parse_node(const CountedPtr parent, xmlDocPtr } //nm->plugin(plugin); + return nm; +#endif + return CountedPtr(); } diff --git a/src/libs/client/PatchModel.cpp b/src/libs/client/PatchModel.cpp index a65f1c49..21e47089 100644 --- a/src/libs/client/PatchModel.cpp +++ b/src/libs/client/PatchModel.cpp @@ -31,13 +31,13 @@ PatchModel::set_path(const Path& new_path) { // FIXME: haack if (new_path == "") { - m_path = ""; + _path = ""; return; } NodeModel::set_path(new_path); for (NodeModelMap::iterator i = m_nodes.begin(); i != m_nodes.end(); ++i) - (*i).second->set_path(m_path +"/"+ (*i).second->path().name()); + (*i).second->set_path(_path +"/"+ (*i).second->path().name()); #ifdef DEBUG // Be sure connection paths are updated and sane @@ -72,7 +72,7 @@ PatchModel::add_child(CountedPtr c) void PatchModel::remove_child(CountedPtr c) { - assert(c->path().is_child_of(m_path)); + assert(c->path().is_child_of(_path)); assert(c->parent().get() == this); CountedPtr pm = PtrCast(c); @@ -102,13 +102,13 @@ void PatchModel::add_node(CountedPtr nm) { assert(nm); - assert(nm->path().is_child_of(m_path)); + assert(nm->path().is_child_of(_path)); assert(nm->parent().get() == this); NodeModelMap::iterator existing = m_nodes.find(nm->path().name()); if (existing != m_nodes.end()) { - cerr << "Warning: node clash, assimilating old node " << m_path << endl; + cerr << "Warning: node clash, assimilating old node " << _path << endl; nm->assimilate((*existing).second); (*existing).second = nm; } else { @@ -121,23 +121,23 @@ PatchModel::add_node(CountedPtr nm) void PatchModel::remove_node(CountedPtr nm) { - assert(nm->path().is_child_of(m_path)); + assert(nm->path().is_child_of(_path)); assert(nm->parent().get() == this); NodeModelMap::iterator i = m_nodes.find(nm->path().name()); if (i != m_nodes.end()) { assert(i->second == nm); m_nodes.erase(i); - removed_node_sig.emit(nm->path().name()); + removed_node_sig.emit(nm); i->second->parent().reset(); return; } - cerr << "[PatchModel::remove_node] " << m_path + cerr << "[PatchModel::remove_node] " << _path << ": failed to find node " << nm->path().name() << endl; } - +#if 0 void PatchModel::remove_node(const string& name) { @@ -151,9 +151,9 @@ PatchModel::remove_node(const string& name) return; } - cerr << "[PatchModel::remove_node] " << m_path << ": failed to find node " << name << endl; + cerr << "[PatchModel::remove_node] " << _path << ": failed to find node " << name << endl; } - +#endif void PatchModel::clear() @@ -204,7 +204,7 @@ PatchModel::rename_node(const Path& old_path, const Path& new_path) return; } - cerr << "[PatchModel::rename_node] " << m_path << ": failed to find node " << old_path << endl; + cerr << "[PatchModel::rename_node] " << _path << ": failed to find node " << old_path << endl; } @@ -229,8 +229,8 @@ void PatchModel::add_connection(CountedPtr cm) { assert(cm); - //assert(cm->src_port_path().parent().parent() == m_path); - //assert(cm->dst_port_path().parent().parent() == m_path); + //assert(cm->src_port_path().parent().parent() == _path); + //assert(cm->dst_port_path().parent().parent() == _path); assert(cm->patch_path() == path()); //cerr << "PatchModel::add_connection: " << cm->src_port_path() << " -> " << cm->dst_port_path() << endl; @@ -314,9 +314,9 @@ PatchModel::disable() bool PatchModel::polyphonic() const { - return (!m_parent) + return (!_parent) ? (m_poly > 1) - : (m_poly > 1) && m_poly == ((PatchModel*)m_parent.get())->poly() && m_poly > 1; + : (m_poly > 1) && m_poly == ((PatchModel*)_parent.get())->poly() && m_poly > 1; } diff --git a/src/libs/client/PatchModel.h b/src/libs/client/PatchModel.h index 6ca8ed8f..49a45503 100644 --- a/src/libs/client/PatchModel.h +++ b/src/libs/client/PatchModel.h @@ -39,11 +39,13 @@ namespace Client { class PatchModel : public NodeModel { public: - PatchModel(const string& patch_path, uint poly) - : NodeModel("ingen:patch", patch_path), + PatchModel(const string& patch_path, size_t internal_poly) + : NodeModel("ingen:patch", patch_path, false ), // FIXME m_enabled(false), - m_poly(poly) - {} + m_poly(internal_poly) + { + cerr << "FIXME: patch poly\n"; + } const NodeModelMap& nodes() const { return m_nodes; } const list >& connections() const { return m_connections; } @@ -55,7 +57,7 @@ public: CountedPtr get_node(const string& node_name); void add_node(CountedPtr nm); - void remove_node(const string& name); + //void remove_node(const string& name); void remove_node(CountedPtr nm); void rename_node(const Path& old_path, const Path& new_path); @@ -77,12 +79,12 @@ public: bool polyphonic() const; // Signals - sigc::signal > new_node_sig; - sigc::signal removed_node_sig; - sigc::signal > new_connection_sig; - sigc::signal removed_connection_sig; - sigc::signal enabled_sig; - sigc::signal disabled_sig; + sigc::signal > new_node_sig; + sigc::signal > removed_node_sig; + sigc::signal > new_connection_sig; + sigc::signal removed_connection_sig; + sigc::signal enabled_sig; + sigc::signal disabled_sig; private: // Prevent copies (undefined) diff --git a/src/libs/client/PortModel.h b/src/libs/client/PortModel.h index 1f816748..dd0a208b 100644 --- a/src/libs/client/PortModel.h +++ b/src/libs/client/PortModel.h @@ -35,22 +35,17 @@ namespace Client { class PortModel : public ObjectModel { public: + // FIXME: metadataify enum Type { CONTROL, AUDIO, MIDI }; enum Direction { INPUT, OUTPUT }; enum Hint { NONE, INTEGER, TOGGLE, LOGARITHMIC }; - PortModel(const string& path, Type type, Direction dir, Hint hint, - float default_val, float min, float max) + PortModel(const string& path, Type type, Direction dir, Hint hint) : ObjectModel(path), m_type(type), m_direction(dir), m_hint(hint), - m_default_val(default_val), - m_min_val(min), - //m_user_min(min), - m_max_val(max), - //m_user_max(max), - m_current_val(default_val), + m_current_val(0.0f), m_connections(0) { } @@ -60,11 +55,6 @@ public: m_type(type), m_direction(dir), m_hint(NONE), - m_default_val(0.0f), - m_min_val(0.0f), - //m_user_min(0.0f), - m_max_val(0.0f), - //m_user_max(0.0f), m_current_val(0.0f), m_connections(0) { @@ -73,14 +63,6 @@ public: void add_child(CountedPtr c) { throw; } void remove_child(CountedPtr c) { throw; } - inline float min_val() const { return m_min_val; } - inline float user_min() const { return atof(get_metadata("min").c_str()); } // FIXME: haaack - //inline void user_min(float f) { m_user_min = f; } - inline float default_val() const { return m_default_val; } - inline void default_val(float f) { m_default_val = f; } - inline float max_val() const { return m_max_val; } - inline float user_max() const { return atof(get_metadata("max").c_str()); } - //inline void user_max(float f) { m_user_max = f; } inline float value() const { return m_current_val; } inline void value(float f) { m_current_val = f; control_change_sig.emit(f); } inline bool connected() { return (m_connections > 0); } @@ -96,7 +78,7 @@ public: inline bool is_toggle() const { return (m_hint == TOGGLE); } inline bool operator==(const PortModel& pm) - { return (m_path == pm.m_path); } + { return (_path == pm._path); } void connected_to(CountedPtr p) { ++m_connections; connection_sig.emit(p); } void disconnected_from(CountedPtr p) { --m_connections; disconnection_sig.emit(p); } @@ -114,11 +96,6 @@ private: Type m_type; Direction m_direction; Hint m_hint; - float m_default_val; - float m_min_val; - //float m_user_min; - float m_max_val; - //float m_user_max; float m_current_val; size_t m_connections; }; diff --git a/src/libs/client/SigClientInterface.h b/src/libs/client/SigClientInterface.h index cef7d27d..a28b1a1d 100644 --- a/src/libs/client/SigClientInterface.h +++ b/src/libs/client/SigClientInterface.h @@ -55,7 +55,7 @@ public: sigc::signal object_destroyed_sig; sigc::signal connection_sig; sigc::signal disconnection_sig; - sigc::signal metadata_update_sig; + sigc::signal metadata_update_sig; sigc::signal control_change_sig; sigc::signal program_add_sig; sigc::signal program_remove_sig; diff --git a/src/libs/client/Store.cpp b/src/libs/client/Store.cpp index df0bdd95..e2637c0f 100644 --- a/src/libs/client/Store.cpp +++ b/src/libs/client/Store.cpp @@ -212,11 +212,11 @@ void Store::destruction_event(const Path& path) { CountedPtr removed = remove_object(path); - removed->controller().reset(); - cerr << "Store removed object " << path - << " controller count: " << removed->controller().use_count(); + removed.reset(); - cerr << ", model count: " << removed.use_count() << endl; + + cerr << "Store removed object " << path + << ", count: " << removed.use_count(); } void @@ -244,12 +244,10 @@ Store::new_node_event(const string& plugin_type, const string& plugin_uri, const CountedPtr plug = plugin(plugin_uri); if (!plug) { - CountedPtr n(new NodeModel(plugin_uri, node_path)); - n->polyphonic(is_polyphonic); + CountedPtr n(new NodeModel(plugin_uri, node_path, is_polyphonic)); add_plugin_orphan(n); } else { - CountedPtr n(new NodeModel(plug, node_path)); - n->polyphonic(is_polyphonic); + CountedPtr n(new NodeModel(plug, node_path, is_polyphonic)); add_object(n); } } @@ -292,7 +290,7 @@ Store::patch_disabled_event(const Path& path) void -Store::metadata_update_event(const Path& subject_path, const string& predicate, const string& value) +Store::metadata_update_event(const Path& subject_path, const string& predicate, const Atom& value) { CountedPtr subject = object(subject_path); if (subject) diff --git a/src/libs/client/Store.h b/src/libs/client/Store.h index e70c5bc0..99466b1d 100644 --- a/src/libs/client/Store.h +++ b/src/libs/client/Store.h @@ -24,6 +24,7 @@ #include "util/CountedPtr.h" #include #include "util/Path.h" +#include "util/Atom.h" using std::string; using std::map; using std::list; namespace Ingen { @@ -75,7 +76,7 @@ private: void new_port_event(const Path& path, const string& data_type, bool is_output); void patch_enabled_event(const Path& path); void patch_disabled_event(const Path& path); - void metadata_update_event(const Path& subject_path, const string& predicate, const string& value); + void metadata_update_event(const Path& subject_path, const string& predicate, const Atom& value); void control_change_event(const Path& port_path, float value); void connection_event(const Path& src_port_path, const Path& dst_port_path); void disconnection_event(const Path& src_port_path, const Path& dst_port_path); diff --git a/src/libs/client/ThreadedSigClientInterface.h b/src/libs/client/ThreadedSigClientInterface.h index 5a677034..981b038d 100644 --- a/src/libs/client/ThreadedSigClientInterface.h +++ b/src/libs/client/ThreadedSigClientInterface.h @@ -23,6 +23,7 @@ #include "interface/ClientInterface.h" #include "SigClientInterface.h" #include "util/Queue.h" +#include "util/Atom.h" using std::string; /** Returns nothing and takes no parameters (because they have all been bound) */ @@ -114,7 +115,7 @@ public: void disconnection(string src_port_path, string dst_port_path) { push_sig(sigc::bind(disconnection_slot, src_port_path, dst_port_path)); } - void metadata_update(string path, string key, string value) + void metadata_update(string path, string key, Atom value) { push_sig(sigc::bind(metadata_update_slot, path, key, value)); } void control_change(string port_path, float value) @@ -151,7 +152,7 @@ private: sigc::slot object_destroyed_slot; sigc::slot object_renamed_slot; sigc::slot disconnection_slot; - sigc::slot metadata_update_slot; + sigc::slot metadata_update_slot; sigc::slot control_change_slot; sigc::slot program_add_slot; sigc::slot program_remove_slot; -- cgit v1.2.1