mirror of
https://github.com/wled/WLED.git
synced 2025-07-16 15:26:31 +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;
|
[[gnu::hot]] uint32_t getPixelColor(int i) const;
|
||||||
// 1D support functions (some implement 2D as well)
|
// 1D support functions (some implement 2D as well)
|
||||||
void blur(uint8_t, bool smear = false);
|
void blur(uint8_t, bool smear = false);
|
||||||
|
void clear();
|
||||||
void fill(uint32_t c);
|
void fill(uint32_t c);
|
||||||
void fade_out(uint8_t r);
|
void fade_out(uint8_t r);
|
||||||
void fadeToSecondaryBy(uint8_t fadeBy);
|
void fadeToSecondaryBy(uint8_t fadeBy);
|
||||||
|
@ -270,7 +270,7 @@ void Segment::startTransition(uint16_t dur) {
|
|||||||
_t->_briT = on ? opacity : 0;
|
_t->_briT = on ? opacity : 0;
|
||||||
_t->_cctT = cct;
|
_t->_cctT = cct;
|
||||||
#ifndef WLED_DISABLE_MODE_BLEND
|
#ifndef WLED_DISABLE_MODE_BLEND
|
||||||
swapSegenv(_t->_segT);
|
swapSegenv(_t->_segT); // copy runtime data to temporary
|
||||||
_t->_modeT = mode;
|
_t->_modeT = mode;
|
||||||
_t->_segT._dataLenT = 0;
|
_t->_segT._dataLenT = 0;
|
||||||
_t->_segT._dataT = nullptr;
|
_t->_segT._dataT = nullptr;
|
||||||
@ -282,6 +282,13 @@ void Segment::startTransition(uint16_t dur) {
|
|||||||
_t->_segT._dataLenT = _dataLen;
|
_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
|
#else
|
||||||
for (size_t i=0; i<NUM_COLORS; i++) _t->_colorT[i] = colors[i];
|
for (size_t i=0; i<NUM_COLORS; i++) _t->_colorT[i] = colors[i];
|
||||||
#endif
|
#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
|
#ifndef WLED_DISABLE_2D
|
||||||
if (Segment::maxHeight>1) boundsUnchanged &= (startY == i1Y && stopY == i2Y); // 2D
|
if (Segment::maxHeight>1) boundsUnchanged &= (startY == i1Y && stopY == i2Y); // 2D
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
if (stop && (spc > 0 || m12 != map1D2D)) clear();
|
||||||
|
/*
|
||||||
if (boundsUnchanged
|
if (boundsUnchanged
|
||||||
&& (!grp || (grouping == grp && spacing == spc))
|
&& (!grp || (grouping == grp && spacing == spc))
|
||||||
&& (ofs == UINT16_MAX || ofs == offset)
|
&& (ofs == UINT16_MAX || ofs == offset)
|
||||||
&& (m12 == map1D2D)
|
&& (m12 == map1D2D)
|
||||||
) return;
|
) return;
|
||||||
|
*/
|
||||||
stateChanged = true; // send UDP/WS broadcast
|
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
|
if (grp) { // prevent assignment of 0
|
||||||
grouping = grp;
|
grouping = grp;
|
||||||
spacing = spc;
|
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;
|
if (ofs < UINT16_MAX) offset = ofs;
|
||||||
map1D2D = constrain(m12, 0, 7);
|
map1D2D = constrain(m12, 0, 7);
|
||||||
|
|
||||||
DEBUG_PRINT(F("setUp segment: ")); DEBUG_PRINT(i1);
|
DEBUG_PRINTF_P(PSTR("Segment geometry: %d,%d -> %d,%d\n"), (int)i1, (int)i2, (int)i1Y, (int)i2Y);
|
||||||
DEBUG_PRINT(','); DEBUG_PRINT(i2);
|
|
||||||
DEBUG_PRINT(F(" -> ")); DEBUG_PRINT(i1Y);
|
|
||||||
DEBUG_PRINT(','); DEBUG_PRINTLN(i2Y);
|
|
||||||
markForReset();
|
markForReset();
|
||||||
if (boundsUnchanged) return;
|
if (boundsUnchanged) return;
|
||||||
|
|
||||||
@ -1159,6 +1159,26 @@ void Segment::refreshLightCapabilities() {
|
|||||||
_capabilities = capabilities;
|
_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
|
* Fills segment with color
|
||||||
*/
|
*/
|
||||||
@ -1512,7 +1532,7 @@ void WS2812FX::service() {
|
|||||||
_segment_index = 0;
|
_segment_index = 0;
|
||||||
|
|
||||||
for (segment &seg : _segments) {
|
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)
|
// process transition (mode changes in the middle of transition)
|
||||||
seg.handleTransition();
|
seg.handleTransition();
|
||||||
@ -1633,8 +1653,8 @@ void WS2812FX::service() {
|
|||||||
if (doShow) {
|
if (doShow) {
|
||||||
yield();
|
yield();
|
||||||
Segment::handleRandomPalette(); // slowly transition random palette; move it into for loop when each segment has individual random palette
|
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
|
_lastServiceShow = nowUp; // update timestamp, for precise FPS control
|
||||||
|
if (!_suspend) show();
|
||||||
}
|
}
|
||||||
#ifdef WLED_DEBUG
|
#ifdef WLED_DEBUG
|
||||||
if ((_targetFps != FPS_UNLIMITED) && (millis() - nowUp > _frametime)) DEBUG_PRINTF_P(PSTR("Slow strip %u/%d.\n"), (unsigned)(millis()-nowUp), (int)_frametime);
|
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 grp = elem["grp"] | seg.grouping;
|
||||||
uint16_t spc = elem[F("spc")] | seg.spacing;
|
uint16_t spc = elem[F("spc")] | seg.spacing;
|
||||||
uint16_t of = seg.offset;
|
uint16_t of = seg.offset;
|
||||||
uint8_t soundSim = elem["si"] | seg.soundSim;
|
uint8_t soundSim = elem["si"] | seg.soundSim;
|
||||||
uint8_t map1D2D = elem["m12"] | seg.map1D2D;
|
uint8_t map1D2D = elem["m12"] | seg.map1D2D;
|
||||||
uint8_t set = elem[F("set")] | seg.set;
|
uint8_t set = elem[F("set")] | seg.set;
|
||||||
seg.set = constrain(set, 0, 3);
|
bool selected = getBoolVal(elem["sel"], seg.selected);
|
||||||
seg.soundSim = constrain(soundSim, 0, 3);
|
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 len = (stop > start) ? stop - start : 1;
|
||||||
int offset = elem[F("of")] | INT32_MAX;
|
int offset = elem[F("of")] | INT32_MAX;
|
||||||
@ -200,20 +206,16 @@ bool deserializeSegment(JsonObject elem, byte it, byte presetId)
|
|||||||
}
|
}
|
||||||
#endif
|
#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
|
#ifndef WLED_DISABLE_2D
|
||||||
bool reverse = seg.reverse;
|
seg.reverse_y = reverse_y;
|
||||||
bool mirror = seg.mirror;
|
seg.mirror_y = mirror_y;
|
||||||
#endif
|
seg.transpose = transpose;
|
||||||
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)
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
byte fx = seg.mode;
|
byte fx = seg.mode;
|
||||||
@ -392,35 +394,38 @@ bool deserializeState(JsonObject root, byte callMode, byte presetId)
|
|||||||
|
|
||||||
int it = 0;
|
int it = 0;
|
||||||
JsonVariant segVar = root["seg"];
|
JsonVariant segVar = root["seg"];
|
||||||
if (!segVar.isNull()) strip.suspend();
|
if (!segVar.isNull()) {
|
||||||
if (segVar.is<JsonObject>())
|
// we may be called during strip.service() so we must not modify segments while effects are executing
|
||||||
{
|
strip.suspend();
|
||||||
int id = segVar["id"] | -1;
|
const unsigned long start = millis();
|
||||||
//if "seg" is not an array and ID not specified, apply to all selected/checked segments
|
while (strip.isServicing() && millis() - start < strip.getFrameTime()) yield(); // wait until frame is over
|
||||||
if (id < 0) {
|
#ifdef WLED_DEBUG
|
||||||
//apply all selected segments
|
if (millis() - start > 0) DEBUG_PRINTLN(F("JSON: Waited for strip to finish servicing."));
|
||||||
//bool didSet = false;
|
#endif
|
||||||
for (size_t s = 0; s < strip.getSegmentsNum(); s++) {
|
if (segVar.is<JsonObject>()) {
|
||||||
Segment &sg = strip.getSegment(s);
|
int id = segVar["id"] | -1;
|
||||||
if (sg.isActive() && sg.isSelected()) {
|
//if "seg" is not an array and ID not specified, apply to all selected/checked segments
|
||||||
deserializeSegment(segVar, s, presetId);
|
if (id < 0) {
|
||||||
//didSet = true;
|
//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 {
|
} 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 {
|
strip.resume();
|
||||||
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();
|
|
||||||
|
|
||||||
UsermodManager::readFromJsonState(root);
|
UsermodManager::readFromJsonState(root);
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user