mirror of
https://github.com/wled/WLED.git
synced 2025-07-15 14:56:32 +00:00
Clear spaced segment
- also wait for strip before updating segment
This commit is contained in:
parent
05cd7d753e
commit
409b4b1963
@ -676,6 +676,7 @@ typedef struct Segment {
|
||||
[[gnu::hot]] uint32_t getPixelColor(int i) const;
|
||||
// 1D support functions (some implement 2D as well)
|
||||
void blur(uint8_t, bool smear = false);
|
||||
void clear();
|
||||
void fill(uint32_t c);
|
||||
void fade_out(uint8_t r);
|
||||
void fadeToSecondaryBy(uint8_t fadeBy);
|
||||
|
@ -270,7 +270,7 @@ void Segment::startTransition(uint16_t dur) {
|
||||
_t->_briT = on ? opacity : 0;
|
||||
_t->_cctT = cct;
|
||||
#ifndef WLED_DISABLE_MODE_BLEND
|
||||
swapSegenv(_t->_segT);
|
||||
swapSegenv(_t->_segT); // copy runtime data to temporary
|
||||
_t->_modeT = mode;
|
||||
_t->_segT._dataLenT = 0;
|
||||
_t->_segT._dataT = nullptr;
|
||||
@ -282,6 +282,13 @@ void Segment::startTransition(uint16_t dur) {
|
||||
_t->_segT._dataLenT = _dataLen;
|
||||
}
|
||||
}
|
||||
DEBUG_PRINTF_P(PSTR("-- pal: %d, bri: %d, C:[%08X,%08X,%08X], m: %d\n"),
|
||||
(int)_t->_palTid,
|
||||
(int)_t->_briT,
|
||||
_t->_segT._colorT[0],
|
||||
_t->_segT._colorT[1],
|
||||
_t->_segT._colorT[2],
|
||||
(int)_t->_modeT);
|
||||
#else
|
||||
for (size_t i=0; i<NUM_COLORS; i++) _t->_colorT[i] = colors[i];
|
||||
#endif
|
||||
@ -502,21 +509,17 @@ void Segment::setGeometry(uint16_t i1, uint16_t i2, uint8_t grp, uint8_t spc, ui
|
||||
#ifndef WLED_DISABLE_2D
|
||||
if (Segment::maxHeight>1) boundsUnchanged &= (startY == i1Y && stopY == i2Y); // 2D
|
||||
#endif
|
||||
|
||||
if (stop && (spc > 0 || m12 != map1D2D)) clear();
|
||||
/*
|
||||
if (boundsUnchanged
|
||||
&& (!grp || (grouping == grp && spacing == spc))
|
||||
&& (ofs == UINT16_MAX || ofs == offset)
|
||||
&& (m12 == map1D2D)
|
||||
) return;
|
||||
|
||||
*/
|
||||
stateChanged = true; // send UDP/WS broadcast
|
||||
|
||||
if (stop || spc != spacing || m12 != map1D2D) {
|
||||
_vWidth = virtualWidth();
|
||||
_vHeight = virtualHeight();
|
||||
_vLength = virtualLength();
|
||||
_segBri = currentBri();
|
||||
fill(BLACK); // turn old segment range off or clears pixels if changing spacing (requires _vWidth/_vHeight/_vLength/_segBri)
|
||||
}
|
||||
if (grp) { // prevent assignment of 0
|
||||
grouping = grp;
|
||||
spacing = spc;
|
||||
@ -527,10 +530,7 @@ void Segment::setGeometry(uint16_t i1, uint16_t i2, uint8_t grp, uint8_t spc, ui
|
||||
if (ofs < UINT16_MAX) offset = ofs;
|
||||
map1D2D = constrain(m12, 0, 7);
|
||||
|
||||
DEBUG_PRINT(F("setUp segment: ")); DEBUG_PRINT(i1);
|
||||
DEBUG_PRINT(','); DEBUG_PRINT(i2);
|
||||
DEBUG_PRINT(F(" -> ")); DEBUG_PRINT(i1Y);
|
||||
DEBUG_PRINT(','); DEBUG_PRINTLN(i2Y);
|
||||
DEBUG_PRINTF_P(PSTR("Segment geometry: %d,%d -> %d,%d\n"), (int)i1, (int)i2, (int)i1Y, (int)i2Y);
|
||||
markForReset();
|
||||
if (boundsUnchanged) return;
|
||||
|
||||
@ -1159,6 +1159,26 @@ void Segment::refreshLightCapabilities() {
|
||||
_capabilities = capabilities;
|
||||
}
|
||||
|
||||
/*
|
||||
* Fills segment with black
|
||||
*/
|
||||
void Segment::clear() {
|
||||
if (!isActive()) return; // not active
|
||||
unsigned oldVW = _vWidth;
|
||||
unsigned oldVH = _vHeight;
|
||||
unsigned oldVL = _vLength;
|
||||
unsigned oldSB = _segBri;
|
||||
_vWidth = virtualWidth();
|
||||
_vHeight = virtualHeight();
|
||||
_vLength = virtualLength();
|
||||
_segBri = currentBri();
|
||||
fill(BLACK);
|
||||
_vWidth = oldVW;
|
||||
_vHeight = oldVH;
|
||||
_vLength = oldVL;
|
||||
_segBri = oldSB;
|
||||
}
|
||||
|
||||
/*
|
||||
* Fills segment with color
|
||||
*/
|
||||
@ -1512,7 +1532,7 @@ void WS2812FX::service() {
|
||||
_segment_index = 0;
|
||||
|
||||
for (segment &seg : _segments) {
|
||||
if (_suspend) return; // immediately stop processing segments if suspend requested during service()
|
||||
if (_suspend) break; // immediately stop processing segments if suspend requested during service()
|
||||
|
||||
// process transition (mode changes in the middle of transition)
|
||||
seg.handleTransition();
|
||||
@ -1633,8 +1653,8 @@ void WS2812FX::service() {
|
||||
if (doShow) {
|
||||
yield();
|
||||
Segment::handleRandomPalette(); // slowly transition random palette; move it into for loop when each segment has individual random palette
|
||||
show();
|
||||
_lastServiceShow = nowUp; // update timestamp, for precise FPS control
|
||||
if (!_suspend) show();
|
||||
}
|
||||
#ifdef WLED_DEBUG
|
||||
if ((_targetFps != FPS_UNLIMITED) && (millis() - nowUp > _frametime)) DEBUG_PRINTF_P(PSTR("Slow strip %u/%d.\n"), (unsigned)(millis()-nowUp), (int)_frametime);
|
||||
|
@ -91,14 +91,20 @@ bool deserializeSegment(JsonObject elem, byte it, byte presetId)
|
||||
}
|
||||
}
|
||||
|
||||
uint16_t grp = elem["grp"] | seg.grouping;
|
||||
uint16_t spc = elem[F("spc")] | seg.spacing;
|
||||
uint16_t of = seg.offset;
|
||||
uint8_t soundSim = elem["si"] | seg.soundSim;
|
||||
uint8_t map1D2D = elem["m12"] | seg.map1D2D;
|
||||
uint8_t set = elem[F("set")] | seg.set;
|
||||
seg.set = constrain(set, 0, 3);
|
||||
seg.soundSim = constrain(soundSim, 0, 3);
|
||||
uint16_t grp = elem["grp"] | seg.grouping;
|
||||
uint16_t spc = elem[F("spc")] | seg.spacing;
|
||||
uint16_t of = seg.offset;
|
||||
uint8_t soundSim = elem["si"] | seg.soundSim;
|
||||
uint8_t map1D2D = elem["m12"] | seg.map1D2D;
|
||||
uint8_t set = elem[F("set")] | seg.set;
|
||||
bool selected = getBoolVal(elem["sel"], seg.selected);
|
||||
bool reverse = getBoolVal(elem["rev"], seg.reverse);
|
||||
bool mirror = getBoolVal(elem["mi"] , seg.mirror);
|
||||
#ifndef WLED_DISABLE_2D
|
||||
bool reverse_y = getBoolVal(elem["rY"] , seg.reverse_y);
|
||||
bool mirror_y = getBoolVal(elem["mY"] , seg.mirror_y);
|
||||
bool transpose = getBoolVal(elem[F("tp")], seg.transpose);
|
||||
#endif
|
||||
|
||||
int len = (stop > start) ? stop - start : 1;
|
||||
int offset = elem[F("of")] | INT32_MAX;
|
||||
@ -200,20 +206,16 @@ bool deserializeSegment(JsonObject elem, byte it, byte presetId)
|
||||
}
|
||||
#endif
|
||||
|
||||
//seg.map1D2D = constrain(map1D2D, 0, 7); // done in setGeometry()
|
||||
seg.set = constrain(set, 0, 3);
|
||||
seg.soundSim = constrain(soundSim, 0, 3);
|
||||
seg.selected = selected;
|
||||
seg.reverse = reverse;
|
||||
seg.mirror = mirror;
|
||||
#ifndef WLED_DISABLE_2D
|
||||
bool reverse = seg.reverse;
|
||||
bool mirror = seg.mirror;
|
||||
#endif
|
||||
seg.selected = getBoolVal(elem["sel"], seg.selected);
|
||||
seg.reverse = getBoolVal(elem["rev"], seg.reverse);
|
||||
seg.mirror = getBoolVal(elem["mi"] , seg.mirror);
|
||||
#ifndef WLED_DISABLE_2D
|
||||
bool reverse_y = seg.reverse_y;
|
||||
bool mirror_y = seg.mirror_y;
|
||||
seg.reverse_y = getBoolVal(elem["rY"] , seg.reverse_y);
|
||||
seg.mirror_y = getBoolVal(elem["mY"] , seg.mirror_y);
|
||||
seg.transpose = getBoolVal(elem[F("tp")], seg.transpose);
|
||||
if (seg.is2D() && seg.map1D2D == M12_pArc && (reverse != seg.reverse || reverse_y != seg.reverse_y || mirror != seg.mirror || mirror_y != seg.mirror_y)) seg.fill(BLACK); // clear entire segment (in case of Arc 1D to 2D expansion)
|
||||
seg.reverse_y = reverse_y;
|
||||
seg.mirror_y = mirror_y;
|
||||
seg.transpose = transpose;
|
||||
#endif
|
||||
|
||||
byte fx = seg.mode;
|
||||
@ -392,35 +394,38 @@ bool deserializeState(JsonObject root, byte callMode, byte presetId)
|
||||
|
||||
int it = 0;
|
||||
JsonVariant segVar = root["seg"];
|
||||
if (!segVar.isNull()) strip.suspend();
|
||||
if (segVar.is<JsonObject>())
|
||||
{
|
||||
int id = segVar["id"] | -1;
|
||||
//if "seg" is not an array and ID not specified, apply to all selected/checked segments
|
||||
if (id < 0) {
|
||||
//apply all selected segments
|
||||
//bool didSet = false;
|
||||
for (size_t s = 0; s < strip.getSegmentsNum(); s++) {
|
||||
Segment &sg = strip.getSegment(s);
|
||||
if (sg.isActive() && sg.isSelected()) {
|
||||
deserializeSegment(segVar, s, presetId);
|
||||
//didSet = true;
|
||||
if (!segVar.isNull()) {
|
||||
// we may be called during strip.service() so we must not modify segments while effects are executing
|
||||
strip.suspend();
|
||||
const unsigned long start = millis();
|
||||
while (strip.isServicing() && millis() - start < strip.getFrameTime()) yield(); // wait until frame is over
|
||||
#ifdef WLED_DEBUG
|
||||
if (millis() - start > 0) DEBUG_PRINTLN(F("JSON: Waited for strip to finish servicing."));
|
||||
#endif
|
||||
if (segVar.is<JsonObject>()) {
|
||||
int id = segVar["id"] | -1;
|
||||
//if "seg" is not an array and ID not specified, apply to all selected/checked segments
|
||||
if (id < 0) {
|
||||
//apply all selected segments
|
||||
for (size_t s = 0; s < strip.getSegmentsNum(); s++) {
|
||||
Segment &sg = strip.getSegment(s);
|
||||
if (sg.isActive() && sg.isSelected()) {
|
||||
deserializeSegment(segVar, s, presetId);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
deserializeSegment(segVar, id, presetId); //apply only the segment with the specified ID
|
||||
}
|
||||
//TODO: not sure if it is good idea to change first active but unselected segment
|
||||
//if (!didSet) deserializeSegment(segVar, strip.getMainSegmentId(), presetId);
|
||||
} else {
|
||||
deserializeSegment(segVar, id, presetId); //apply only the segment with the specified ID
|
||||
size_t deleted = 0;
|
||||
JsonArray segs = segVar.as<JsonArray>();
|
||||
for (JsonObject elem : segs) {
|
||||
if (deserializeSegment(elem, it++, presetId) && !elem["stop"].isNull() && elem["stop"]==0) deleted++;
|
||||
}
|
||||
if (strip.getSegmentsNum() > 3 && deleted >= strip.getSegmentsNum()/2U) strip.purgeSegments(); // batch deleting more than half segments
|
||||
}
|
||||
} else {
|
||||
size_t deleted = 0;
|
||||
JsonArray segs = segVar.as<JsonArray>();
|
||||
for (JsonObject elem : segs) {
|
||||
if (deserializeSegment(elem, it++, presetId) && !elem["stop"].isNull() && elem["stop"]==0) deleted++;
|
||||
}
|
||||
if (strip.getSegmentsNum() > 3 && deleted >= strip.getSegmentsNum()/2U) strip.purgeSegments(); // batch deleting more than half segments
|
||||
strip.resume();
|
||||
}
|
||||
strip.resume();
|
||||
|
||||
UsermodManager::readFromJsonState(root);
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user