Skip to content

Commit

Permalink
One Fixture containing a list of Leds classes, each running an effect
Browse files Browse the repository at this point in the history
index.js
- changeHTML: options: add th: update all select cells as well
- rename generateHTML to createHTML

AppEffects
- replace leds.distance by leds.fixture->distance
- setEffect: remove rowNr if needed

AppFixture: extracted from AppLeds:
- Projections
- leds -> ledsList
- projectAndMap
- vector pointer loops!!!
- use Coord3D pixel
- use ledsList and leds functions (1 fixture: multiple leds)
- distance incl distance (Coord3D)

AppLeds
- mappingTable public
- set/getPixelColor, fadeToBlackBy, fill_solid,  fill_rainbow to .cpp (due to AppLeds cross link with Fixture)
- add XYZ(Coord3D)

AppModLeds
- include AppFixture (which includes leds)
- remove value from fxTbl (childs do it theirselves)
- add fxLayout (WIP)
- call effect loop for each leds class (basis for multiple effects on same fixture)

SysModModel
- setChFunAndWs: send chFun with rowNr is 0 if no rowNr (WIP)
- getValue: if no valid rowNr (null or too big) return value[0]
- Coord3D: add operator >= -= and -

SysModUI: InitVarAndUpdate: call changeFun with rowNr 0 if value not array
  • Loading branch information
ewowi committed Jan 31, 2024
1 parent 11ffab3 commit 26c0068
Show file tree
Hide file tree
Showing 18 changed files with 1,931 additions and 1,821 deletions.
1 change: 0 additions & 1 deletion data/app.js
Original file line number Diff line number Diff line change
Expand Up @@ -281,7 +281,6 @@ function preview3D(canvasNode, buffer) {
}

// controls.rotateSpeed = 0.4;
// console.log(buffer[1], buffer[2], buffer[3]);
scene.rotation.x = buffer[1];
scene.rotation.y = buffer[2];
scene.rotation.z = buffer[3];
Expand Down
45 changes: 27 additions & 18 deletions data/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -69,8 +69,8 @@ function makeWS() {
if (!found) {
let module = json;
model.push((module)); //this is the model
console.log("WS receive generateHTML", module);
generateHTML(module); //no parentNode
console.log("WS receive createHTML", module);
createHTML(module); //no parentNode

if (module.id == "System") {
console.log("system changes", module);
Expand Down Expand Up @@ -137,17 +137,17 @@ function linearToLogarithm(json, value) {
return Math.round(result);
}

function generateHTML(json, parentNode = null, rowNr = -1) {
function createHTML(json, parentNode = null, rowNr = -1) {

// console.log("generateHTML", json, parentNode);
// console.log("createHTML", json, parentNode);
if (Array.isArray(json)) {
//sort according to o value
json.sort(function(a,b) {
return Math.abs(a.o) - Math.abs(b.o); //o is order nr (ignore negatives for the time being)
});

for (let variable of json) { //if isArray then variables of array
generateHTML(variable, parentNode, rowNr);
createHTML(variable, parentNode, rowNr);
}
}
else { // json is variable
Expand Down Expand Up @@ -306,7 +306,7 @@ function generateHTML(json, parentNode = null, rowNr = -1) {
let cmarkNode = cE("span");
cmarkNode.className = "checkmark";
varNode.appendChild(cmarkNode);
} else if (variable.type == "button") {
} else if (variable.type == "button") {
varNode = cE("input");
varNode.type = variable.type;
varNode.disabled = variable.ro;
Expand Down Expand Up @@ -409,10 +409,10 @@ function generateHTML(json, parentNode = null, rowNr = -1) {
ndivNode.id = variable.id + (isPartOfTableRow?"#" + rowNr:"") + "_n";
ndivNode.className = "ndiv";
divNode.appendChild(ndivNode); // add to the parent of the node
generateHTML(variable.n, ndivNode, rowNr);
createHTML(variable.n, ndivNode, rowNr);
}
else
generateHTML(variable.n, varNode, rowNr); //details (e.g. module)
createHTML(variable.n, varNode, rowNr); //details (e.g. module)
}

//don't call uiFun on table rows (the table header calls uiFun and propagate this to table row columns in changeHTML when needed - e.g. select)
Expand Down Expand Up @@ -450,7 +450,7 @@ function genTableRowHTML(json, parentNode = null, rowNr = -1) {
for (let columnVar of variable.n) {
let tdNode = cE("td");
trNode.appendChild(tdNode);
generateHTML(columnVar, tdNode, rowNr); //will also do the values
createHTML(columnVar, tdNode, rowNr); //will also do the values
}
if (!variable.ro) {
let tdNode = cE("td");
Expand Down Expand Up @@ -502,7 +502,7 @@ function receiveData(json) {
let rowNr = variable["rowNr"]!=null?variable["rowNr"]:-1;
let nodeId = variable.id + ((rowNr != -1)?"#" + rowNr:"");
//if var object with .n, create .n (e.g. see setEffect and fixtureGenChFun, tbd: )
console.log("receiveData details", key, variable);
console.log("receiveData details", key, variable, nodeId);
if (gId(nodeId + "_n")) gId(nodeId + "_n").remove(); //remove old ndiv

//create new ndiv
Expand All @@ -511,7 +511,7 @@ function receiveData(json) {
ndivNode.id = nodeId + "_n";
ndivNode.className = "ndiv";
gId(nodeId).parentNode.appendChild(ndivNode);
generateHTML(variable.n, ndivNode, rowNr);
createHTML(variable.n, ndivNode, rowNr);
}
flushUIFunCommands(); //make sure uiFuns of new elements are called
}
Expand Down Expand Up @@ -646,13 +646,22 @@ function changeHTML(variable, node, commandJson, rowNr = -1) {
} //comment

if (commandJson.hasOwnProperty("options")) { //replace the body of a table
// console.log("changeHTML options", variable, node, commandJson, rowNr);

let selectNodes = [];
//check if there are also column select cells which also needs to be updated
if (nodeType == "th") {
let tableNode = node.parentNode.parentNode.parentNode;
selectNodes = tableNode.querySelector('tbody').querySelectorAll(`select[id*="${variable.id}"]`);
}
else if (nodeType == "select") { //span/ro will be set in .value
selectNodes.push(node);
}

if (nodeType == "select") { //span/ro will be set in .value
for (let selectNode of selectNodes) {
//remove all old options first
var index = 0;
while (node.options && node.options.length > 0) {
node.remove(0);
while (selectNode.options && selectNode.options.length > 0) {
selectNode.remove(0);
}
for (var value of commandJson.options) {
let optNode = cE("option");
Expand All @@ -664,7 +673,7 @@ function changeHTML(variable, node, commandJson, rowNr = -1) {
optNode.value = index;
optNode.text = value;
}
node.appendChild(optNode);
selectNode.appendChild(optNode);
index++;
}
}
Expand Down Expand Up @@ -741,7 +750,7 @@ function changeHTML(variable, node, commandJson, rowNr = -1) {
if (newRowNr < valueLength)
changeHTML(variable, cellNode, {"value":newValue, "chk":"column"}, newRowNr);
else
changeHTML(variable, cellNode, {"value":null, "chk":"column"}, newRowNr);
changeHTML(variable, cellNode, {"value":null, "chk":"column"}, newRowNr); //new row cell has no value
}
else
console.log("changeHTML th cellNode not found", node, node.id + "#" + newRowNr);
Expand Down Expand Up @@ -919,7 +928,7 @@ function findVar(id, parent = model) {
// console.log("findVar", id, parent, model);

let foundVar = null;
for( var variable of parent) {
for (var variable of parent) {
if (foundVar == null) {
if (variable.id == id)
foundVar = variable;
Expand Down
52 changes: 25 additions & 27 deletions src/App/AppEffects.h
Original file line number Diff line number Diff line change
Expand Up @@ -223,7 +223,7 @@ class BPMEffect: public Effect {
// colored stripes pulsing at a defined Beats-Per-Minute (BPM)
uint8_t BeatsPerMinute = 62;
uint8_t beat = beatsin8( BeatsPerMinute, 64, 255);
for( int i = 0; i < leds.nrOfLeds; i++) { //9948
for (uint16_t i = 0; i < leds.nrOfLeds; i++) { //9948
leds[i] = ColorFromPalette(palette, gHue+(i*2), beat-gHue+(i*10));
}
}
Expand All @@ -242,7 +242,7 @@ class JuggleEffect: public Effect {
// eight colored dots, weaving in and out of sync with each other
leds.fadeToBlackBy(20);
uint8_t dothue = 0;
for( int i = 0; i < 8; i++) {
for (uint8_t i = 0; i < 8; i++) {
leds[beatsin16( i+7, 0, leds.nrOfLeds-1 )] |= CHSV(dothue, 200, 255);
dothue += 32;
}
Expand All @@ -265,7 +265,7 @@ class Ripples3DEffect: public Effect {
Coord3D pos = {0,0,0};
for (pos.z=0; pos.z<leds.size.z; pos.z++) {
for (pos.x=0; pos.x<leds.size.x; pos.x++) {
float d = leds.distance(3.5, 3.5, 0, pos.x, pos.z, 0)/9.899495*leds.size.y;
float d = leds.fixture->distance(3.5, 3.5, 0, pos.x, pos.z, 0)/9.899495*leds.size.y;
pos.y = floor(leds.size.y/2.0+sinf(d/ripple_interval + now/100/((256.0-128.0)/20.0))*leds.size.y/2.0); //between 0 and 8

leds[pos] = CHSV( gHue + random8(64), 200, 255);// ColorFromPalette(pal,call, bri, LINEARBLEND);
Expand Down Expand Up @@ -304,7 +304,7 @@ class SphereMove3DEffect: public Effect {
for (pos.x=0; pos.x<leds.size.x; pos.x++) {
for (pos.y=0; pos.y<leds.size.y; pos.y++) {
for (pos.z=0; pos.z<leds.size.z; pos.z++) {
d = leds.distance(pos.x, pos.y, pos.z, origin.x, origin.y, origin.z);
d = leds.fixture->distance(pos.x, pos.y, pos.z, origin.x, origin.y, origin.z);

if (d>diameter && d<diameter+1) {
leds[pos] = CHSV( gHue + random8(64), 200, 255);// ColorFromPalette(pal,call, bri, LINEARBLEND);
Expand Down Expand Up @@ -971,9 +971,9 @@ class Effects {
#ifdef USERMOD_WLEDAUDIO

if (mdl->getValue("mHead") ) {
leds.head.x = wledAudioMod->fftResults[3];
leds.head.y = wledAudioMod->fftResults[8];
leds.head.z = wledAudioMod->fftResults[13];
leds.fixture->head.x = wledAudioMod->fftResults[3];
leds.fixture->head.y = wledAudioMod->fftResults[8];
leds.fixture->head.z = wledAudioMod->fftResults[13];
}

#endif
Expand All @@ -983,21 +983,19 @@ class Effects {
EVERY_N_MILLISECONDS( 20 ) { gHue++; } // slowly cycle the "base color" through the rainbow
}

size_t size() {
return effects.size();
}

bool setEffect(Leds &leds, JsonObject parentVar, uint8_t rowNr) {
bool setEffect(Leds &leds, JsonObject var, uint8_t rowNr) {
bool doMap = false;

leds.fx = mdl->getValue(parentVar, rowNr);
leds.fx = mdl->getValue(var, rowNr);

if (rowNr != UINT8_MAX)
parentVar["rowNr"] = rowNr; //store the rownNr of the updated value to send back to ui
var["rowNr"] = rowNr; //store the rownNr of the updated value to send back to ui
else
var.remove("rowNr");

USER_PRINTF("setEffect %d\n", leds.fx);

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

//tbd: make property of effects
if (strstr(effects[leds.fx]->name(), "2D")) {
Expand All @@ -1022,17 +1020,17 @@ class Effects {
sharedData.clear(); //make sure all values are 0

// nullify values for this row
if (rowNr != UINT8_MAX) {
for (JsonObject var: parentVar["n"].as<JsonArray>()) {
mdl->setValue(var, -99, rowNr); //unused value for this row, so don't show
}
}
else
parentVar.remove("n"); //tbd: we should also remove the uiFun and chFun !!
// if (rowNr != UINT8_MAX) {
// for (JsonObject var: var["n"].as<JsonArray>()) {
// mdl->setValue(var, -99, rowNr); //unused value for this row, so don't show
// }
// }
// else
var.remove("n"); //tbd: we should also remove the uiFun and chFun !!
//tbd: we need to reuse the values set...

// // nullify values for this row
// for (JsonObject var: parentVar["n"].as<JsonArray>()) {
// for (JsonObject var: var["n"].as<JsonArray>()) {
// if (rowNr != UINT8_MAX) {
// if (var["value"].is<JsonArray>()) {
// var["value"][rowNr] = -99; //unused value for this row, so don't show
Expand All @@ -1045,20 +1043,20 @@ class Effects {
// // var["value"] = -99;
// }
// // else
// // parentVar.remove("n"); //tbd: we should also remove the uiFun and chFun !!
// // var.remove("n"); //tbd: we should also remove the uiFun and chFun !!

Effect* effect = effects[leds.fx];
effect->controls(parentVar); //tbd: add rowNr...
effect->controls(var); //tbd: add rowNr...

effect->setup(leds); //if changed then run setup once (like call==0 in WLED)

JsonDocument *responseDoc = web->getResponseDoc();
responseDoc->clear(); //needed for deserializeJson?
JsonObject responseObject = responseDoc->to<JsonObject>();

responseObject["details"] = parentVar;
responseObject["details"] = var;

print->printJson("parentVar", responseObject);
print->printJson("var", responseObject);
web->sendDataWs(responseObject); //always send, also when no children, to remove them from ui

} // fx < size
Expand Down
Loading

0 comments on commit 26c0068

Please sign in to comment.