Skip to content

Commit

Permalink
Refactor initVarAndValue: support pointer to vector
Browse files Browse the repository at this point in the history
SysModUI
- rename initVarAndUpdate to initVarAndValue
- add initNumber for vector
- add initVarAndValue for vectors
- initVarAndValue: call initVar and initValue and call setValue if initValue says so
- initValue: (came from initVarAndUpdate), setValue needed is return value
- processJson: onDelete: call varFun before actual delete
- callVarFun: if onDelete and pointer, remove row from pointer vector
- FunTypes: rename onAddRow to onAdd and onDeleteRow to onDelete

SysModModel
- remove ChangeFun typedef
- Variable.valueString: support rowNr
- Add Variable.rows (WIP)
- rename callVarChangeFun to callVarOnChange
- callVarOnChange: if pointer is array, get the right rowNr, if varVal is array, treat the pointer as a vector and assign value to pointer
  • Loading branch information
ewoudwijma committed Sep 16, 2024
1 parent f262ba5 commit 2be0136
Show file tree
Hide file tree
Showing 7 changed files with 1,389 additions and 1,260 deletions.
20 changes: 10 additions & 10 deletions data/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -393,8 +393,8 @@ function createHTML(json, parentNode = null, rowNr = UINT8_MAX) {
console.log("Table +", event.target);

var command = {};
command.addRow = {};
command.addRow.id = variable.id;
command.onAdd = {};
command.onAdd.id = variable.id;
requestJson(command);
});
divNode.appendChild(buttonNode);
Expand Down Expand Up @@ -719,9 +719,9 @@ function genTableRowHTML(json, parentNode = null, rowNr = UINT8_MAX) {
console.log("Table -", event.target);

var command = {};
command.delRow = {};
command.delRow.id = variable.id;
command.delRow.rowNr = rowNr;
command.onDelete = {};
command.onDelete.id = variable.id;
command.onDelete.rowNr = rowNr;
requestJson(command);

});
Expand Down Expand Up @@ -789,7 +789,7 @@ function receiveData(json) {
}
flushOnUICommands(); //make sure onUIs of new elements are called
}
else if (key == "addRow") { //update the row of a table
else if (key == "onAdd") { //update the row of a table
ppf("receiveData", key, value);

if (value.id && value.rowNr != null) {
Expand All @@ -800,16 +800,16 @@ function receiveData(json) {
let tableNode = gId(tableId);
let tbodyNode = tableNode.querySelector("tbody");

ppf("addRow ", tableVar, tableNode, rowNr);
ppf("onAdd ", tableVar, tableNode, rowNr);

let newRowNr = tbodyNode.querySelectorAll("tr").length;

genTableRowHTML(tableVar, tableNode, newRowNr);
}
else
ppf("dev receiveData addRow no id and/or rowNr specified", key, value);
ppf("dev receiveData onAdd no id and/or rowNr specified", key, value);

} else if (key == "delRow") { //update the row of a table
} else if (key == "onDelete") { //update the row of a table

ppf("receiveData", key, value);
let tableId = value.id;
Expand All @@ -824,7 +824,7 @@ function receiveData(json) {

varRemoveValuesForRow(tableVar, rowNr);

ppf("delRow ", tableVar, tableNode, rowNr);
ppf("onDelete ", tableVar, tableNode, rowNr);

} else if (key == "updRow") { //update the row of a table

Expand Down
10 changes: 5 additions & 5 deletions src/Sys/SysModFiles.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -35,16 +35,16 @@ void SysModFiles::setup() {
ui->setLabel(var, "Files");
ui->setComment(var, "List of files");
return true;
case onAddRow:
case onAdd:
rowNr = fileList.size();
web->getResponseObject()["addRow"]["rowNr"] = rowNr;
web->getResponseObject()["onAdd"]["rowNr"] = rowNr;
//add a row with all defaults
//tbd: File upload does not call onAddRow (bug?)
//tbd: File upload does not call onAdd (bug?)
return true;
case onDeleteRow:
case onDelete:
if (rowNr != UINT8_MAX && rowNr < fileList.size()) {
const char * fileName = fileList[rowNr].name;
// ppf("fileTbl delRow %s[%d] = %s %s\n", Variable(var).id(), rowNr, Variable(var).valueString(), fileName);
// ppf("fileTbl onDelete %s[%d] = %s %s\n", Variable(var).id(), rowNr, Variable(var).valueString(), fileName);
this->removeFiles(fileName, false);

#ifdef STARBASE_USERMOD_LIVE
Expand Down
102 changes: 58 additions & 44 deletions src/Sys/SysModModel.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -237,7 +237,7 @@ bool checkDash(JsonObject var) {
return false;
}

bool SysModModel::callVarChangeFun(JsonObject var, unsigned8 rowNr, bool init) {
bool SysModModel::callVarOnChange(JsonObject var, unsigned8 rowNr, bool init) {
Variable variable = Variable(var);
//not in SysModModel.h as ui->callVarFun cannot be used in SysModModel.h

Expand All @@ -248,55 +248,69 @@ bool SysModModel::callVarChangeFun(JsonObject var, unsigned8 rowNr, bool init) {

//if var is bound by pointer, set the pointer value before calling onChange
if (!var["p"].isNull()) {
JsonVariant value;
//pointer is an array if set by setValueRowNr, used for controls as each control has a seperate variable
int pointer;
if (rowNr == UINT8_MAX) {
value = var["value"];
pointer = var["p"];
} else {
value = var["value"][rowNr];
if (var["p"].is<JsonArray>())
pointer = var["p"][rowNr];
}
else
pointer = var["p"];

if (var["type"] == "select" || var["type"] == "checkbox" || var["type"] == "range") {
uint8_t *valuePointer = (uint8_t *)pointer;
if (valuePointer != nullptr) {
*valuePointer = value;
ppf("pointer set8 %s: v:%d (p:%p) (r:%d v:%s p:%d)\n", variable.id(), *valuePointer, valuePointer, rowNr, variable.valueString(), pointer);
}
else
ppf("dev pointer set8 %s: v:%d (p:%p) (r:%d v:%s p:%d)\n", variable.id(), *valuePointer, valuePointer, rowNr, variable.valueString(), pointer);
}
else if (var["type"] == "number") {
uint16_t *valuePointer = (uint16_t *)pointer;
if (valuePointer != nullptr) {
*valuePointer = value;
ppf("pointer set16 %s: v:%d (p:%p) (r:%d v:%s p:%d)\n", variable.id(), *valuePointer, valuePointer, rowNr, variable.valueString(), pointer);
}
else
ppf("dev pointer set16 %s: v:%d (p:%p) (r:%d v:%s p:%d)\n", variable.id(), *valuePointer, valuePointer, rowNr, variable.valueString(), pointer);
}
// else if (var["type"] == "text") {
// const char *valuePointer = (const char *)pointer;
// if (valuePointer != nullptr) {
// *valuePointer = value;
// ppf("pointer set16 %s: v:%d (p:%p) (r:%d v:%s p:%d)\n", Variable(var).id(), *valuePointer, valuePointer, rowNr, var["value"].as<String>().c_str(), pointer);
// }
// else
// ppf("dev pointer set16 %s: v:%d (p:%p) (r:%d v:%s p:%d)\n", Variable(var).id(), *valuePointer, valuePointer, rowNr, var["value"].as<String>().c_str(), pointer);
// }
else if (var["type"] == "coord3D") {
Coord3D *valuePointer = (Coord3D *)pointer;
if (valuePointer != nullptr) {
*valuePointer = value;
// ppf("pointer set coord3D %s: v:%d,%d,%d (p:%p) (r:%d v:%s p:%d)\n", Variable(var).id(), (*valuePointer).x, (*valuePointer).y, (*valuePointer).z, valuePointer, rowNr, var["value"].as<String>().c_str(), pointer);
if (pointer != 0) {

if (var["value"].is<JsonArray>()) {
if (rowNr != UINT8_MAX) {
if (var["type"] == "select" || var["type"] == "checkbox" || var["type"] == "range") {
std::vector<uint8_t> *valuePointer = (std::vector<uint8_t> *)pointer;
while (rowNr >= (*valuePointer).size()) (*valuePointer).push_back(UINT8_MAX); //create vector space if needed...
(*valuePointer)[rowNr] = var["value"][rowNr]; //value should be an uint16_t
}
else if (var["type"] == "number") {
std::vector<uint16_t> *valuePointer = (std::vector<uint16_t> *)pointer;
while (rowNr >= (*valuePointer).size()) (*valuePointer).push_back(UINT16_MAX); //create vector space if needed...
(*valuePointer)[rowNr] = var["value"][rowNr]; //value should be an uint16_t
}
else if (var["type"] == "coord3D") {
std::vector<Coord3D> *valuePointer = (std::vector<Coord3D> *)pointer;
while (rowNr >= (*valuePointer).size()) (*valuePointer).push_back({-1,-1,-1}); //create vector space if needed...
(*valuePointer)[rowNr] = var["value"][rowNr]; //value should be an uint16_t
}
else
print->printJson("dev callVarOnChange type not supported yet", var);

ppf("callVarOnChange set pointer to vector %s[%d]: v:%s p:%d\n", variable.id(), rowNr, variable.valueString(), pointer);
} else
print->printJson("dev value is array but no rowNr\n", var);
} else {
if (var["type"] == "select" || var["type"] == "checkbox" || var["type"] == "range") {
uint8_t *valuePointer = (uint8_t *)pointer;
*valuePointer = var["value"];
}
else if (var["type"] == "number") {
uint16_t *valuePointer = (uint16_t *)pointer;
*valuePointer = var["value"];
}
else if (var["type"] == "coord3D") {
Coord3D *valuePointer = (Coord3D *)pointer;
*valuePointer = var["value"];
}

ppf("callVarOnChange set pointer %s[%d]: v:%s p:%d\n", variable.id(), rowNr, variable.valueString(), pointer);
}
else
ppf("dev pointer set coord3D %s: v:%d,%d,%d (p:%p) (r:%d v:%s p:%d)\n", variable.id(), (*valuePointer).x, (*valuePointer).y, (*valuePointer).z, valuePointer, rowNr, variable.valueString(), pointer);

// else if (var["type"] == "text") {
// const char *valuePointer = (const char *)pointer;
// if (valuePointer != nullptr) {
// *valuePointer = value;
// ppf("pointer set16 %s: v:%d (p:%p) (r:%d v:%s p:%d)\n", Variable(var).id(), *valuePointer, valuePointer, rowNr, var["value"].as<String>().c_str(), pointer);
// }
// else
// ppf("dev pointer set16 %s: v:%d (p:%p) (r:%d v:%s p:%d)\n", Variable(var).id(), *valuePointer, valuePointer, rowNr, var["value"].as<String>().c_str(), pointer);
// }
}
else
ppf("dev pointer of type %s not supported yet\n", var["type"].as<String>().c_str());
}
// ppf("dev pointer of type %s is 0\n", var["type"].as<String>().c_str());
print->printJson("dev pointer is 0", var);
} //pointer

return ui->callVarFun(var, rowNr, onChange);

Expand Down
42 changes: 35 additions & 7 deletions src/Sys/SysModModel.h
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,6 @@
#include "SysModules.h" //isConnected

typedef std::function<void(JsonObject)> FindFun;
typedef std::function<void(JsonObject, size_t)> ChangeFun;

struct Coord3D {
int x;
Expand Down Expand Up @@ -200,12 +199,16 @@ class Variable {
this->var = var;
}

//core methods
const char * id() {
return var["id"];
}

String valueString() {
return var["value"].as<String>();
String valueString(uint8_t rowNr = UINT8_MAX) {
if (rowNr == UINT8_MAX)
return var["value"].as<String>();
else
return var["value"][rowNr].as<String>();
}

int order() {return var["o"];}
Expand Down Expand Up @@ -233,6 +236,31 @@ class Variable {

JsonArray valArray() {if (var["value"].is<JsonArray>()) return var["value"]; else return JsonArray(); }

//if variable is a table, loop through its rows
void rows(std::function<void(Variable, uint8_t)> fun = nullptr) {
//tbd table check ...
//tbd move to table subclass??
// get the first child
JsonObject firstChild = children()[0];
//loop through its rows
uint8_t rowNr = 0;
for (JsonVariant value: Variable(firstChild).valArray()) {
if (fun) fun(*this, rowNr);
// find the other columns
//loop over children to get the table columns
// ppf("row %d:", rowNr);
// for (JsonObject child: children()) {
// Variable childVariable = Variable(child);
// ppf(" %s: %s", childVariable.id(), childVariable.valueString(rowNr));
// //process each ...
// }
// ppf("\n");
rowNr++;
}
}

//extra methods

unsigned8 linearToLogarithm(unsigned8 value) {
if (value == 0) return 0;

Expand Down Expand Up @@ -408,7 +436,7 @@ class SysModModel:public SysModule {
}

if (var["value"].is<JsonArray>()) {
JsonArray valueArray = var["value"].as<JsonArray>();
JsonArray valueArray = variable.valArray();
//set the right value in the array (if array did not contain values yet, all values before rownr are set to false)
bool notSame = true; //rowNr >= size

Expand All @@ -425,11 +453,11 @@ class SysModModel:public SysModule {
}
}
else {
ppf("setValue %s could not create value array\n", Variable(var).id());
ppf("setValue %s could not create value array\n", variable.id());
}
}

if (changed) callVarChangeFun(var, rowNr);
if (changed) callVarOnChange(var, rowNr);

return var;
}
Expand Down Expand Up @@ -498,7 +526,7 @@ class SysModModel:public SysModule {
// void varToValues(JsonObject var, JsonArray values);

//sends dash var change to udp (if init), sets pointer if pointer var and run onChange
bool callVarChangeFun(JsonObject var, unsigned8 rowNr = UINT8_MAX, bool init = false);
bool callVarOnChange(JsonObject var, unsigned8 rowNr = UINT8_MAX, bool init = false);

private:
bool doShowObsolete = false;
Expand Down
22 changes: 14 additions & 8 deletions src/Sys/SysModUI.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -178,23 +178,29 @@ void SysModUI::processJson(JsonVariant json) {
var[JsonString(key, JsonString::Copied)] = JsonString(value, JsonString::Copied); //this is needed as key can become a dangling pointer
// json.remove(key); //key should stay as all clients use this to perform the changeHTML action
}
else if (pair.key() == "addRow" || pair.key() == "delRow") {
else if (pair.key() == "onAdd" || pair.key() == "onDelete") {
if (value.is<JsonObject>()) {
JsonObject command = value;
JsonObject var = mdl->findVar(command["id"]);
stackUnsigned8 rowNr = command["rowNr"].isNull()?UINT8_MAX:command["rowNr"];
ppf("processJson %s - %s[%d]\n", key, Variable(var).id(), rowNr);

bool doWS = false;

if (callVarFun(var, rowNr, pair.key() == "onAdd"?onAdd:onDelete)) {
doWS = true;
}

//first remove the deleted row both on server and on client(s)
if (pair.key() == "delRow") {
ppf("delRow remove values\n");
if (pair.key() == "onDelete") {
ppf("onDelete remove values\n");
Variable(var).removeValuesForRow(rowNr);
web->sendResponseObject(); //async response //trigger receiveData->delRow
doWS = true;
}

if (callVarFun(var, rowNr, pair.key() == "addRow"?onAddRow:onDeleteRow)) {
web->sendResponseObject(); //async response
}
if (doWS)
web->sendResponseObject(); //async response //trigger receiveData->onDelete

}
json.remove(key); //key processed we don't need the key in the response
}
Expand Down Expand Up @@ -241,7 +247,7 @@ void SysModUI::processJson(JsonVariant json) {
{
//a button never sets the value
if (var["type"] == "button") { //button always
mdl->callVarChangeFun(var, rowNr);
mdl->callVarOnChange(var, rowNr);
if (rowNr != UINT8_MAX) web->getResponseObject()[Variable(var).id()]["rowNr"] = rowNr;
}
else {
Expand Down
Loading

0 comments on commit 2be0136

Please sign in to comment.