diff options
Diffstat (limited to 'src/libs/client/PatchLibrarian.cpp')
-rw-r--r-- | src/libs/client/PatchLibrarian.cpp | 136 |
1 files changed, 102 insertions, 34 deletions
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 <libxml/parser.h> #include <libxml/tree.h> #include <libxml/xpath.h> +#include <algorithm> #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<string,string>::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 = "; |