Skip to content

Commit

Permalink
Refactor onAdd/onDelete (incl bugfix)
Browse files Browse the repository at this point in the history
SysModFiles
- remove onAdd (done by callVarFun)

SysModUI
- callVarFun: delete pointers after calling var.onDelete
- processJson: onAdd/onDelete: do not remove key so swEvent can return the response
  • Loading branch information
ewoudwijma committed Oct 7, 2024
1 parent 866d05c commit 731f2da
Show file tree
Hide file tree
Showing 6 changed files with 52 additions and 61 deletions.
10 changes: 1 addition & 9 deletions src/Sys/SysModFiles.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -34,12 +34,6 @@ void SysModFiles::setup() {
case onUI:
ui->setComment(var, "List of files");
return true;
case onAdd:
rowNr = fileNames.size();
web->getResponseObject()["onAdd"]["rowNr"] = rowNr; //also done in callVarFun??
//add a row with all defaults
//tbd: File upload does not call onAdd (bug?)
return true;
case onDelete:
if (rowNr != UINT8_MAX && rowNr < fileNames.size()) {
const char * fileName = fileNames[rowNr].s;
Expand All @@ -54,11 +48,9 @@ void SysModFiles::setup() {
strlcpy(web->lastFileUpdated, name, sizeof(web->lastFileUpdated));
}
#endif

// print->printVar(var);
// ppf("\n");
}
return true;
//tbd: File upload does not call onAdd (bug?)
default: return false;
}});

Expand Down
2 changes: 1 addition & 1 deletion src/Sys/SysModSystem.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -211,7 +211,7 @@ void SysModSystem::setup() {

ui->initFileUpload(parentVar, "update", nullptr, UINT16_MAX, false, [](JsonObject var, uint8_t rowNr, uint8_t funType) { switch (funType) { //varFun
case onUI:
ui->setComment(var, "OTA Update");
ui->setComment(var, "OTA Firmware Update");
return true;
default: return false;
}});
Expand Down
16 changes: 4 additions & 12 deletions src/Sys/SysModUI.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -179,24 +179,16 @@ void SysModUI::processJson(JsonVariant json) {
uint8_t 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;
}
callVarFun(var, rowNr, pair.key() == "onAdd"?onAdd:onDelete);

//first remove the deleted row both on server and on client(s)
if (pair.key() == "onDelete") {
ppf("onDelete remove values\n");
ppf("onDelete remove removeValuesForRow\n");
Variable(var).removeValuesForRow(rowNr);
doWS = true;
}

if (doWS)
web->sendResponseObject(); //async response //trigger receiveData->onDelete

}
json.remove(key); //key processed we don't need the key in the response
// we need to send back the key so UI can add or delete the value
// json.remove(key); //key processed we don't need the key in the response
}
else if (pair.key() == "onUI") { //JsonString can do ==
//find the select var and collect it's options...
Expand Down
77 changes: 42 additions & 35 deletions src/Sys/SysModUI.h
Original file line number Diff line number Diff line change
Expand Up @@ -319,8 +319,36 @@ class SysModUI: public SysModule {
Variable variable = Variable(var);
bool result = false;

//call varFun if exists
if (!var["fun"].isNull()) {//isNull needed here!
size_t funNr = var["fun"];
if (funNr < varFunctions.size()) {
result = varFunctions[funNr](var, rowNr, funType);
if (result && !variable.readOnly()) { //send rowNr = 0 if no rowNr
//only print vars with a value and not onSetValue as that changes a lot due to insTbl clTbl etc (tbd)
//don't print if onSetValue or oldValue is null
if (funType != onSetValue && (!var["oldValue"].isNull() || ((rowNr != UINT8_MAX) && !var["oldValue"][rowNr].isNull()))) {
ppf("%sFun %s", funType==onSetValue?"val":funType==onUI?"ui":funType==onChange?"ch":funType==onAdd?"add":funType==onDelete?"del":"other", Variable(var).id());
if (rowNr != UINT8_MAX) {
ppf("[%d] (", rowNr);
if (funType == onChange) ppf("%s ->", var["oldValue"][rowNr].as<String>().c_str());
ppf("%s)\n", var["value"][rowNr].as<String>().c_str());
}
else {
ppf(" (");
if (funType == onChange) ppf("%s ->", var["oldValue"].as<String>().c_str());
ppf("%s)\n", variable.valueString().c_str());
}
}
} //varFun exists
}
else
ppf("dev callVarFun function nr %s.%s outside bounds %d >= %d\n", variable.pid(), variable.id(), funNr, varFunctions.size());
} //varFun exists

//delete pointers after calling var.onDelete as var.onDelete might need the values
if (funType == onAdd || funType == onDelete) {
//do this before calling onDelete

print->printJson("callVarFun add/del", var);
//if delete, delete also from vector ...
//find the columns of the table
Expand All @@ -338,54 +366,33 @@ class SysModUI: public SysModule {
//pointer checks
if (childVar["type"] == "select" || childVar["type"] == "range" || childVar["type"] == "pin") {
std::vector<uint8_t> *valuePointer = (std::vector<uint8_t> *)pointer;
(*valuePointer).erase((*valuePointer).begin() + rowNr);
if (rowNr < (*valuePointer).size())
(*valuePointer).erase((*valuePointer).begin() + rowNr);
} else if (childVar["type"] == "number") {
std::vector<uint16_t> *valuePointer = (std::vector<uint16_t> *)pointer;
(*valuePointer).erase((*valuePointer).begin() + rowNr);
if (rowNr < (*valuePointer).size())
(*valuePointer).erase((*valuePointer).begin() + rowNr);
} else if (childVar["type"] == "checkbox") {
std::vector<bool> *valuePointer = (std::vector<bool> *)pointer;
(*valuePointer).erase((*valuePointer).begin() + rowNr);
if (rowNr < (*valuePointer).size())
(*valuePointer).erase((*valuePointer).begin() + rowNr);
} else if (childVar["type"] == "text" || childVar["type"] == "fileEdit") {
std::vector<VectorString> *valuePointer = (std::vector<VectorString> *)pointer;
(*valuePointer).erase((*valuePointer).begin() + rowNr);
if (rowNr < (*valuePointer).size())
(*valuePointer).erase((*valuePointer).begin() + rowNr);
} else if (childVar["type"] == "coord3D") {
std::vector<Coord3D> *valuePointer = (std::vector<Coord3D> *)pointer;
(*valuePointer).erase((*valuePointer).begin() + rowNr);
if (rowNr < (*valuePointer).size())
(*valuePointer).erase((*valuePointer).begin() + rowNr);
}
else
print->printJson("dev callVarFun onDelete type not supported yet", childVar);
}
}
}
} //onDelete
web->getResponseObject()[funType==onAdd?"onAdd":"onDelete"]["rowNr"] = rowNr;
}

//call varFun if exists
if (!var["fun"].isNull()) {//isNull needed here!
size_t funNr = var["fun"];
if (funNr < varFunctions.size()) {
result = varFunctions[funNr](var, rowNr, funType);
if (result && !variable.readOnly()) { //send rowNr = 0 if no rowNr
//only print vars with a value and not onSetValue as that changes a lot due to insTbl clTbl etc (tbd)
//don't print if onSetValue or oldValue is null
if (funType != onSetValue && (!var["oldValue"].isNull() || ((rowNr != UINT8_MAX) && !var["oldValue"][rowNr].isNull()))) {
ppf("%sFun %s", funType==onSetValue?"val":funType==onUI?"ui":funType==onChange?"ch":funType==onAdd?"add":funType==onDelete?"del":"other", Variable(var).id());
if (rowNr != UINT8_MAX) {
ppf("[%d] (", rowNr);
if (funType == onChange) ppf("%s ->", var["oldValue"][rowNr].as<String>().c_str());
ppf("%s)\n", var["value"][rowNr].as<String>().c_str());
}
else {
ppf(" (");
if (funType == onChange) ppf("%s ->", var["oldValue"].as<String>().c_str());
ppf("%s)\n", variable.valueString().c_str());
}
}
}
}
else
ppf("dev callVarFun function nr %s.%s outside bounds %d >= %d\n", variable.pid(), variable.id(), funNr, varFunctions.size());
}
print->printJson("callVarFun add/del response", web->getResponseObject());
} //onAdd onDelete

//for ro variables, call onSetValue to add also the value in responseDoc (as it is not stored in the model)
if (funType == onUI && variable.readOnly()) {
Expand Down
2 changes: 1 addition & 1 deletion src/Sys/SysModWeb.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -324,7 +324,7 @@ void SysModWeb::wsEvent(WebSocket * ws, WebClient * client, AwsEventType type, v
sendResponseObject(isOnUI?client:nullptr); //onUI only send to requesting client async response
}
else {
ppf("WS_EVT_DATA no responseDoc\n");
ppf("wsEvent no responseDoc\n");
client->text("{\"success\":true}"); // we have to send something back otherwise WS connection closes
}
}
Expand Down
6 changes: 3 additions & 3 deletions src/User/UserModLive.h
Original file line number Diff line number Diff line change
Expand Up @@ -118,7 +118,7 @@ class UserModLive:public SysModule {

parentVar = ui->initUserMod(parentVar, name, 6310);

ui->initSelect(parentVar, "script", UINT16_MAX, false, [this](JsonObject var, uint8_t rowNr, uint8_t funType) { switch (funType) { //varFun
ui->initSelect(parentVar, "script", UINT8_MAX, false, [this](JsonObject var, uint8_t rowNr, uint8_t funType) { switch (funType) { //varFun
case onUI: {
// ui->setComment(var, "Fixture to display effect on");
JsonArray options = ui->setOptions(var);
Expand Down Expand Up @@ -148,13 +148,13 @@ class UserModLive:public SysModule {

ui->initText(parentVar, "fps1", nullptr, 10, true, [this](JsonObject var, uint8_t rowNr, uint8_t funType) { switch (funType) { //varFun
case onLoop1s:
mdl->setValue(var, "%.0f /s", fps);
mdl->setValue(var, "%.0f /s", fps, 0); //0 is to force format overload used
return true;
default: return false;
}});
ui->initText(parentVar, "fps2", nullptr, 10, true, [this](JsonObject var, uint8_t rowNr, uint8_t funType) { switch (funType) { //varFun
case onLoop1s:
mdl->setValue(var, "%d /s", frameCounter);
mdl->setValue(var, "%d /s", frameCounter, 0); //0 is to force format overload used
frameCounter = 0;
return true;
default: return false;
Expand Down

0 comments on commit 731f2da

Please sign in to comment.