Skip to content

Commit a307fa6

Browse files
committed
Clean up setGeometry
Reorganize setGeometry to perform all checks first before applying the values. This lets us accurately detect changes before starting a transition.
1 parent 4fb5fbe commit a307fa6

1 file changed

Lines changed: 67 additions & 43 deletions

File tree

wled00/FX_fcn.cpp

Lines changed: 67 additions & 43 deletions
Original file line numberDiff line numberDiff line change
@@ -457,58 +457,82 @@ void Segment::handleRandomPalette() {
457457
nblendPaletteTowardPalette(_randomPalette, _newRandomPalette, 48);
458458
}
459459

460-
// segId is given when called from network callback, changes are queued if that segment is currently in its effect function
461460
void Segment::setGeometry(uint16_t i1, uint16_t i2, uint8_t grp, uint8_t spc, uint16_t ofs, uint16_t i1Y, uint16_t i2Y, uint8_t m12) {
462-
// return if neither bounds nor grouping have changed
463-
bool boundsUnchanged = (start == i1 && stop == i2);
461+
// Sanitise inputs
462+
if (i2 < i1) { // For any values, this means "stop"; we do i2 before i1 for this case
463+
i2 = 0;
464+
} else {
465+
// Clamp i2 to maximum length
466+
if (i2 > Segment::maxWidth*Segment::maxHeight) {
467+
i2 = MIN(i2,strip.getLengthTotal());
468+
} else if (i2 > Segment::maxWidth) {
469+
i2 = Segment::maxWidth;
470+
} else if (i2 < 1) {
471+
i2 = 1;
472+
}
473+
}
474+
// If i1 is invalid, use old value
475+
// Valid range is inside maxWidth, or in trailing segment range
476+
if ((i1 >= Segment::maxWidth) && (i1 < Segment::maxWidth*Segment::maxHeight || i1 >= strip.getLengthTotal())) {
477+
i1 = start;
478+
}
479+
464480
#ifndef WLED_DISABLE_2D
465-
if (Segment::maxHeight>1) boundsUnchanged &= (startY == i1Y && stopY == i2Y); // 2D
481+
if (Segment::maxHeight>1) { // 2D
482+
if (i1Y >= Segment::maxHeight) i1Y = startY;
483+
if (i2Y > Segment::maxHeight) {
484+
i2Y = Segment::maxHeight;
485+
} else if (i2Y < 1) {
486+
i2Y = 1;
487+
}
488+
if (i2Y < i1Y) {
489+
i2 = 0; // stop
490+
}
491+
} else
466492
#endif
493+
{
494+
i1Y = 0;
495+
i2Y = 1;
496+
}
467497

498+
if (grp == 0) { grp = 1; spc = 0; } // prevent assignment of 0
499+
if (ofs == UINT16_MAX) ofs = offset;
468500
m12 = constrain(m12, 0, 7);
469-
if (stop) fill(BLACK); // turn off LEDs in segment before changing geometry
470-
if (m12 != map1D2D) map1D2D = m12;
471-
/*
472-
if (boundsUnchanged
473-
&& (!grp || (grouping == grp && spacing == spc))
474-
&& (m12 == map1D2D)
475-
) return;
476-
*/
477-
stateChanged = true; // send UDP/WS broadcast
478501

479-
if (grp) { // prevent assignment of 0
480-
grouping = grp;
481-
spacing = spc;
482-
} else {
483-
grouping = 1;
484-
spacing = 0;
502+
// Final safety check
503+
if ((i1 >= i2) || (i1Y >= i2Y)) {
504+
i2 = 0; // disable segment
485505
}
486-
if (ofs < UINT16_MAX) offset = ofs;
487506

488-
DEBUG_PRINTF_P(PSTR("Segment geometry: %d,%d -> %d,%d\n"), (int)i1, (int)i2, (int)i1Y, (int)i2Y);
507+
// Inputs are ok, check if anything has changed
508+
bool boundsUnchanged = (start == i1 && stop == i2)
509+
#ifndef WLED_DISABLE_2D
510+
&& ((Segment::maxHeight <= 1) || (startY == i1Y && stopY == i2Y))
511+
#endif
512+
&& (grouping == grp)
513+
&& (spacing == spc)
514+
&& (offset == ofs)
515+
&& (m12 == map1D2D);
516+
489517
if (boundsUnchanged) return;
518+
519+
DEBUG_PRINTF_P(PSTR("Segment geometry: (%d,%d),(%d,%d) -> (%d,%d),(%d,%d)\n"), start, stop, startY, stopY, (int)i1, (int)i2, (int)i1Y, (int)i2Y);
520+
521+
if (stop > 0) fill(BLACK); // turn off LEDs in segment before changing geometry
522+
523+
stateChanged = true; // send UDP/WS broadcast
490524
markForReset();
491525

492-
// apply change immediately
493-
if (i2 <= i1) { //disable segment
494-
stop = 0;
495-
return;
496-
}
497-
if (i1 < Segment::maxWidth || (i1 >= Segment::maxWidth*Segment::maxHeight && i1 < strip.getLengthTotal())) start = i1; // Segment::maxWidth equals strip.getLengthTotal() for 1D
498-
stop = i2 > Segment::maxWidth*Segment::maxHeight ? MIN(i2,strip.getLengthTotal()) : (i2 > Segment::maxWidth ? Segment::maxWidth : MAX(1,i2));
499-
startY = 0;
500-
stopY = 1;
501-
#ifndef WLED_DISABLE_2D
502-
if (Segment::maxHeight>1) { // 2D
503-
if (i1Y < Segment::maxHeight) startY = i1Y;
504-
stopY = i2Y > Segment::maxHeight ? Segment::maxHeight : MAX(1,i2Y);
505-
}
506-
#endif
507-
// safety check
508-
if (start >= stop || startY >= stopY) {
509-
stop = 0;
510-
return;
511-
}
526+
// apply change
527+
start = i1;
528+
stop = i2;
529+
startY = i1Y;
530+
stopY = i2Y;
531+
grouping = grp;
532+
spacing = spc;
533+
offset = ofs;
534+
map1D2D = m12;
535+
512536
refreshLightCapabilities();
513537
}
514538

@@ -532,7 +556,7 @@ Segment &Segment::setCCT(uint16_t k) {
532556
k = (k - 1900) >> 5;
533557
}
534558
if (cct != k) {
535-
//DEBUGFX_PRINTF_P(PSTR("- Starting CCT transition: %d\n"), k);
559+
DEBUG_PRINTF_P(PSTR("- Starting CCT transition: %d\n"), k);
536560
startTransition(strip.getTransition()); // start transition prior to change
537561
cct = k;
538562
stateChanged = true; // send UDP/WS broadcast
@@ -542,7 +566,7 @@ Segment &Segment::setCCT(uint16_t k) {
542566

543567
Segment &Segment::setOpacity(uint8_t o) {
544568
if (opacity != o) {
545-
//DEBUGFX_PRINTF_P(PSTR("- Starting opacity transition: %d\n"), o);
569+
DEBUG_PRINTF_P(PSTR("- Starting opacity transition: %d\n"), o);
546570
startTransition(strip.getTransition()); // start transition prior to change
547571
opacity = o;
548572
stateChanged = true; // send UDP/WS broadcast

0 commit comments

Comments
 (0)