@@ -36,6 +36,7 @@ struct ModuleWidget : OpaqueWidget { | |||||
virtual json_t *toJson(); | virtual json_t *toJson(); | ||||
virtual void fromJson(json_t *rootJ); | virtual void fromJson(json_t *rootJ); | ||||
void copyClipboard(); | void copyClipboard(); | ||||
void pasteClipboard(); | void pasteClipboard(); | ||||
void save(std::string filename); | void save(std::string filename); | ||||
@@ -115,9 +115,12 @@ struct Module { | |||||
randomize(); | randomize(); | ||||
} | } | ||||
json_t *toJson(); | |||||
void fromJson(json_t *rootJ); | |||||
/** Override these to store extra internal data in the "data" property of the module's JSON object */ | /** Override these to store extra internal data in the "data" property of the module's JSON object */ | ||||
virtual json_t *toJson() { return NULL; } | |||||
virtual void fromJson(json_t *root) {} | |||||
virtual json_t *dataToJson() { return NULL; } | |||||
virtual void dataFromJson(json_t *root) {} | |||||
/** Deprecated */ | /** Deprecated */ | ||||
virtual void reset() {} | virtual void reset() {} | ||||
@@ -125,13 +125,13 @@ struct AudioInterface : Module { | |||||
void step() override; | void step() override; | ||||
json_t *toJson() override { | |||||
json_t *dataToJson() override { | |||||
json_t *rootJ = json_object(); | json_t *rootJ = json_object(); | ||||
json_object_set_new(rootJ, "audio", audioIO.toJson()); | json_object_set_new(rootJ, "audio", audioIO.toJson()); | ||||
return rootJ; | return rootJ; | ||||
} | } | ||||
void fromJson(json_t *rootJ) override { | |||||
void dataFromJson(json_t *rootJ) override { | |||||
json_t *audioJ = json_object_get(rootJ, "audio"); | json_t *audioJ = json_object_get(rootJ, "audio"); | ||||
audioIO.fromJson(audioJ); | audioIO.fromJson(audioJ); | ||||
} | } | ||||
@@ -74,7 +74,7 @@ struct MIDICCToCVInterface : Module { | |||||
} | } | ||||
} | } | ||||
json_t *toJson() override { | |||||
json_t *dataToJson() override { | |||||
json_t *rootJ = json_object(); | json_t *rootJ = json_object(); | ||||
json_t *ccsJ = json_array(); | json_t *ccsJ = json_array(); | ||||
@@ -88,7 +88,7 @@ struct MIDICCToCVInterface : Module { | |||||
return rootJ; | return rootJ; | ||||
} | } | ||||
void fromJson(json_t *rootJ) override { | |||||
void dataFromJson(json_t *rootJ) override { | |||||
json_t *ccsJ = json_object_get(rootJ, "ccs"); | json_t *ccsJ = json_object_get(rootJ, "ccs"); | ||||
if (ccsJ) { | if (ccsJ) { | ||||
for (int i = 0; i < 16; i++) { | for (int i = 0; i < 16; i++) { | ||||
@@ -61,7 +61,7 @@ struct MIDIToCVInterface : Module { | |||||
onReset(); | onReset(); | ||||
} | } | ||||
json_t *toJson() override { | |||||
json_t *dataToJson() override { | |||||
json_t *rootJ = json_object(); | json_t *rootJ = json_object(); | ||||
json_t *divisionsJ = json_array(); | json_t *divisionsJ = json_array(); | ||||
@@ -75,7 +75,7 @@ struct MIDIToCVInterface : Module { | |||||
return rootJ; | return rootJ; | ||||
} | } | ||||
void fromJson(json_t *rootJ) override { | |||||
void dataFromJson(json_t *rootJ) override { | |||||
json_t *divisionsJ = json_object_get(rootJ, "divisions"); | json_t *divisionsJ = json_object_get(rootJ, "divisions"); | ||||
if (divisionsJ) { | if (divisionsJ) { | ||||
for (int i = 0; i < 2; i++) { | for (int i = 0; i < 2; i++) { | ||||
@@ -107,7 +107,7 @@ struct MIDITriggerToCVInterface : Module { | |||||
} | } | ||||
} | } | ||||
json_t *toJson() override { | |||||
json_t *dataToJson() override { | |||||
json_t *rootJ = json_object(); | json_t *rootJ = json_object(); | ||||
json_t *notesJ = json_array(); | json_t *notesJ = json_array(); | ||||
@@ -122,7 +122,7 @@ struct MIDITriggerToCVInterface : Module { | |||||
return rootJ; | return rootJ; | ||||
} | } | ||||
void fromJson(json_t *rootJ) override { | |||||
void dataFromJson(json_t *rootJ) override { | |||||
json_t *notesJ = json_object_get(rootJ, "notes"); | json_t *notesJ = json_object_get(rootJ, "notes"); | ||||
if (notesJ) { | if (notesJ) { | ||||
for (int i = 0; i < 16; i++) { | for (int i = 0; i < 16; i++) { | ||||
@@ -55,14 +55,14 @@ struct QuadMIDIToCVInterface : Module { | |||||
onReset(); | onReset(); | ||||
} | } | ||||
json_t *toJson() override { | |||||
json_t *dataToJson() override { | |||||
json_t *rootJ = json_object(); | json_t *rootJ = json_object(); | ||||
json_object_set_new(rootJ, "midi", midiInput.toJson()); | json_object_set_new(rootJ, "midi", midiInput.toJson()); | ||||
json_object_set_new(rootJ, "polyMode", json_integer(polyMode)); | json_object_set_new(rootJ, "polyMode", json_integer(polyMode)); | ||||
return rootJ; | return rootJ; | ||||
} | } | ||||
void fromJson(json_t *rootJ) override { | |||||
void dataFromJson(json_t *rootJ) override { | |||||
json_t *midiJ = json_object_get(rootJ, "midi"); | json_t *midiJ = json_object_get(rootJ, "midi"); | ||||
if (midiJ) | if (midiJ) | ||||
midiInput.fromJson(midiJ); | midiInput.fromJson(midiJ); | ||||
@@ -66,23 +66,14 @@ json_t *ModuleWidget::toJson() { | |||||
json_object_set_new(rootJ, "version", json_string(model->plugin->version.c_str())); | json_object_set_new(rootJ, "version", json_string(model->plugin->version.c_str())); | ||||
// model | // model | ||||
json_object_set_new(rootJ, "model", json_string(model->slug.c_str())); | json_object_set_new(rootJ, "model", json_string(model->slug.c_str())); | ||||
// params | |||||
if (module) { | |||||
json_t *paramsJ = json_array(); | |||||
for (Param ¶m : module->params) { | |||||
json_t *paramJ = param.toJson(); | |||||
json_array_append_new(paramsJ, paramJ); | |||||
} | |||||
json_object_set_new(rootJ, "params", paramsJ); | |||||
} | |||||
// data | |||||
// Other properties | |||||
if (module) { | if (module) { | ||||
json_t *dataJ = module->toJson(); | |||||
if (dataJ) { | |||||
json_object_set_new(rootJ, "data", dataJ); | |||||
} | |||||
json_t *moduleJ = module->toJson(); | |||||
// Merge with rootJ | |||||
json_object_update(rootJ, moduleJ); | |||||
json_decref(moduleJ); | |||||
} | } | ||||
return rootJ; | return rootJ; | ||||
} | } | ||||
@@ -117,27 +108,8 @@ void ModuleWidget::fromJson(json_t *rootJ) { | |||||
} | } | ||||
} | } | ||||
// params | |||||
json_t *paramsJ = json_object_get(rootJ, "params"); | |||||
size_t i; | |||||
json_t *paramJ; | |||||
json_array_foreach(paramsJ, i, paramJ) { | |||||
uint32_t paramId = i; | |||||
// Get paramId | |||||
json_t *paramIdJ = json_object_get(paramJ, "paramId"); | |||||
if (paramIdJ) { | |||||
// Legacy v0.6.0 to <v1.0 | |||||
paramId = json_integer_value(paramIdJ); | |||||
} | |||||
if (paramId < module->params.size()) { | |||||
module->params[paramId].fromJson(paramJ); | |||||
} | |||||
} | |||||
// data | |||||
json_t *dataJ = json_object_get(rootJ, "data"); | |||||
if (dataJ && module) { | |||||
module->fromJson(dataJ); | |||||
if (module) { | |||||
module->fromJson(rootJ); | |||||
} | } | ||||
} | } | ||||
@@ -105,6 +105,53 @@ void Light::setBrightnessSmooth(float brightness, float frames) { | |||||
} | } | ||||
json_t *Module::toJson() { | |||||
json_t *rootJ = json_object(); | |||||
// params | |||||
json_t *paramsJ = json_array(); | |||||
for (Param ¶m : params) { | |||||
json_t *paramJ = param.toJson(); | |||||
json_array_append_new(paramsJ, paramJ); | |||||
} | |||||
json_object_set_new(rootJ, "params", paramsJ); | |||||
// data | |||||
json_t *dataJ = dataToJson(); | |||||
if (dataJ) { | |||||
json_object_set_new(rootJ, "data", dataJ); | |||||
} | |||||
return rootJ; | |||||
} | |||||
void Module::fromJson(json_t *rootJ) { | |||||
// params | |||||
json_t *paramsJ = json_object_get(rootJ, "params"); | |||||
size_t i; | |||||
json_t *paramJ; | |||||
json_array_foreach(paramsJ, i, paramJ) { | |||||
uint32_t paramId = i; | |||||
// Get paramId | |||||
json_t *paramIdJ = json_object_get(paramJ, "paramId"); | |||||
if (paramIdJ) { | |||||
// Legacy v0.6.0 to <v1.0 | |||||
paramId = json_integer_value(paramIdJ); | |||||
} | |||||
if (paramId < params.size()) { | |||||
params[paramId].fromJson(paramJ); | |||||
} | |||||
} | |||||
// data | |||||
json_t *dataJ = json_object_get(rootJ, "data"); | |||||
if (dataJ) { | |||||
dataFromJson(dataJ); | |||||
} | |||||
} | |||||
void Wire::step() { | void Wire::step() { | ||||
float value = outputModule->outputs[outputId].value; | float value = outputModule->outputs[outputId].value; | ||||
inputModule->inputs[inputId].value = value; | inputModule->inputs[inputId].value = value; | ||||