From acbe9a26ec3ab689e430225d15e95e73a7378aa9 Mon Sep 17 00:00:00 2001 From: David Robillard Date: Thu, 7 Sep 2006 06:04:55 +0000 Subject: Patch port fixes. Port metadata fixes. Compatibility hacks for loading old patches. Internal node fixes, cleanups, minor refactor. Path fixes. git-svn-id: http://svn.drobilla.net/lad/ingen@118 a436a847-0d15-0410-975c-d299462d15a1 --- src/libs/client/OSCEngineInterface.cpp | 4 +- src/libs/client/OSCEngineInterface.h | 2 +- src/libs/client/PatchLibrarian.cpp | 136 ++++++++++++++++++++++++--------- src/libs/client/PatchLibrarian.h | 28 +++---- 4 files changed, 120 insertions(+), 50 deletions(-) (limited to 'src/libs/client') diff --git a/src/libs/client/OSCEngineInterface.cpp b/src/libs/client/OSCEngineInterface.cpp index 29bb965a..b747e2e4 100644 --- a/src/libs/client/OSCEngineInterface.cpp +++ b/src/libs/client/OSCEngineInterface.cpp @@ -116,14 +116,14 @@ OSCEngineInterface::create_patch(const string& path, void OSCEngineInterface::create_port(const string& path, const string& data_type, - bool direction) + bool is_output) { assert(_engine_addr); lo_send(_engine_addr, "/om/synth/create_port", "issi", next_id(), path.c_str(), data_type.c_str(), - (direction ? 1 : 0)); + (is_output ? 1 : 0)); } diff --git a/src/libs/client/OSCEngineInterface.h b/src/libs/client/OSCEngineInterface.h index 69b7dc05..4405438c 100644 --- a/src/libs/client/OSCEngineInterface.h +++ b/src/libs/client/OSCEngineInterface.h @@ -74,7 +74,7 @@ public: void create_port(const string& path, const string& data_type, - bool direction); + bool is_output); void create_node(const string& path, const string& plugin_type, diff --git a/src/libs/client/PatchLibrarian.cpp b/src/libs/client/PatchLibrarian.cpp index e12c99e0..e09ac23c 100644 --- a/src/libs/client/PatchLibrarian.cpp +++ b/src/libs/client/PatchLibrarian.cpp @@ -18,6 +18,7 @@ #include #include #include +#include #include "PatchModel.h" #include "NodeModel.h" #include "ModelClientInterface.h" @@ -59,7 +60,7 @@ namespace Client { string PatchLibrarian::find_file(const string& filename, const string& additional_path) { - string search_path = additional_path + ":" + m_patch_path; + string search_path = additional_path + ":" + _patch_search_path; // Try to open the raw filename first std::ifstream is(filename.c_str(), std::ios::in); @@ -95,6 +96,20 @@ PatchLibrarian::find_file(const string& filename, const string& additional_path) } +string +PatchLibrarian::translate_load_path(const string& path) +{ + std::map::iterator t = _load_path_translations.find(path); + + if (t != _load_path_translations.end()) { + return (*t).second; + } else { + assert(Path::is_valid(path)); + return path; + } +} + + /** Save a patch from a PatchModel to a filename. * * The filename passed is the true filename the patch will be saved to (with no prefixing or anything @@ -447,10 +462,10 @@ PatchLibrarian::load_patch(PatchModel* pm, bool wait, bool existing) if (!existing) { // Wait until the patch is created or the node creations may fail if (wait) { - //int id = m_osc_model_engine_interface->get_next_request_id(); - //m_osc_model_engine_interface->set_wait_response_id(id); - m_osc_model_engine_interface->create_patch_from_model(pm); - //bool succeeded = m_osc_model_engine_interface->wait_for_response(); + //int id = _engine->get_next_request_id(); + //_engine->set_wait_response_id(id); + _engine->create_patch_from_model(pm); + //bool succeeded = _engine->wait_for_response(); // If creating the patch failed, bail out so we don't load all these nodes // into an already existing patch @@ -459,7 +474,7 @@ PatchLibrarian::load_patch(PatchModel* pm, bool wait, bool existing) return ""; }*/ // FIXME } else { - m_osc_model_engine_interface->create_patch_from_model(pm); + _engine->create_patch_from_model(pm); } } @@ -468,7 +483,7 @@ PatchLibrarian::load_patch(PatchModel* 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 - m_osc_model_engine_interface->set_metadata(pm->path(), "filename", pm->filename()); + _engine->set_metadata(pm->path(), "filename", pm->filename()); // Load nodes NodeModel* nm = NULL; @@ -478,14 +493,14 @@ PatchLibrarian::load_patch(PatchModel* pm, bool wait, bool existing) if ((!xmlStrcmp(cur->name, (const xmlChar*)"node"))) { nm = parse_node(pm, doc, cur); if (nm != NULL) { - m_osc_model_engine_interface->create_node_from_model(nm); - m_osc_model_engine_interface->set_all_metadata(nm); + _engine->create_node_from_model(nm); + _engine->set_all_metadata(nm); 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()); - m_osc_model_engine_interface->set_metadata((*j)->path(), "user-min", temp_buf); + _engine->set_metadata((*j)->path(), "user-min", temp_buf); snprintf(temp_buf, temp_buf_length, "%f", (*j)->user_max()); - m_osc_model_engine_interface->set_metadata((*j)->path(), "user-max", temp_buf); + _engine->set_metadata((*j)->path(), "user-max", temp_buf); } nm = NULL; usleep(10000); @@ -503,14 +518,14 @@ PatchLibrarian::load_patch(PatchModel* pm, bool wait, bool existing) cur = cur->next; } - // Load connections ConnectionModel* cm = NULL; + // Load connections cur = xmlDocGetRootElement(doc)->xmlChildrenNode; while (cur != NULL) { if ((!xmlStrcmp(cur->name, (const xmlChar*)"connection"))) { cm = parse_connection(pm, doc, cur); if (cm != NULL) { - m_osc_model_engine_interface->connect(cm->src_port_path(), cm->dst_port_path()); + _engine->connect(cm->src_port_path(), cm->dst_port_path()); usleep(1000); } } @@ -526,7 +541,7 @@ PatchLibrarian::load_patch(PatchModel* pm, bool wait, bool existing) preset_model = parse_preset(pm, doc, cur); assert(preset_model != NULL); if (preset_model->name() == "default") - m_osc_model_engine_interface->set_preset(pm->path(), preset_model); + _engine->set_preset(pm->path(), preset_model); } cur = cur->next; } @@ -534,10 +549,12 @@ PatchLibrarian::load_patch(PatchModel* pm, bool wait, bool existing) xmlFreeDoc(doc); xmlCleanupParser(); - m_osc_model_engine_interface->set_all_metadata(pm); + _engine->set_all_metadata(pm); if (!existing) - m_osc_model_engine_interface->enable_patch(pm->path()); + _engine->enable_patch(pm->path()); + + _load_path_translations.clear(); string ret = pm->path(); return ret; @@ -555,14 +572,11 @@ PatchLibrarian::parse_node(const PatchModel* parent, xmlDocPtr doc, const xmlNod xmlChar* key; xmlNodePtr cur = node->xmlChildrenNode; - bool found_name = false; - while (cur != NULL) { key = xmlNodeListGetString(doc, cur->xmlChildrenNode, 1); if ((!xmlStrcmp(cur->name, (const xmlChar*)"name"))) { - nm->set_path(parent->base_path() + (char*)key); - found_name = true; + nm->set_path(parent->base_path() + Path::nameify((char*)key)); } else if ((!xmlStrcmp(cur->name, (const xmlChar*)"polyphonic"))) { nm->polyphonic(!strcmp((char*)key, "true")); } else if ((!xmlStrcmp(cur->name, (const xmlChar*)"type"))) { @@ -584,7 +598,7 @@ PatchLibrarian::parse_node(const PatchModel* parent, xmlDocPtr doc, const xmlNod key = xmlNodeListGetString(doc, child->xmlChildrenNode, 1); if ((!xmlStrcmp(child->name, (const xmlChar*)"name"))) { - path = nm->base_path() + (char*)key; + path = nm->base_path() + 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"))) { @@ -666,10 +680,62 @@ PatchLibrarian::parse_node(const PatchModel* parent, xmlDocPtr doc, const xmlNod cerr << "[PatchLibrarian] Node ignored." << endl; delete nm; return NULL; - } else { - //nm->plugin(plugin); - return nm; + + // Compatibility hacks for old patches + } else if (plugin->type() == PluginModel::Internal) { + bool is_port = false; + const string path = Path::pathify(nm->path()); + if (plugin->plug_label() == "audio_input") { + _engine->create_port(path, "AUDIO", false); + is_port = true; + } else if ( plugin->plug_label() == "audio_output") { + _engine->create_port(path, "AUDIO", true); + is_port = true; + } else if ( plugin->plug_label() == "control_input") { + _engine->create_port(path, "CONTROL", false); + is_port = true; + } else if ( plugin->plug_label() == "control_output" ) { + _engine->create_port(path, "CONTROL", true); + is_port = true; + } else if ( plugin->plug_label() == "midi_input") { + _engine->create_port(path, "MIDI", false); + is_port = true; + } else if ( plugin->plug_label() == "midi_output" ) { + _engine->create_port(path, "MIDI", true); + is_port = true; + } + + if (is_port) { + const string old_path = nm->path(); + const string new_path = Path::pathify(old_path); + + // Set up translations (for connections etc) to alias both the old + // module path and the old module/port path to the new port path + _load_path_translations[old_path] = new_path; + _load_path_translations[old_path + "/in"] = new_path; + _load_path_translations[old_path + "/out"] = new_path; + + nm->set_path(new_path); + _engine->set_all_metadata(nm); + delete nm; + return NULL; + } else { + if (plugin->uri() == "") { + if (plugin->plug_label() == "note_in") { + plugin->uri("ingen:note_node"); + } else if (plugin->plug_label() == "control_input") { + plugin->uri("ingen:control_node"); + } else if (plugin->plug_label() == "transport") { + plugin->uri("ingen:transport_node"); + } else if (plugin->plug_label() == "trigger_in") { + plugin->uri("ingen:trigger_node"); + } + } + } } + + //nm->plugin(plugin); + return nm; } @@ -749,17 +815,15 @@ PatchLibrarian::parse_connection(const PatchModel* parent, xmlDocPtr doc, const return NULL; } - // FIXME: temporary compatibility, remove any slashes from port names - // remove this soon once patches have migrated - string::size_type slash_index; - while ((slash_index = source_port.find("/")) != string::npos) - source_port[slash_index] = '-'; + // Compatibility fixes for old (fundamentally broken) patches + source_node = Path::nameify(source_node); + source_port = Path::nameify(source_port); + dest_node = Path::nameify(dest_node); + dest_port = Path::nameify(dest_port); - while ((slash_index = dest_port.find("/")) != string::npos) - dest_port[slash_index] = '-'; - - ConnectionModel* cm = new ConnectionModel(parent->base_path() + source_node +"/"+ source_port, - parent->base_path() + dest_node +"/"+ dest_port); + ConnectionModel* cm = new ConnectionModel( + translate_load_path(parent->base_path() + source_node +"/"+ source_port), + translate_load_path(parent->base_path() + dest_node +"/"+ dest_port)); return cm; } @@ -803,6 +867,10 @@ PatchLibrarian::parse_preset(const PatchModel* patch, xmlDocPtr doc, const xmlNo child = child->next; } + + // Compatibility fixes for old patch files + node_name = Path::nameify(node_name); + port_name = Path::nameify(port_name); if (port_name == "") { string msg = "Unable to parse control in patch file ( node = "; diff --git a/src/libs/client/PatchLibrarian.h b/src/libs/client/PatchLibrarian.h index 817f98ca..5c199974 100644 --- a/src/libs/client/PatchLibrarian.h +++ b/src/libs/client/PatchLibrarian.h @@ -17,6 +17,8 @@ #ifndef PATCHLIBRARIAN_H #define PATCHLIBRARIAN_H +#include +#include #include #include #include @@ -42,21 +44,16 @@ class ModelClientInterface; class PatchLibrarian { public: - // FIXME: return booleans and set an errstr that can be checked? + // FIXME: return booleans and set an errstr that can be checked or something? - PatchLibrarian(OSCModelEngineInterface* const osc_model_engine_interface/*,ModelClientInterface* const client_hooks*/) - : m_patch_path("."), m_osc_model_engine_interface(osc_model_engine_interface)//, m_client_hooks(client_hooks) + PatchLibrarian(OSCModelEngineInterface* osc_model_engine_interface) + : _patch_search_path("."), _engine(osc_model_engine_interface) { - assert(m_osc_model_engine_interface); - //assert(m_client_hooks != NULL); + assert(_engine); } -// PatchLibrarian(OSCModelEngineInterface* osc_model_engine_interface) -// : m_osc_model_engine_interface(osc_model_engine_interface), m_client_hooks(new DummyModelClientInterface()) -// {} - - void path(const string& path) { m_patch_path = path; } - const string& path() { return m_patch_path; } + void path(const string& path) { _patch_search_path = path; } + const string& path() { return _patch_search_path; } string find_file(const string& filename, const string& additional_path = ""); @@ -64,8 +61,13 @@ public: string load_patch(PatchModel* pm, bool wait = true, bool existing = false); private: - string m_patch_path; - OSCModelEngineInterface* const m_osc_model_engine_interface; + string translate_load_path(const string& path); + + string _patch_search_path; + OSCModelEngineInterface* const _engine; + + /// Translations of paths from the loading file to actual paths (for deprecated patches) + std::map _load_path_translations; NodeModel* parse_node(const PatchModel* parent, xmlDocPtr doc, const xmlNodePtr cur); ConnectionModel* parse_connection(const PatchModel* parent, xmlDocPtr doc, const xmlNodePtr cur); -- cgit v1.2.1