| @@ -145,6 +145,7 @@ json_t *CableWidget::toJson() { | |||
| assert(isComplete()); | |||
| json_t *rootJ = json_object(); | |||
| json_object_set_new(rootJ, "id", json_integer(cable->id)); | |||
| json_object_set_new(rootJ, "outputModuleId", json_integer(cable->outputModule->id)); | |||
| json_object_set_new(rootJ, "outputId", json_integer(cable->outputId)); | |||
| json_object_set_new(rootJ, "inputModuleId", json_integer(cable->inputModule->id)); | |||
| @@ -181,6 +182,16 @@ void CableWidget::fromJson(json_t *rootJ) { | |||
| if (!inputIdJ) return; | |||
| int inputId = json_integer_value(inputIdJ); | |||
| // Only set ID if unset | |||
| if (cable->id < 0) { | |||
| // id | |||
| json_t *idJ = json_object_get(rootJ, "id"); | |||
| // Before 1.0, cables IDs were not used, so just leave it as default and Engine will assign one automatically. | |||
| if (idJ) { | |||
| cable->id = json_integer_value(idJ); | |||
| } | |||
| } | |||
| // Set ports | |||
| if (APP->patch->isLegacy(1)) { | |||
| // Before 0.6, the index of the "ports" array was the index of the PortWidget in the `outputs` and `inputs` vector. | |||
| @@ -483,60 +483,17 @@ PortWidget *ModuleWidget::getInput(int inputId) { | |||
| } | |||
| json_t *ModuleWidget::toJson() { | |||
| json_t *rootJ = json_object(); | |||
| // plugin | |||
| json_object_set_new(rootJ, "plugin", json_string(model->plugin->slug.c_str())); | |||
| // version of plugin | |||
| if (!model->plugin->version.empty()) | |||
| 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())); | |||
| // Merge with module JSON | |||
| if (module) { | |||
| json_t *moduleJ = module->toJson(); | |||
| // Merge with rootJ | |||
| json_object_update(rootJ, moduleJ); | |||
| json_decref(moduleJ); | |||
| } | |||
| if (!module) | |||
| return NULL; | |||
| json_t *rootJ = module->toJson(); | |||
| return rootJ; | |||
| } | |||
| void ModuleWidget::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); | |||
| if (pluginSlug != model->plugin->slug) { | |||
| WARN("Plugin %s does not match ModuleWidget'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); | |||
| if (modelSlug != model->slug) { | |||
| WARN("Model %s does not match ModuleWidget's model %s.", modelSlug.c_str(), model->slug.c_str()); | |||
| return; | |||
| } | |||
| } | |||
| // 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 (module) { | |||
| module->fromJson(rootJ); | |||
| } | |||
| if (!module) | |||
| return; | |||
| module->fromJson(rootJ); | |||
| } | |||
| void ModuleWidget::copyClipboard() { | |||
| @@ -192,8 +192,6 @@ json_t *RackWidget::toJson() { | |||
| // module | |||
| json_t *moduleJ = moduleWidget->toJson(); | |||
| { | |||
| // id | |||
| json_object_set_new(moduleJ, "id", json_integer(moduleWidget->module->id)); | |||
| // pos | |||
| math::Vec pos = moduleWidget->box.pos.minus(moduleOffset); | |||
| pos = pos.div(RACK_GRID_SIZE).round(); | |||
| @@ -215,12 +213,7 @@ json_t *RackWidget::toJson() { | |||
| continue; | |||
| json_t *cableJ = cw->toJson(); | |||
| { | |||
| // id | |||
| json_object_set_new(rootJ, "id", json_integer(cw->cable->id)); | |||
| } | |||
| json_array_append_new(cablesJ, cableJ); | |||
| } | |||
| json_object_set_new(rootJ, "cables", cablesJ); | |||
| @@ -242,10 +235,6 @@ void RackWidget::fromJson(json_t *rootJ) { | |||
| if (APP->patch->isLegacy(2)) { | |||
| moduleWidget->module->id = moduleIndex; | |||
| } | |||
| // id | |||
| json_t *idJ = json_object_get(moduleJ, "id"); | |||
| if (idJ) | |||
| moduleWidget->module->id = json_integer_value(idJ); | |||
| // pos | |||
| json_t *posJ = json_object_get(moduleJ, "pos"); | |||
| @@ -288,15 +277,6 @@ void RackWidget::fromJson(json_t *rootJ) { | |||
| delete cw; | |||
| continue; | |||
| } | |||
| // Before 1.0, cables IDs were not used, so just use the index of the "cables" array. | |||
| if (APP->patch->isLegacy(2)) { | |||
| cw->cable->id = cableIndex; | |||
| } | |||
| // id | |||
| json_t *idJ = json_object_get(cableJ, "id"); | |||
| if (idJ) | |||
| cw->cable->id = json_integer_value(idJ); | |||
| addCable(cw); | |||
| } | |||
| } | |||
| @@ -32,6 +32,18 @@ void Module::config(int numParams, int numInputs, int numOutputs, int numLights) | |||
| json_t *Module::toJson() { | |||
| json_t *rootJ = json_object(); | |||
| // id | |||
| json_object_set_new(rootJ, "id", json_integer(id)); | |||
| // 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())); | |||
| // params | |||
| json_t *paramsJ = json_array(); | |||
| for (size_t paramId = 0; paramId < params.size(); paramId++) { | |||
| @@ -54,12 +66,6 @@ json_t *Module::toJson() { | |||
| if (bypass) | |||
| json_object_set_new(rootJ, "bypass", json_boolean(bypass)); | |||
| // data | |||
| json_t *dataJ = dataToJson(); | |||
| if (dataJ) { | |||
| json_object_set_new(rootJ, "data", dataJ); | |||
| } | |||
| // leftModuleId | |||
| if (leftExpander.moduleId >= 0) | |||
| json_object_set_new(rootJ, "leftModuleId", json_integer(leftExpander.moduleId)); | |||
| @@ -68,10 +74,54 @@ json_t *Module::toJson() { | |||
| if (rightExpander.moduleId >= 0) | |||
| json_object_set_new(rootJ, "rightModuleId", json_integer(rightExpander.moduleId)); | |||
| // data | |||
| json_t *dataJ = dataToJson(); | |||
| if (dataJ) { | |||
| json_object_set_new(rootJ, "data", dataJ); | |||
| } | |||
| return rootJ; | |||
| } | |||
| 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); | |||
| 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); | |||
| if (modelSlug != model->slug) { | |||
| WARN("Model %s does not match Module's model %s.", modelSlug.c_str(), model->slug.c_str()); | |||
| return; | |||
| } | |||
| } | |||
| // 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()); | |||
| } | |||
| } | |||
| // Only set ID if unset | |||
| if (id < 0) { | |||
| // id | |||
| json_t *idJ = json_object_get(rootJ, "id"); | |||
| if (idJ) | |||
| id = json_integer_value(idJ); | |||
| } | |||
| // params | |||
| json_t *paramsJ = json_object_get(rootJ, "params"); | |||
| size_t i; | |||