@@ -26,7 +26,7 @@ plugin::Model* createModel(const std::string& slug) { | |||
return m; | |||
} | |||
app::ModuleWidget* createModuleWidget(engine::Module* m) override { | |||
TModule *tm = NULL; | |||
TModule* tm = NULL; | |||
if (m) { | |||
assert(m->model == this); | |||
tm = dynamic_cast<TModule*>(m); | |||
@@ -611,8 +611,6 @@ PortWidget* ModuleWidget::getOutput(int portId) { | |||
json_t* ModuleWidget::toJson() { | |||
json_t* moduleJ = APP->engine->moduleToJson(module); | |||
// When serializing ModuleWidget, don't include the ID. This ID is only meaningful when serializing the entire rack. | |||
json_object_del(moduleJ, "id"); | |||
return moduleJ; | |||
} | |||
@@ -622,13 +620,9 @@ void ModuleWidget::fromJson(json_t* rootJ) { | |||
void ModuleWidget::copyClipboard() { | |||
json_t* moduleJ = toJson(); | |||
DEFER({ | |||
json_decref(moduleJ); | |||
}); | |||
DEFER({json_decref(moduleJ);}); | |||
char* moduleJson = json_dumps(moduleJ, JSON_INDENT(2) | JSON_REAL_PRECISION(9)); | |||
DEFER({ | |||
free(moduleJson); | |||
}); | |||
DEFER({std::free(moduleJson);}); | |||
glfwSetClipboardString(APP->window->win, moduleJson); | |||
} | |||
@@ -645,9 +639,12 @@ void ModuleWidget::pasteClipboardAction() { | |||
WARN("JSON parsing error at %s %d:%d %s", error.source, error.line, error.column, error.text); | |||
return; | |||
} | |||
DEFER({ | |||
json_decref(moduleJ); | |||
}); | |||
DEFER({json_decref(moduleJ);}); | |||
// Don't use IDs from JSON | |||
json_object_del(moduleJ, "id"); | |||
json_object_del(moduleJ, "leftModuleId"); | |||
json_object_del(moduleJ, "rightModuleId"); | |||
// history::ModuleChange | |||
history::ModuleChange* h = new history::ModuleChange; | |||
@@ -665,9 +662,7 @@ void ModuleWidget::load(std::string filename) { | |||
FILE* file = std::fopen(filename.c_str(), "r"); | |||
if (!file) | |||
throw Exception(string::f("Could not load patch file %s", filename.c_str())); | |||
DEFER({ | |||
std::fclose(file); | |||
}); | |||
DEFER({std::fclose(file);}); | |||
INFO("Loading preset %s", filename.c_str()); | |||
@@ -675,9 +670,12 @@ void ModuleWidget::load(std::string filename) { | |||
json_t* moduleJ = json_loadf(file, 0, &error); | |||
if (!moduleJ) | |||
throw Exception(string::f("File is not a valid patch file. JSON parsing error at %s %d:%d %s", error.source, error.line, error.column, error.text)); | |||
DEFER({ | |||
json_decref(moduleJ); | |||
}); | |||
DEFER({json_decref(moduleJ);}); | |||
// Don't use IDs from JSON | |||
json_object_del(moduleJ, "id"); | |||
json_object_del(moduleJ, "leftModuleId"); | |||
json_object_del(moduleJ, "rightModuleId"); | |||
fromJson(moduleJ); | |||
} | |||
@@ -729,7 +727,7 @@ void ModuleWidget::loadDialog() { | |||
// No path selected | |||
return; | |||
} | |||
DEFER({free(pathC);}); | |||
DEFER({std::free(pathC);}); | |||
try { | |||
loadAction(pathC); | |||
@@ -744,17 +742,13 @@ void ModuleWidget::save(std::string filename) { | |||
json_t* moduleJ = toJson(); | |||
assert(moduleJ); | |||
DEFER({ | |||
json_decref(moduleJ); | |||
}); | |||
DEFER({json_decref(moduleJ);}); | |||
FILE* file = fopen(filename.c_str(), "w"); | |||
FILE* file = std::fopen(filename.c_str(), "w"); | |||
if (!file) { | |||
WARN("Could not write to patch file %s", filename.c_str()); | |||
} | |||
DEFER({ | |||
fclose(file); | |||
}); | |||
DEFER({std::fclose(file);}); | |||
json_dumpf(moduleJ, file, JSON_INDENT(2) | JSON_REAL_PRECISION(9)); | |||
} | |||
@@ -786,7 +780,7 @@ void ModuleWidget::saveDialog() { | |||
// No path selected | |||
return; | |||
} | |||
DEFER({free(pathC);}); | |||
DEFER({std::free(pathC);}); | |||
std::string path = pathC; | |||
if (system::getExtension(path) == "") | |||
@@ -872,15 +866,18 @@ void ModuleWidget::cloneAction() { | |||
// history::ComplexAction | |||
history::ComplexAction* h = new history::ComplexAction; | |||
// Clone Module | |||
engine::Module* clonedModule = model->createModule(); | |||
// JSON serialization is the obvious way to do this | |||
json_t* moduleJ = toJson(); | |||
// Don't use IDs from JSON | |||
json_object_del(moduleJ, "id"); | |||
json_object_del(moduleJ, "leftModuleId"); | |||
json_object_del(moduleJ, "rightModuleId"); | |||
// 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); | |||
json_decref(moduleJ); | |||
// Reset ID so the Engine automatically assigns a new one | |||
clonedModule->id = -1; | |||
APP->engine->addModule(clonedModule); | |||
// Clone ModuleWidget | |||
@@ -22,8 +22,9 @@ namespace app { | |||
/** Creates a new Module and ModuleWidget */ | |||
ModuleWidget* moduleWidgetFromJson(json_t* moduleJ) { | |||
static ModuleWidget* moduleWidgetFromJson(json_t* moduleJ) { | |||
plugin::Model* model = plugin::modelFromJson(moduleJ); | |||
assert(model); | |||
engine::Module* module = model->createModule(); | |||
assert(module); | |||
module->fromJson(moduleJ); | |||
@@ -287,10 +288,12 @@ void RackWidget::fromJson(json_t* rootJ) { | |||
} | |||
CableWidget* cw = new CableWidget; | |||
// Legacy: Before v1, cable colors were not serialized. So we need to initialize the color here. | |||
cw->setNextCableColor(); | |||
cw->setCable(cable); | |||
cw->fromJson(cableJ); | |||
// In <=v1, cable colors were not serialized, so choose one from the available colors. | |||
if (cw->color.a == 0.f) { | |||
cw->setNextCableColor(); | |||
} | |||
addCable(cw); | |||
} | |||
} | |||
@@ -308,20 +311,19 @@ void RackWidget::pastePresetClipboardAction() { | |||
WARN("JSON parsing error at %s %d:%d %s", error.source, error.line, error.column, error.text); | |||
return; | |||
} | |||
DEFER({ | |||
json_decref(moduleJ); | |||
}); | |||
DEFER({json_decref(moduleJ);}); | |||
// Because we are creating a new module, we don't want to use the IDs from the JSON. | |||
json_object_del(moduleJ, "id"); | |||
json_object_del(moduleJ, "leftModuleId"); | |||
json_object_del(moduleJ, "rightModuleId"); | |||
try { | |||
plugin::Model* model = plugin::modelFromJson(moduleJ); | |||
engine::Module* module = model->createModule(); | |||
assert(module); | |||
module->fromJson(moduleJ); | |||
// Reset ID so the Engine automatically assigns a new one | |||
module->id = -1; | |||
APP->engine->addModule(module); | |||
ModuleWidget* mw = module->model->createModuleWidget(module); | |||
ModuleWidget* mw = moduleWidgetFromJson(moduleJ); | |||
assert(mw); | |||
assert(mw->module); | |||
APP->engine->addModule(mw->module); | |||
addModuleAtMouse(mw); | |||
// history::ModuleAdd | |||
@@ -152,13 +152,10 @@ void Module::fromJson(json_t* rootJ) { | |||
} | |||
} | |||
// Only set ID if unset | |||
if (id < 0) { | |||
// id | |||
json_t* idJ = json_object_get(rootJ, "id"); | |||
if (idJ) | |||
id = json_integer_value(idJ); | |||
} | |||
// 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"); | |||
@@ -176,16 +173,15 @@ void Module::fromJson(json_t* rootJ) { | |||
if (bypassedJ) | |||
internal->bypassed = json_boolean_value(bypassedJ); | |||
// These do not need to be deserialized, since the module positions will set them correctly when added to the rack. | |||
// // leftModuleId | |||
// json_t *leftModuleIdJ = json_object_get(rootJ, "leftModuleId"); | |||
// if (leftModuleIdJ) | |||
// leftExpander.moduleId = json_integer_value(leftModuleIdJ); | |||
// leftModuleId | |||
json_t *leftModuleIdJ = json_object_get(rootJ, "leftModuleId"); | |||
if (leftModuleIdJ) | |||
leftExpander.moduleId = json_integer_value(leftModuleIdJ); | |||
// // rightModuleId | |||
// json_t *rightModuleIdJ = json_object_get(rootJ, "rightModuleId"); | |||
// if (rightModuleIdJ) | |||
// rightExpander.moduleId = json_integer_value(rightModuleIdJ); | |||
// rightModuleId | |||
json_t *rightModuleIdJ = json_object_get(rootJ, "rightModuleId"); | |||
if (rightModuleIdJ) | |||
rightExpander.moduleId = json_integer_value(rightModuleIdJ); | |||
// data | |||
json_t* dataJ = json_object_get(rootJ, "data"); | |||
@@ -101,9 +101,7 @@ bool isTruncated() { | |||
FILE* file = std::fopen(asset::logPath.c_str(), "r"); | |||
if (!file) | |||
return false; | |||
DEFER({ | |||
std::fclose(file); | |||
}); | |||
DEFER({std::fclose(file);}); | |||
if (fileEndsWith(file, "END")) | |||
return false; | |||
@@ -4,6 +4,7 @@ | |||
#include <curl/curl.h> | |||
#include <network.hpp> | |||
#include <system.hpp> | |||
#include <asset.hpp> | |||
@@ -160,7 +161,7 @@ static int xferInfoCallback(void* clientp, curl_off_t dltotal, curl_off_t dlnow, | |||
bool requestDownload(const std::string& url, const std::string& filename, float* progress, const CookieMap& cookies) { | |||
CURL* curl = createCurl(); | |||
FILE* file = fopen(filename.c_str(), "wb"); | |||
FILE* file = std::fopen(filename.c_str(), "wb"); | |||
if (!file) | |||
return false; | |||
@@ -182,10 +183,10 @@ bool requestDownload(const std::string& url, const std::string& filename, float* | |||
CURLcode res = curl_easy_perform(curl); | |||
curl_easy_cleanup(curl); | |||
fclose(file); | |||
std::fclose(file); | |||
if (res != CURLE_OK) | |||
remove(filename.c_str()); | |||
system::remove(filename); | |||
return res == CURLE_OK; | |||
} | |||
@@ -273,9 +273,7 @@ void PatchManager::loadAutosave() { | |||
// TODO Load template without causing infinite recursion | |||
return; | |||
} | |||
DEFER({ | |||
std::fclose(file); | |||
}); | |||
DEFER({std::fclose(file);}); | |||
json_error_t error; | |||
json_t* rootJ = json_loadf(file, 0, &error); | |||
@@ -260,9 +260,7 @@ void save(const std::string& path) { | |||
FILE* file = std::fopen(path.c_str(), "w"); | |||
if (!file) | |||
return; | |||
DEFER({ | |||
std::fclose(file); | |||
}); | |||
DEFER({std::fclose(file);}); | |||
json_dumpf(rootJ, file, JSON_INDENT(2) | JSON_REAL_PRECISION(9)); | |||
json_decref(rootJ); | |||
@@ -273,9 +271,7 @@ void load(const std::string& path) { | |||
FILE* file = std::fopen(path.c_str(), "r"); | |||
if (!file) | |||
return; | |||
DEFER({ | |||
std::fclose(file); | |||
}); | |||
DEFER({std::fclose(file);}); | |||
json_error_t error; | |||
json_t* rootJ = json_loadf(file, 0, &error); | |||