Skip to content

Commit

Permalink
Value update improvements
Browse files Browse the repository at this point in the history
AppEffects, AppLeds: - move SharedData to Leds

SysModModel: setValue: split into setValue and setValueNoRoCheck for initVarAndUpdate of ro values

SysModSytem: simplify RO values (chipInfo, version, restart)

SysModUI: initVarAndUpdate: deal with RO and not connected -> store in model

SysModWeb: sendResponseObject in loop1s for all looptask updates

UserModInstances: stage vars valueFun: store in responseObject instead of variable updaterow disabled (temporary)
  • Loading branch information
ewowi committed Feb 20, 2024
1 parent 03eb004 commit 94e3975
Show file tree
Hide file tree
Showing 11 changed files with 142 additions and 139 deletions.
97 changes: 25 additions & 72 deletions src/App/AppEffects.h
Original file line number Diff line number Diff line change
Expand Up @@ -20,53 +20,6 @@ uint8_t gHue = 0; // rotating "base color" used by many of the patterns
unsigned long call = 0; //not used at the moment (don't use in effect calculations)
unsigned long now = millis();

//StarMod implementation of segment.data
class SharedData {
private:
byte *data;
uint16_t index = 0;
uint16_t bytesAllocated = 0;

public:
SharedData() {
bytesAllocated = 1024;
data = (byte*) malloc(bytesAllocated); //start with 100 bytes
}

void clear() {
memset(data, 0, bytesAllocated);
}

void allocate(size_t size) {
index = 0;
if (size > bytesAllocated) {
USER_PRINTF("realloc %d %d %d\n", index, size, bytesAllocated);
data = (byte*)realloc(data, size);
bytesAllocated = size;
}
}

template <typename Type>
Type* bind(int length = 1) {
Type* returnValue = reinterpret_cast<Type*>(data + index);
index += length * sizeof(Type); //add consumed amount of bytes, index is next byte which will be pointed to
if (index > bytesAllocated) {
USER_PRINTF("bind too big %d %d\n", index, bytesAllocated);
return nullptr;
}
return returnValue;
}

bool allocated() {
if (index>bytesAllocated) {
USER_PRINTF("not all variables bound %d %d\n", index, bytesAllocated);
return false;
}
return true;
}

} sharedData;

//should not contain variables/bytes to keep mem as small as possible!!
class Effect {
public:
Expand Down Expand Up @@ -466,14 +419,14 @@ class Octopus2D: public Effect {
uint8_t legs = mdl->getValue("Legs", leds.rowNr);
CRGBPalette16 pal = getPalette(leds.rowNr);

sharedData.allocate(sizeof(map_t) * leds.size.x * leds.size.y + 2 * sizeof(uint8_t) + 2 * sizeof(uint16_t) + sizeof(uint32_t));
map_t *rMap = sharedData.bind<map_t>(leds.size.x * leds.size.y); //array
uint8_t *offsX = sharedData.bind<uint8_t>();
uint8_t *offsY = sharedData.bind<uint8_t>();
uint16_t *aux0 = sharedData.bind<uint16_t>();
uint16_t *aux1 = sharedData.bind<uint16_t>();
uint32_t *step = sharedData.bind<uint32_t>();
if (!sharedData.allocated()) return;
leds.sharedData.allocate(sizeof(map_t) * leds.size.x * leds.size.y + 2 * sizeof(uint8_t) + 2 * sizeof(uint16_t) + sizeof(uint32_t));
map_t *rMap = leds.sharedData.bind<map_t>(leds.size.x * leds.size.y); //array
uint8_t *offsX = leds.sharedData.bind<uint8_t>();
uint8_t *offsY = leds.sharedData.bind<uint8_t>();
uint16_t *aux0 = leds.sharedData.bind<uint16_t>();
uint16_t *aux1 = leds.sharedData.bind<uint16_t>();
uint32_t *step = leds.sharedData.bind<uint32_t>();
if (!leds.sharedData.allocated()) return;

Coord3D pos = {0,0,0};

Expand Down Expand Up @@ -590,9 +543,9 @@ class BouncingBalls1D: public Effect {
uint8_t numBalls = mdl->getValue("balls", leds.rowNr);
CRGBPalette16 pal = getPalette(leds.rowNr);

sharedData.allocate(sizeof(Ball) * maxNumBalls);
Ball *balls = sharedData.bind<Ball>(maxNumBalls); //array
if (!sharedData.allocated()) return;
leds.sharedData.allocate(sizeof(Ball) * maxNumBalls);
Ball *balls = leds.sharedData.bind<Ball>(maxNumBalls); //array
if (!leds.sharedData.allocated()) return;

leds.fill_solid(CRGB::Black);

Expand Down Expand Up @@ -667,9 +620,9 @@ class RingRandomFlow:public RingEffect {
}

void loop(Leds &leds) {
sharedData.allocate(sizeof(uint8_t) * leds.nrOfLeds);
uint8_t *hue = sharedData.bind<uint8_t>(leds.nrOfLeds); //array
if (!sharedData.allocated()) return;
leds.sharedData.allocate(sizeof(uint8_t) * leds.nrOfLeds);
uint8_t *hue = leds.sharedData.bind<uint8_t>(leds.nrOfLeds); //array
if (!leds.sharedData.allocated()) return;

hue[0] = random(0, 255);
for (int r = 0; r < leds.nrOfLeds; r++) {
Expand Down Expand Up @@ -789,9 +742,9 @@ class PopCorn1D: public Effect {
uint8_t intensity = mdl->getValue("intensity", leds.rowNr);
bool useaudio = mdl->getValue("useaudio", leds.rowNr);

sharedData.allocate(sizeof(Spark) * maxNumPopcorn);
Spark *popcorn = sharedData.bind<Spark>(maxNumPopcorn); //array
if (!sharedData.allocated()) return;
leds.sharedData.allocate(sizeof(Spark) * maxNumPopcorn);
Spark *popcorn = leds.sharedData.bind<Spark>(maxNumPopcorn); //array
if (!leds.sharedData.allocated()) return;

float gravity = -0.0001 - (speed/200000.0); // m/s/s
gravity *= leds.nrOfLeds;
Expand Down Expand Up @@ -866,10 +819,10 @@ class GEQEffect:public Effect {
}

void loop(Leds &leds) {
sharedData.allocate(sizeof(uint16_t) * leds.size.x + sizeof(uint32_t));
uint16_t *previousBarHeight = sharedData.bind<uint16_t>(leds.size.x); //array
uint32_t *step = sharedData.bind<uint32_t>();
if (!sharedData.allocated()) return;
leds.sharedData.allocate(sizeof(uint16_t) * leds.size.x + sizeof(uint32_t));
uint16_t *previousBarHeight = leds.sharedData.bind<uint16_t>(leds.size.x); //array
uint32_t *step = leds.sharedData.bind<uint32_t>();
if (!leds.sharedData.allocated()) return;

const int NUM_BANDS = NUM_GEQ_CHANNELS ; // map(SEGMENT.custom1, 0, 255, 1, 16);

Expand Down Expand Up @@ -1029,9 +982,9 @@ class FreqMatrix:public Effect {
}

void loop(Leds &leds) {
sharedData.allocate(sizeof(uint8_t));
uint8_t *aux0 = sharedData.bind<uint8_t>();
if (!sharedData.allocated()) return;
leds.sharedData.allocate(sizeof(uint8_t));
uint8_t *aux0 = leds.sharedData.bind<uint8_t>();
if (!leds.sharedData.allocated()) return;

uint8_t speed = mdl->getValue("speed", leds.rowNr);
uint8_t fx = mdl->getValue("Sound effect", leds.rowNr);
Expand Down Expand Up @@ -1171,7 +1124,7 @@ class Effects {

if (leds.fx < effects.size()) {

sharedData.clear(); //make sure all values are 0
leds.sharedData.clear(); //make sure all values are 0

for (JsonObject var: var["n"].as<JsonArray>()) { //for all controls
if (mdl->varOrder(var) >= 0) { //post init
Expand Down
52 changes: 52 additions & 0 deletions src/App/AppLeds.h
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,56 @@

class Fixture; //forward


//StarMod implementation of segment.data
class SharedData {
private:
byte *data;
uint16_t index = 0;
uint16_t bytesAllocated = 0;

public:
SharedData() {
bytesAllocated = 1024;
data = (byte*) malloc(bytesAllocated); //start with 100 bytes
}

void clear() {
memset(data, 0, bytesAllocated);
}

void allocate(size_t size) {
index = 0;
if (size > bytesAllocated) {
USER_PRINTF("realloc %d %d %d\n", index, size, bytesAllocated);
data = (byte*)realloc(data, size);
bytesAllocated = size;
}
}

template <typename Type>
Type* bind(int length = 1) {
Type* returnValue = reinterpret_cast<Type*>(data + index);
index += length * sizeof(Type); //add consumed amount of bytes, index is next byte which will be pointed to
if (index > bytesAllocated) {
USER_PRINTF("bind too big %d %d\n", index, bytesAllocated);
return nullptr;
}
return returnValue;
}

bool allocated() {
if (index>bytesAllocated) {
USER_PRINTF("not all variables bound %d %d\n", index, bytesAllocated);
return false;
}
return true;
}

};



class Leds {

public:
Expand All @@ -48,6 +98,8 @@ class Leds {
uint8_t effectDimension = -1;
Coord3D startPos = {0,0,0}, endPos = {7,7,0}; //default

SharedData sharedData;

std::vector<std::vector<uint16_t>> mappingTable;

uint16_t XY( uint8_t x, uint8_t y) {
Expand Down
4 changes: 1 addition & 3 deletions src/App/AppModLeds.h
Original file line number Diff line number Diff line change
Expand Up @@ -205,11 +205,9 @@ class AppModLeds:public SysModule {
ui->initText(tableVar, "fxSize", nullptr, 32, true, [this](JsonObject var, uint8_t rowNr, uint8_t funType) { switch (funType) { //varFun
case f_ValueFun:
for (std::vector<Leds>::iterator leds=fixture.ledsList.begin(); leds!=fixture.ledsList.end(); ++leds) {
// for (uint8_t rowNr = 0; rowNr < fixture.ledsList.size(); rowNr++) {
USER_PRINTF("fxSize valueFun %d %d %d\n", fixture.ledsList.size(), rowNr, fixture.ledsList[rowNr].rowNr);
// Leds leds = fixture.ledsList[rowNr];
char message[32];
print->fFormat(message, sizeof(message)-1, "%d x %d x %d = %d", leds->size.x, leds->size.y, leds->size.z, leds->nrOfLeds);
USER_PRINTF("fxSize[%d]([%d 0f %d]) = %s\n", leds - fixture.ledsList.begin(), fixture.ledsList[leds - fixture.ledsList.begin()].rowNr, fixture.ledsList.size(), message);
mdl->setValue(var, JsonString(message, JsonString::Copied), leds - fixture.ledsList.begin()); //rowNr
}
return true;
Expand Down
9 changes: 7 additions & 2 deletions src/Sys/SysModModel.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ SysModModel::SysModModel() :SysModule("Model") {
USER_PRINTF("Reading model from /model.json... (deserializeConfigFromFS)\n");
if (files->readObjectFromFile("/model.json", model)) {//not part of success...
// print->printJson("Read model", *model);
web->sendDataWs(*model);
// web->sendDataWs(*model);
} else {
root = model->to<JsonArray>(); //re create the model as it is corrupted by readFromFile
}
Expand Down Expand Up @@ -63,6 +63,11 @@ void SysModModel::setup() {
ui->setLabel(var, "Delete obsolete variables");
ui->setComment(var, "WIP");
return true;
case f_ChangeFun:
model->to<JsonArray>(); //create
if (files->readObjectFromFile("/model.json", model)) {//not part of success...
}
return true;
default: return false;
}});
}
Expand Down Expand Up @@ -128,7 +133,7 @@ void SysModModel::cleanUpModel(JsonObject parent, bool oPos, bool ro) {
//remove ro values (ro vars cannot be deleted as SM uses these vars)
// remove if var is ro or table of var is ro (ro table can have non ro vars e.g. instance table)
if (ro && ((parent["type"] == "table" && varRO(parent)) || varRO(var))) {// && !var["value"].isNull())
// if (ro && var["ro"].as<bool>()) {// && !var["value"].isNull())
// if (ro && varRO(var)) {// && !var["value"].isNull())
USER_PRINTF("remove ro value %s\n", varID(var));
var.remove("value");
}
Expand Down
21 changes: 14 additions & 7 deletions src/Sys/SysModModel.h
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@
#include "SysModule.h"
#include "SysModPrint.h"
#include "SysModWeb.h"
#include "SysModules.h" //isConnected

typedef std::function<void(JsonObject)> FindFun;
typedef std::function<void(JsonObject, size_t)> ChangeFun;
Expand Down Expand Up @@ -175,14 +176,22 @@ class SysModModel:public SysModule {

template <typename Type>
JsonObject setValue(JsonObject var, Type value, uint8_t rowNr = UINT8_MAX) {
// print->printJson("setValueB", var);
bool changed = false;
if (var["ro"].as<bool>()) {
if (varRO(var)) {
// print->printJson("setValue ro to ws", web->getResponseObject());
web->addResponse(var["id"], "value", value, rowNr);
changed = true;
callChangeFun(var, rowNr); //always call change fun, if present
return var;
}
else if (rowNr == UINT8_MAX) { //normal situation
else
return setValueNoROCheck(var, value, rowNr);
}

template <typename Type>
JsonObject setValueNoROCheck(JsonObject var, Type value, uint8_t rowNr = UINT8_MAX) {

bool changed = false;

if (rowNr == UINT8_MAX) { //normal situation
if (var["value"].isNull() || var["value"].as<Type>() != value) { //const char * will be JsonString so comparison works
JsonString oldValue = JsonString(var["value"], JsonString::Copied);
var["value"] = value;
Expand Down Expand Up @@ -259,8 +268,6 @@ class SysModModel:public SysModule {
va_end(args);

web->addResponse(id, "value", JsonString(value, JsonString::Copied));

web->sendResponseObject();
}

JsonVariant getValue(const char * id, uint8_t rowNr = UINT8_MAX) {
Expand Down
18 changes: 3 additions & 15 deletions src/Sys/SysModSystem.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,8 @@ void SysModSystem::setup() {

ui->initText(parentVar, "loops", nullptr, 16, true);

ui->initText(parentVar, "chip", nullptr, 16, true);
print->fFormat(chipInfo, sizeof(chipInfo)-1, "%s %s c#:%d %d mHz f:%d KB %d mHz %d", ESP.getChipModel(), ESP.getSdkVersion(), ESP.getChipCores(), ESP.getCpuFreqMHz(), ESP.getFlashChipSize()/1024, ESP.getFlashChipSpeed()/1000000, ESP.getFlashChipMode());
ui->initText(parentVar, "chip", chipInfo, 16, true);

ui->initProgress(parentVar, "heap", UINT16_MAX, 0, ESP.getHeapSize()/1000, true, [](JsonObject var, uint8_t rowNr, uint8_t funType) { switch (funType) { //varFun
case f_ValueFun:
Expand Down Expand Up @@ -95,9 +96,6 @@ void SysModSystem::setup() {
}});

ui->initSelect(parentVar, "reset0", (int)rtc_get_reset_reason(0), true, [](JsonObject var, uint8_t rowNr, uint8_t funType) { switch (funType) { //varFun
case f_ValueFun:
mdl->setValue(var, rtc_get_reset_reason(0));
return true;
case f_UIFun:
ui->setLabel(var, "Reset 0");
ui->setComment(var, "Reason Core 0");
Expand All @@ -108,9 +106,6 @@ void SysModSystem::setup() {

if (ESP.getChipCores() > 1)
ui->initSelect(parentVar, "reset1", (int)rtc_get_reset_reason(1), true, [](JsonObject var, uint8_t rowNr, uint8_t funType) { switch (funType) { //varFun
case f_ValueFun:
mdl->setValue(var, rtc_get_reset_reason(1));
return true;
case f_UIFun:
ui->setLabel(var, "Reset 1");
ui->setComment(var, "Reason Core 1");
Expand All @@ -120,9 +115,6 @@ void SysModSystem::setup() {
}});

ui->initSelect(parentVar, "restartReason", (int)esp_reset_reason(), true, [](JsonObject var, uint8_t rowNr, uint8_t funType) { switch (funType) { //varFun
case f_ValueFun:
mdl->setValue(var, esp_reset_reason());
return true;
case f_UIFun:
ui->setLabel(var, "Restart");
ui->setComment(var, "Reason restart");
Expand All @@ -142,7 +134,7 @@ void SysModSystem::setup() {

USER_PRINTF("version %s %s %s %d:%d:%d\n", version, __DATE__, __TIME__, hour, minute, second);

ui->initText(parentVar, "version", nullptr, 16, true);
ui->initText(parentVar, "version", version, 16, true);
// ui->initText(parentVar, "date", __DATE__, 16, true);
// ui->initText(parentVar, "time", __TIME__, 16, true);

Expand Down Expand Up @@ -177,10 +169,6 @@ void SysModSystem::loop1s() {
loopCounter = 0;
}
void SysModSystem::loop10s() {
mdl->setValue("version", JsonString(version)); //make sure ui shows the right version !!!never do this in uiFun as it interupts with uiFun sendDataWS!!

mdl->setUIValueV("chip", "%s %s c#:%d %d mHz f:%d KB %d mHz %d", ESP.getChipModel(), ESP.getSdkVersion(), ESP.getChipCores(), ESP.getCpuFreqMHz(), ESP.getFlashChipSize()/1024, ESP.getFlashChipSpeed()/1000000, ESP.getFlashChipMode());

ui->callVarFun(mdl->findVar("heap"));
ui->callVarFun(mdl->findVar("stack"));

Expand Down
1 change: 1 addition & 0 deletions src/Sys/SysModSystem.h
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ class SysModSystem:public SysModule {

public:
char version[16] = "";
char chipInfo[64] = "";

SysModSystem();
void setup();
Expand Down
Loading

0 comments on commit 94e3975

Please sign in to comment.