diff --git a/src/app/ModuleWidget.cpp b/src/app/ModuleWidget.cpp index 6c5bb08d..9fd0b529 100644 --- a/src/app/ModuleWidget.cpp +++ b/src/app/ModuleWidget.cpp @@ -744,7 +744,12 @@ void ModuleWidget::pasteClipboardAction() { h->moduleId = module->id; h->oldModuleJ = toJson(); - fromJson(moduleJ); + try { + fromJson(moduleJ); + } + catch (Exception& e) { + WARN("%s", e.what()); + } h->newModuleJ = toJson(); APP->history->push(h); @@ -1006,7 +1011,12 @@ void ModuleWidget::cloneAction() { // Clone Module engine::Module* clonedModule = model->createModule(); // This doesn't need a lock (via Engine::moduleFromJson()) because the Module is not added to the Engine yet. - clonedModule->fromJson(moduleJ); + try { + clonedModule->fromJson(moduleJ); + } + catch (Exception& e) { + WARN("%s", e.what()); + } json_decref(moduleJ); APP->engine->addModule(clonedModule); diff --git a/src/engine/Module.cpp b/src/engine/Module.cpp index 8a961cc8..589b94ab 100644 --- a/src/engine/Module.cpp +++ b/src/engine/Module.cpp @@ -105,12 +105,12 @@ json_t* Module::toJson() { // plugin json_object_set_new(rootJ, "plugin", json_string(model->plugin->slug.c_str())); - // version - json_object_set_new(rootJ, "version", json_string(model->plugin->version.c_str())); - // model json_object_set_new(rootJ, "model", json_string(model->slug.c_str())); + // version + json_object_set_new(rootJ, "version", json_string(model->plugin->version.c_str())); + // params json_t* paramsJ = paramsToJson(); if (paramsJ) @@ -139,35 +139,17 @@ json_t* Module::toJson() { void Module::fromJson(json_t* rootJ) { - // Check if plugin and model are incorrect - json_t* pluginJ = json_object_get(rootJ, "plugin"); - std::string pluginSlug; - if (pluginJ) { - pluginSlug = json_string_value(pluginJ); - pluginSlug = plugin::normalizeSlug(pluginSlug); - if (pluginSlug != model->plugin->slug) { - WARN("Plugin %s does not match Module's plugin %s.", pluginSlug.c_str(), model->plugin->slug.c_str()); - return; - } - } - - json_t* modelJ = json_object_get(rootJ, "model"); - std::string modelSlug; - if (modelJ) { - modelSlug = json_string_value(modelJ); - modelSlug = plugin::normalizeSlug(modelSlug); - if (modelSlug != model->slug) { - WARN("Model %s does not match Module's model %s.", modelSlug.c_str(), model->slug.c_str()); - return; - } - } + plugin::Model* model = plugin::modelFromJson(rootJ); + assert(model); + if (model != this->model) + throw Exception("Model %s %s does not match Module's model %s %s.", model->plugin->slug.c_str(), model->slug.c_str(), this->model->plugin->slug.c_str(), this->model->slug.c_str()); // Check plugin version json_t* versionJ = json_object_get(rootJ, "version"); if (versionJ) { std::string version = json_string_value(versionJ); - if (version != model->plugin->version) { - INFO("Patch created with %s v%s, currently using v%s.", pluginSlug.c_str(), version.c_str(), model->plugin->version.c_str()); + if (version != this->model->plugin->version) { + INFO("Patch created with %s v%s, currently using v%s.", this->model->plugin->slug.c_str(), version.c_str(), this->model->plugin->version.c_str()); } } @@ -243,13 +225,14 @@ void Module::paramsFromJson(json_t* rootJ) { if (paramId >= paramQuantities.size()) continue; + ParamQuantity* pq = paramQuantities[paramId]; // Check that the Param is bounded - if (!paramQuantities[paramId]->isBounded()) + if (!pq->isBounded()) continue; json_t* valueJ = json_object_get(paramJ, "value"); if (valueJ) - paramQuantities[paramId]->setValue(json_number_value(valueJ)); + pq->setValue(json_number_value(valueJ)); } } diff --git a/src/history.cpp b/src/history.cpp index 8b30d464..4510a330 100644 --- a/src/history.cpp +++ b/src/history.cpp @@ -63,7 +63,12 @@ void ModuleAdd::undo() { void ModuleAdd::redo() { engine::Module* module = model->createModule(); module->id = moduleId; - module->fromJson(moduleJ); + try { + module->fromJson(moduleJ); + } + catch (Exception& e) { + WARN("%s", e.what()); + } APP->engine->addModule(module); app::ModuleWidget* mw = model->createModuleWidget(module); diff --git a/src/patch.cpp b/src/patch.cpp index 387b265c..884c4bc5 100644 --- a/src/patch.cpp +++ b/src/patch.cpp @@ -460,9 +460,15 @@ void PatchManager::fromJson(json_t* rootJ) { if (!unsavedJ) APP->history->setSaved(); - APP->engine->fromJson(rootJ); - if (APP->scene) { - APP->scene->rack->fromJson(rootJ); + try { + APP->engine->fromJson(rootJ); + if (APP->scene) { + APP->scene->rack->fromJson(rootJ); + } + } + catch (Exception& e) { + warningLog += "\n"; + warningLog += e.what(); } // At this point, ModuleWidgets and CableWidgets should own all Modules and Cables. // TODO Assert this diff --git a/src/plugin.cpp b/src/plugin.cpp index a27092a8..c3385e9c 100644 --- a/src/plugin.cpp +++ b/src/plugin.cpp @@ -1,6 +1,7 @@ #include #include #include +#include #include #include @@ -250,24 +251,53 @@ void destroy() { } +// To request fallback slugs to be added to this list, open a GitHub issue. +static const std::map pluginSlugFallbacks = { + // {"", ""}, +}; + + Plugin* getPlugin(const std::string& pluginSlug) { + if (pluginSlug.empty()) + return NULL; for (Plugin* plugin : plugins) { if (plugin->slug == pluginSlug) { return plugin; } } + // Use fallback plugin slug + auto it = pluginSlugFallbacks.find(pluginSlug); + if (it != pluginSlugFallbacks.end()) { + return getPlugin(it->second); + } return NULL; } +// To request fallback slugs to be added to this list, open a GitHub issue. +using PluginModuleSlug = std::tuple; +static const std::map moduleSlugFallbacks = { + {{"AudibleInstrumentsPreview", "Plaits"}, {"AudibleInstruments", "Plaits"}}, + {{"AudibleInstrumentsPreview", "Marbles"}, {"AudibleInstruments", "Marbles"}}, + // {{"", ""}, {"", ""}}, +}; + + Model* getModel(const std::string& pluginSlug, const std::string& modelSlug) { - Plugin* plugin = getPlugin(pluginSlug); - if (!plugin) + if (pluginSlug.empty() || modelSlug.empty()) return NULL; - Model* model = plugin->getModel(modelSlug); - if (!model) - return NULL; - return model; + Plugin* plugin = getPlugin(pluginSlug); + if (plugin) { + Model* model = plugin->getModel(modelSlug); + if (model) + return model; + } + // Use fallback (module slug, plugin slug) + auto it = moduleSlugFallbacks.find(std::make_tuple(pluginSlug, modelSlug)); + if (it != moduleSlugFallbacks.end()) { + return getModel(std::get<0>(it->second), std::get<1>(it->second)); + } + return NULL; }