Skip to content

Commit

Permalink
Introducing Lambda [this] and E131 refactor
Browse files Browse the repository at this point in the history
AppModLedFixGen
- ledFixGenChFun and generateChFun not static
- use lambda [this] to call these functions

SysModUI
- enable lambda[this] on UCFun type: replace typedef void(*UCFun)(JsonObject); with typedef std::function<void(JsonObject)> UCFun;
- use tUCFun in ucFunctions
- remove checks on duplicats in ucFunctions

UserModE131
- varsToWatch from array to vector and private
- add UI: universe, dmxChannel and patches
- use lambda [this] on e131Tbl for varsToWatch
  • Loading branch information
ewowi committed Oct 28, 2023
1 parent 583bcb9 commit a85c321
Show file tree
Hide file tree
Showing 6 changed files with 120 additions and 65 deletions.
4 changes: 2 additions & 2 deletions src/App/AppEffects.h
Original file line number Diff line number Diff line change
Expand Up @@ -739,8 +739,8 @@ class GEQEffect:public Effect {

if (e131mod->isEnabled) {
uint16_t dmxChannel = mdl->getValue("dmxChannel");
e131mod->patchChannel(dmxChannel + 3, "fadeOut", 255); // TODO: add constant for name
e131mod->patchChannel(dmxChannel + 4, "ripple", 255);
e131mod->patchChannel(3, "fadeOut", 255); // TODO: add constant for name
e131mod->patchChannel(4, "ripple", 255);
}

#endif
Expand Down
8 changes: 4 additions & 4 deletions src/App/AppModLedFixGen.h
Original file line number Diff line number Diff line change
Expand Up @@ -524,7 +524,7 @@ class AppModLedFixGen:public Module {
select.add("3DCube"); //9
select.add("3DGlobe WIP"); //10
select.add("3DGeodesicDome WIP"); //11
}, [](JsonObject var) { //chFun
}, [this](JsonObject var) { //chFun
ledFixGenChFun(var);
}); //ledFixGen

Expand All @@ -533,7 +533,7 @@ class AppModLedFixGen:public Module {
});

ui->initButton(parentVar, "generate", nullptr, false, [](JsonObject var) { //uiFun
}, [](JsonObject var) {
}, [this](JsonObject var) {
generateChFun(var);
});

Expand Down Expand Up @@ -562,7 +562,7 @@ class AppModLedFixGen:public Module {
};

//generate dynamic html for fixture controls
static void ledFixGenChFun(JsonObject var) {
void ledFixGenChFun(JsonObject var) {
JsonObject parentVar = mdl->findVar(var["id"]);
parentVar.remove("n"); //tbd: we should also remove the uiFun and chFun !!
uint8_t value = var["value"];
Expand Down Expand Up @@ -620,7 +620,7 @@ class AppModLedFixGen:public Module {
web->sendDataWs(parentVar); //always send, also when no children, to remove them from ui
}

static void generateChFun(JsonObject var) {
void generateChFun(JsonObject var) {

uint8_t fix = mdl->getValue("ledFixGen");

Expand Down
18 changes: 7 additions & 11 deletions src/App/AppModLeds.h
Original file line number Diff line number Diff line change
Expand Up @@ -201,19 +201,15 @@ class AppModLeds:public Module {

#ifdef USERMOD_E131
// if (e131mod->isEnabled) {
ui->initNumber(parentVar, "dmxChannel", 1, 1, 512, false, [](JsonObject var) { //uiFun
web->addResponse(var["id"], "comment", "First channel (bri, fx, palette + fx channels, total 5 now)");
}, [](JsonObject var) { //chFun
uint16_t dmxChannel = var["value"];
e131mod->patchChannel(dmxChannel + 0, "bri", 255); //should be 256??
e131mod->patchChannel(dmxChannel + 1, "fx", effects.size());
e131mod->patchChannel(dmxChannel + 2, "palette", 8); //tbd: calculate nr of palettes (from select)
e131mod->patchChannel(0, "bri", 255); //should be 256??
e131mod->patchChannel(1, "fx", effects.size());
e131mod->patchChannel(2, "palette", 8); //tbd: calculate nr of palettes (from select)
// //add these temporary to test remote changing of this values do not crash the system
// e131mod->patchChannel(3, "projection", Projections::count);
// e131mod->patchChannel(4, "ledFix", 5); //assuming 5!!!

ui->valChangedForInstancesTemp = true;
});
// //add these temporary to test remote changing of this values do not crash the system
// e131mod->patchChannel(3, "projection", Projections::count);
// e131mod->patchChannel(4, "ledFix", 5); //assuming 5!!!

// }
// else
// USER_PRINTF("Leds e131 not enabled\n");
Expand Down
25 changes: 14 additions & 11 deletions src/Sys/SysModUI.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@
#include "html_ui.h"

//init static variables (https://www.tutorialspoint.com/cplusplus/cpp_static_members.htm)
std::vector<void(*)(JsonObject var)> SysModUI::ucFunctions;
std::vector<UCFun> SysModUI::ucFunctions;
std::vector<VarLoop> SysModUI::loopFunctions;
int SysModUI::varCounter = 1; //start with 1 so it can be negative, see var["o"]
bool SysModUI::valChangedForInstancesTemp = false;
Expand Down Expand Up @@ -172,25 +172,28 @@ JsonObject SysModUI::initVar(JsonObject parent, const char * id, const char * ty
//if uiFun, add it to the list
if (uiFun) {
//if fun already in ucFunctions then reuse, otherwise add new fun in ucFunctions
std::vector<void(*)(JsonObject var)>::iterator itr = find(ucFunctions.begin(), ucFunctions.end(), uiFun);
if (itr!=ucFunctions.end()) //found
var["uiFun"] = distance(ucFunctions.begin(), itr); //assign found function
else { //not found
//lambda update: when replacing typedef void(*UCFun)(JsonObject); with typedef std::function<void(JsonObject)> UCFun; this gives error:
// mismatched types 'T*' and 'std::function<void(ArduinoJson::V6213PB2::JsonObject)>' { return *__it == _M_value; }
// it also looks like functions are not added more then once anyway
// std::vector<UCFun>::iterator itr = find(ucFunctions.begin(), ucFunctions.end(), uiFun);
// if (itr!=ucFunctions.end()) //found
// var["uiFun"] = distance(ucFunctions.begin(), itr); //assign found function
// else { //not found
ucFunctions.push_back(uiFun); //add new function
var["uiFun"] = ucFunctions.size()-1;
}
// }
}

//if chFun, add it to the list
if (chFun) {
//if fun already in ucFunctions then reuse, otherwise add new fun in ucFunctions
std::vector<void(*)(JsonObject var)>::iterator itr = find(ucFunctions.begin(), ucFunctions.end(), chFun);
if (itr!=ucFunctions.end()) //found
var["chFun"] = distance(ucFunctions.begin(), itr); //assign found function
else { //not found
// std::vector<UCFun>::iterator itr = find(ucFunctions.begin(), ucFunctions.end(), chFun);
// if (itr!=ucFunctions.end()) //found
// var["chFun"] = distance(ucFunctions.begin(), itr); //assign found function
// else { //not found
ucFunctions.push_back(chFun); //add new function
var["chFun"] = ucFunctions.size()-1;
}
// }
}

//if loopFun, add it to the list
Expand Down
3 changes: 2 additions & 1 deletion src/Sys/SysModUI.h
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,8 @@
#include "ArduinoJson.h"
#include "Module.h"

typedef void(*UCFun)(JsonObject);
// https://stackoverflow.com/questions/59111610/how-do-you-declare-a-lambda-function-using-typedef-and-then-use-it-by-passing-to
typedef std::function<void(JsonObject)> UCFun;
typedef void(*LoopFun)(JsonObject, uint8_t*);

struct VarLoop {
Expand Down
127 changes: 91 additions & 36 deletions src/User/UserModE131.h
Original file line number Diff line number Diff line change
Expand Up @@ -13,20 +13,12 @@

#include <vector>

#define maxChannels 20

struct VarToWatch {
const char * id = nullptr;
uint16_t max = -1;
uint8_t savedValue = -1;
};
#define maxChannels 513

class UserModE131:public Module {

public:

VarToWatch varsToWatch[maxChannels]; //up to 513

UserModE131() :Module("e131-sACN") {
USER_PRINT_FUNCTION("%s %s\n", __PRETTY_FUNCTION__, name);

Expand All @@ -39,6 +31,52 @@ class UserModE131:public Module {
void setup() {
Module::setup();
USER_PRINT_FUNCTION("%s %s\n", __PRETTY_FUNCTION__, name);

parentVar = ui->initModule(parentVar, name);

ui->initNumber(parentVar, "dmxUni", universe, 1, 512, false, [](JsonObject var) { //uiFun
web->addResponse(var["id"], "label", "Universe");
}, [this](JsonObject var) { //chFun
universe = var["value"];
ui->valChangedForInstancesTemp = true;
});

ui->initNumber(parentVar, "dmxChannel", 1, 1, 512, false, [](JsonObject var) { //uiFun
web->addResponse(var["id"], "label", "Channel");
web->addResponse(var["id"], "comment", "First channel");
}, [](JsonObject var) { //chFun

ui->valChangedForInstancesTemp = true;

ui->processUiFun("e131Tbl"); //rebuild table

});

JsonObject tableVar = ui->initTable(parentVar, "e131Tbl", nullptr, false, [this](JsonObject var) { //uiFun
web->addResponse(var["id"], "label", "Vars to watch");
web->addResponse(var["id"], "comment", "List of instances");
JsonArray rows = web->addResponseA(var["id"], "table");
for (auto varToWatch: varsToWatch) {
JsonArray row = rows.createNestedArray();
row.add(varToWatch.channel + mdl->getValue("dmxChannel").as<uint8_t>());
row.add((char *)varToWatch.id);
row.add(varToWatch.max);
row.add(varToWatch.savedValue);
}
});
ui->initNumber(tableVar, "e131Channel", -1, 1, 512, true, [](JsonObject var) { //uiFun
web->addResponse(var["id"], "label", "Channel");
});
ui->initText(tableVar, "e131Name", nullptr, 32, true, [](JsonObject var) { //uiFun
web->addResponse(var["id"], "label", "Name");
});
ui->initNumber(tableVar, "e131Max", -1, 0, (uint16_t)-1, true, [](JsonObject var) { //uiFun
web->addResponse(var["id"], "label", "Max");
});
ui->initNumber(tableVar, "e131Value", -1, 0, (uint8_t)-1, true, [](JsonObject var) { //uiFun
web->addResponse(var["id"], "label", "Value");
});

}

// void connectedChanged() {
Expand Down Expand Up @@ -71,6 +109,7 @@ class UserModE131:public Module {
e131Created = true;
}
else {
// e131.end()???
e131Created = false;
}
}
Expand All @@ -84,35 +123,42 @@ class UserModE131:public Module {
e131_packet_t packet;
e131.pull(&packet); // Pull packet from ring buffer

for (int i=0; i < maxChannels; i++) {
if (packet.property_values[i] != varsToWatch[i].savedValue) {

USER_PRINTF("Universe %u / %u Channels | Packet#: %u / Errors: %u / CH%d: %u -> %u",
htons(packet.universe), // The Universe for this packet
htons(packet.property_value_count) - 1, // Start code is ignored, we're interested in dimmer data
e131.stats.num_packets, // Packet counter
e131.stats.packet_errors, // Packet error counter
i,
varsToWatch[i].savedValue,
packet.property_values[i]); // Dimmer data for Channel i

varsToWatch[i].savedValue = packet.property_values[i];

if (varsToWatch[i].id != nullptr && varsToWatch[i].max != 0) {
USER_PRINTF(" varsToWatch: %s\n", varsToWatch[i].id);
mdl->setValueI(varsToWatch[i].id, varsToWatch[i].savedValue%(varsToWatch[i].max+1)); // TODO: ugly to have magic string
}
else
USER_PRINTF("\n");
}
}
}
}
for (auto varToWatch=varsToWatch.begin(); varToWatch!=varsToWatch.end(); ++varToWatch) {
for (int i=0; i < maxChannels; i++) {
if (i == varToWatch->channel) {
if (packet.property_values[i] != varToWatch->savedValue) {

USER_PRINTF("Universe %u / %u Channels | Packet#: %u / Errors: %u / CH%d: %u -> %u",
htons(packet.universe), // The Universe for this packet
htons(packet.property_value_count) - 1, // Start code is ignored, we're interested in dimmer data
e131.stats.num_packets, // Packet counter
e131.stats.packet_errors, // Packet error counter
i,
varToWatch->savedValue,
packet.property_values[i]); // Dimmer data for Channel i

varToWatch->savedValue = packet.property_values[i];

if (varToWatch->id != nullptr && varToWatch->max != 0) {
USER_PRINTF(" varsToWatch: %s\n", varToWatch->id);
mdl->setValueI(varToWatch->id, varToWatch->savedValue%(varToWatch->max+1)); // TODO: ugly to have magic string
}
else
USER_PRINTF("\n");
}//!= savedValue
}//if channel
}//maxChannels
} //for varToWatch
} //!e131.isEmpty()
} //loop

void patchChannel(uint8_t channel, const char * id, uint8_t max = 255) {
varsToWatch[channel].id = id;
varsToWatch[channel].savedValue = 0; // Always reset when (re)patching so variable gets set to DMX value even if unchanged
varsToWatch[channel].max = max;
VarToWatch varToWatch;
varToWatch.channel = channel;
varToWatch.id = id;
varToWatch.savedValue = 0; // Always reset when (re)patching so variable gets set to DMX value even if unchanged
varToWatch.max = max;
varsToWatch.push_back(varToWatch);
}

// uint8_t getValue(const char * id) {
Expand All @@ -126,6 +172,15 @@ class UserModE131:public Module {
// }

private:
struct VarToWatch {
uint16_t channel;
const char * id = nullptr;
uint16_t max = -1;
uint8_t savedValue = -1;
};

std::vector<VarToWatch> varsToWatch;

ESPAsyncE131 e131;
boolean e131Created = false;
uint16_t universe = 1;
Expand Down

0 comments on commit a85c321

Please sign in to comment.