Bugfixes.
This commit is contained in:
parent
6c6849d8d7
commit
a46894f395
@ -103,7 +103,7 @@ class Animated_Staircase : public Usermod {
|
||||
|
||||
void updateSegments() {
|
||||
mainSegmentId = strip.getMainSegmentId();
|
||||
for (int i = 0; i < strip.getActiveSegmentsNum(); i++) {
|
||||
for (int i = 0; i < strip.getSegmentsNum(); i++) {
|
||||
Segment &seg = strip.getSegment(i);
|
||||
if (!seg.isActive()) {
|
||||
maxSegmentId = i - 1;
|
||||
@ -289,7 +289,7 @@ class Animated_Staircase : public Usermod {
|
||||
}
|
||||
} else {
|
||||
// Restore segment options
|
||||
for (int i = 0; i < strip.getActiveSegmentsNum(); i++) {
|
||||
for (int i = 0; i < strip.getSegmentsNum(); i++) {
|
||||
Segment &seg = strip.getSegment(i);
|
||||
if (!seg.isActive()) {
|
||||
maxSegmentId = i - 1;
|
||||
|
@ -528,7 +528,7 @@ public:
|
||||
effectCurrent = modes_alpha_indexes[effectCurrentIndex];
|
||||
stateChanged = true;
|
||||
if (applyToAll) {
|
||||
for (byte i=0; i<strip.getActiveSegmentsNum(); i++) {
|
||||
for (byte i=0; i<strip.getSegmentsNum(); i++) {
|
||||
Segment& seg = strip.getSegment(i);
|
||||
if (!seg.isActive()) continue;
|
||||
strip.setMode(i, effectCurrent);
|
||||
@ -556,7 +556,7 @@ public:
|
||||
effectSpeed = max(min((increase ? effectSpeed+fadeAmount : effectSpeed-fadeAmount), 255), 0);
|
||||
stateChanged = true;
|
||||
if (applyToAll) {
|
||||
for (byte i=0; i<strip.getActiveSegmentsNum(); i++) {
|
||||
for (byte i=0; i<strip.getSegmentsNum(); i++) {
|
||||
Segment& seg = strip.getSegment(i);
|
||||
if (!seg.isActive()) continue;
|
||||
seg.speed = effectSpeed;
|
||||
@ -584,7 +584,7 @@ public:
|
||||
effectIntensity = max(min((increase ? effectIntensity+fadeAmount : effectIntensity-fadeAmount), 255), 0);
|
||||
stateChanged = true;
|
||||
if (applyToAll) {
|
||||
for (byte i=0; i<strip.getActiveSegmentsNum(); i++) {
|
||||
for (byte i=0; i<strip.getSegmentsNum(); i++) {
|
||||
Segment& seg = strip.getSegment(i);
|
||||
if (!seg.isActive()) continue;
|
||||
seg.intensity = effectIntensity;
|
||||
@ -619,7 +619,7 @@ public:
|
||||
case 2: val = sid.custom2 = max(min((increase ? sid.custom2+fadeAmount : sid.custom2-fadeAmount), 255), 0); break;
|
||||
default: val = sid.custom1 = max(min((increase ? sid.custom1+fadeAmount : sid.custom1-fadeAmount), 255), 0); break;
|
||||
}
|
||||
for (byte i=0; i<strip.getActiveSegmentsNum(); i++) {
|
||||
for (byte i=0; i<strip.getSegmentsNum(); i++) {
|
||||
Segment& seg = strip.getSegment(i);
|
||||
if (!seg.isActive() || i == id) continue;
|
||||
switch (par) {
|
||||
@ -658,7 +658,7 @@ public:
|
||||
effectPalette = palettes_alpha_indexes[effectPaletteIndex];
|
||||
stateChanged = true;
|
||||
if (applyToAll) {
|
||||
for (byte i=0; i<strip.getActiveSegmentsNum(); i++) {
|
||||
for (byte i=0; i<strip.getSegmentsNum(); i++) {
|
||||
Segment& seg = strip.getSegment(i);
|
||||
if (!seg.isActive()) continue;
|
||||
seg.palette = effectPalette;
|
||||
@ -687,7 +687,7 @@ public:
|
||||
colorHStoRGB(currentHue1*256, currentSat1, col);
|
||||
stateChanged = true;
|
||||
if (applyToAll) {
|
||||
for (byte i=0; i<strip.getActiveSegmentsNum(); i++) {
|
||||
for (byte i=0; i<strip.getSegmentsNum(); i++) {
|
||||
Segment& seg = strip.getSegment(i);
|
||||
if (!seg.isActive()) continue;
|
||||
seg.colors[0] = RGBW32(col[0], col[1], col[2], col[3]);
|
||||
@ -716,7 +716,7 @@ public:
|
||||
currentSat1 = max(min((increase ? currentSat1+fadeAmount : currentSat1-fadeAmount), 255), 0);
|
||||
colorHStoRGB(currentHue1*256, currentSat1, col);
|
||||
if (applyToAll) {
|
||||
for (byte i=0; i<strip.getActiveSegmentsNum(); i++) {
|
||||
for (byte i=0; i<strip.getSegmentsNum(); i++) {
|
||||
Segment& seg = strip.getSegment(i);
|
||||
if (!seg.isActive()) continue;
|
||||
seg.colors[0] = RGBW32(col[0], col[1], col[2], col[3]);
|
||||
@ -776,7 +776,7 @@ public:
|
||||
#endif
|
||||
currentCCT = max(min((increase ? currentCCT+fadeAmount : currentCCT-fadeAmount), 255), 0);
|
||||
// if (applyToAll) {
|
||||
for (byte i=0; i<strip.getActiveSegmentsNum(); i++) {
|
||||
for (byte i=0; i<strip.getSegmentsNum(); i++) {
|
||||
Segment& seg = strip.getSegment(i);
|
||||
if (!seg.isActive()) continue;
|
||||
seg.setCCT(currentCCT);
|
||||
|
219
wled00/FX.h
219
wled00/FX.h
@ -426,39 +426,38 @@ typedef struct Segment {
|
||||
|
||||
public:
|
||||
|
||||
Segment(uint16_t sStart=0, uint16_t sStop=30) : start(sStart), stop(sStop) {
|
||||
mode = DEFAULT_MODE;
|
||||
colors[0] = DEFAULT_COLOR;
|
||||
colors[1] = BLACK;
|
||||
colors[2] = BLACK;
|
||||
startY = 0;
|
||||
stopY = 1;
|
||||
speed = DEFAULT_SPEED;
|
||||
intensity = DEFAULT_INTENSITY;
|
||||
custom1 = DEFAULT_C1;
|
||||
custom2 = DEFAULT_C2;
|
||||
custom3 = DEFAULT_C3;
|
||||
grouping = 1;
|
||||
spacing = 0;
|
||||
offset = 0;
|
||||
opacity = 255;
|
||||
cct = 127;
|
||||
name = nullptr;
|
||||
options = NO_OPTIONS;
|
||||
setOption(SEG_OPTION_SELECTED, 1);
|
||||
setOption(SEG_OPTION_ON, 1);
|
||||
call = 0;
|
||||
step = 0;
|
||||
next_time = 0;
|
||||
aux0 = 0;
|
||||
aux1 = 0;
|
||||
data = nullptr;
|
||||
_dataLen = 0;
|
||||
//_t = nullptr;
|
||||
}
|
||||
Segment(uint16_t sStart=0, uint16_t sStop=30) :
|
||||
start(sStart),
|
||||
stop(sStop),
|
||||
offset(0),
|
||||
speed(DEFAULT_SPEED),
|
||||
intensity(DEFAULT_INTENSITY),
|
||||
palette(0),
|
||||
mode(DEFAULT_MODE),
|
||||
options(SELECTED | SEGMENT_ON),
|
||||
grouping(1),
|
||||
spacing(0),
|
||||
opacity(255),
|
||||
colors{DEFAULT_COLOR,BLACK,BLACK},
|
||||
cct(127),
|
||||
custom1(DEFAULT_C1),
|
||||
custom2(DEFAULT_C2),
|
||||
custom3(DEFAULT_C3),
|
||||
startY(0),
|
||||
stopY(1),
|
||||
name(nullptr),
|
||||
next_time(0),
|
||||
step(0),
|
||||
call(0),
|
||||
aux0(0),
|
||||
aux1(0),
|
||||
data(nullptr),
|
||||
_capabilities(0),
|
||||
_dataLen(0)
|
||||
//_t(nullptr)
|
||||
{}
|
||||
|
||||
Segment(uint16_t sStartX, uint16_t sStopX, uint16_t sStartY, uint16_t sStopY) {
|
||||
Segment(sStartX, sStopX);
|
||||
Segment(uint16_t sStartX, uint16_t sStopX, uint16_t sStartY, uint16_t sStopY) : Segment(sStartX, sStopX) {
|
||||
startY = sStartY;
|
||||
stopY = sStopY;
|
||||
}
|
||||
@ -467,8 +466,12 @@ typedef struct Segment {
|
||||
Segment(Segment &&orig) noexcept; // move constructor
|
||||
|
||||
~Segment() {
|
||||
Serial.print(F("Destroying segment: "));
|
||||
if (name) Serial.println(name); else Serial.println();
|
||||
#ifdef WLED_DEBUG
|
||||
Serial.print(F("Destroying segment."));
|
||||
if (name) Serial.printf(" %s (%p)", name, name);
|
||||
if (data) Serial.printf(" %p", data);
|
||||
Serial.println();
|
||||
#endif
|
||||
if (name) delete[] name;
|
||||
//if (_t) delete _t;
|
||||
deallocateData();
|
||||
@ -495,8 +498,9 @@ typedef struct Segment {
|
||||
|
||||
// runtime data functions
|
||||
bool allocateData(uint16_t len);
|
||||
void deallocateData();
|
||||
void resetIfRequired();
|
||||
void deallocateData(void);
|
||||
inline uint16_t dataSize(void) { return _dataLen; }
|
||||
void resetIfRequired(void);
|
||||
/**
|
||||
* Flags that before the next effect is calculated,
|
||||
* the internal segment state should be reset.
|
||||
@ -581,7 +585,56 @@ class WS2812FX { // 96 bytes
|
||||
|
||||
public:
|
||||
|
||||
WS2812FX() {
|
||||
WS2812FX() :
|
||||
gammaCorrectBri(false),
|
||||
gammaCorrectCol(true),
|
||||
paletteFade(0),
|
||||
paletteBlend(0),
|
||||
milliampsPerLed(55),
|
||||
cctBlending(0),
|
||||
ablMilliampsMax(ABL_MILLIAMPS_DEFAULT),
|
||||
currentMilliamps(0),
|
||||
now(millis()),
|
||||
timebase(0),
|
||||
isMatrix(false),
|
||||
#ifndef WLED_DISABLE_2D
|
||||
hPanels(1),
|
||||
vPanels(1),
|
||||
panelH(8),
|
||||
panelW(8),
|
||||
matrixWidth(DEFAULT_LED_COUNT),
|
||||
matrixHeight(1),
|
||||
matrix{0,0,0,0},
|
||||
panel{{0,0,0,0}},
|
||||
#endif
|
||||
currentPalette(CRGBPalette16(CRGB::Black)),
|
||||
targetPalette(CloudColors_p),
|
||||
_bri_t(0),
|
||||
_colors_t{0,0,0},
|
||||
_virtualSegmentLength(0),
|
||||
_length(DEFAULT_LED_COUNT),
|
||||
_rand16seed(0),
|
||||
_brightness(DEFAULT_BRIGHTNESS),
|
||||
_usedSegmentData(0),
|
||||
_transitionDur(750),
|
||||
_targetFps(WLED_FPS),
|
||||
_frametime(FRAMETIME_FIXED),
|
||||
_cumulativeFps(2),
|
||||
_isServicing(false),
|
||||
_isOffRefreshRequired(false),
|
||||
_hasWhiteChannel(false),
|
||||
_triggered(false),
|
||||
_no_rgb(false),
|
||||
_modeCount(MODE_COUNT),
|
||||
_callback(nullptr),
|
||||
customMappingTable(nullptr),
|
||||
customMappingSize(0),
|
||||
_lastPaletteChange(0),
|
||||
_lastShow(0),
|
||||
_segment_index(0),
|
||||
_segment_index_palette_last(99),
|
||||
_mainSegment(0)
|
||||
{
|
||||
WS2812FX::instance = this;
|
||||
_mode.reserve(_modeCount);
|
||||
_modeData.reserve(_modeCount);
|
||||
@ -593,21 +646,15 @@ class WS2812FX { // 96 bytes
|
||||
if (_mode && _modeData) setupEffectData();
|
||||
else _modeCount = 1; // only Solid will work
|
||||
*/
|
||||
_brightness = DEFAULT_BRIGHTNESS;
|
||||
currentPalette = CRGBPalette16(CRGB::Black);
|
||||
targetPalette = CloudColors_p;
|
||||
ablMilliampsMax = ABL_MILLIAMPS_DEFAULT;
|
||||
currentMilliamps = 0;
|
||||
timebase = 0;
|
||||
_usedSegmentData = 0;
|
||||
//resetSegments(); // no need here
|
||||
}
|
||||
|
||||
~WS2812FX() {
|
||||
if (customMappingTable) delete[] customMappingTable;
|
||||
//delete[] _mode;
|
||||
//delete[] _modeData;
|
||||
_mode.clear();
|
||||
_modeData.clear();
|
||||
_segments.clear();
|
||||
}
|
||||
|
||||
static WS2812FX* getInstance(void) { return instance; }
|
||||
@ -649,23 +696,24 @@ class WS2812FX { // 96 bytes
|
||||
inline void addUsedSegmentData(int16_t size) { _usedSegmentData += size; }
|
||||
|
||||
bool
|
||||
gammaCorrectBri = false,
|
||||
gammaCorrectCol = true,
|
||||
gammaCorrectBri,
|
||||
gammaCorrectCol,
|
||||
checkSegmentAlignment(void),
|
||||
hasRGBWBus(void),
|
||||
hasCCTBus(void),
|
||||
// return true if the strip is being sent pixel updates
|
||||
isUpdating(void);
|
||||
|
||||
inline bool isServicing(void) { return _isServicing; }
|
||||
inline bool hasWhiteChannel(void) {return _hasWhiteChannel;}
|
||||
inline bool isOffRefreshRequired(void) {return _isOffRefreshRequired;}
|
||||
|
||||
uint8_t
|
||||
paletteFade = 0,
|
||||
paletteBlend = 0,
|
||||
milliampsPerLed = 55,
|
||||
cctBlending = 0,
|
||||
//getActiveSegmentsNum(void),
|
||||
paletteFade,
|
||||
paletteBlend,
|
||||
milliampsPerLed,
|
||||
cctBlending,
|
||||
getActiveSegmentsNum(void),
|
||||
getFirstSelectedSegId(void),
|
||||
getLastActiveSegmentId(void),
|
||||
setPixelSegment(uint8_t n),
|
||||
@ -674,7 +722,7 @@ class WS2812FX { // 96 bytes
|
||||
|
||||
inline uint8_t getBrightness(void) { return _brightness; }
|
||||
inline uint8_t getMaxSegments(void) { return MAX_NUM_SEGMENTS; } // returns maximum number of supported segments (fixed value)
|
||||
inline uint8_t getActiveSegmentsNum(void) { return _segments.size(); } // returns currently active (present) segments
|
||||
inline uint8_t getSegmentsNum(void) { return _segments.size(); } // returns currently present segments
|
||||
inline uint8_t getCurrSegmentId(void) { return _segment_index; }
|
||||
inline uint8_t getMainSegmentId(void) { return _mainSegment; }
|
||||
inline uint8_t getPaletteCount() { return 13 + GRADIENT_PALETTE_COUNT; }
|
||||
@ -709,27 +757,26 @@ class WS2812FX { // 96 bytes
|
||||
const char **
|
||||
getModeDataSrc(void) { return &(_modeData[0]); } // vectors use arrays for underlying data
|
||||
|
||||
//inline Segment& getSegment(uint8_t id) { return _segments[id >= getMaxSegments() ? getMainSegmentId() : id]; }
|
||||
inline Segment& getSegment(uint8_t id) { return _segments[id >= _segments.size() ? getMainSegmentId() : id]; } // vectors
|
||||
Segment& getSegment(uint8_t id);
|
||||
inline Segment& getFirstSelectedSeg(void) { return _segments[getFirstSelectedSegId()]; }
|
||||
inline Segment& getMainSegment(void) { return _segments[getMainSegmentId()]; }
|
||||
inline Segment* getSegments(void) { return &(_segments[0]); }
|
||||
|
||||
// 2D support (panels)
|
||||
bool
|
||||
isMatrix = false;
|
||||
isMatrix;
|
||||
|
||||
#ifndef WLED_DISABLE_2D
|
||||
#define WLED_MAX_PANELS 64
|
||||
uint8_t
|
||||
hPanels = 1,
|
||||
vPanels = 1;
|
||||
hPanels,
|
||||
vPanels;
|
||||
|
||||
uint16_t
|
||||
panelH = 8,
|
||||
panelW = 8,
|
||||
matrixWidth = DEFAULT_LED_COUNT,
|
||||
matrixHeight = 1;
|
||||
panelH,
|
||||
panelW,
|
||||
matrixWidth,
|
||||
matrixHeight;
|
||||
|
||||
typedef struct panel_bitfield_t {
|
||||
unsigned char
|
||||
@ -739,8 +786,8 @@ class WS2812FX { // 96 bytes
|
||||
serpentine : 1; // is serpentine?
|
||||
} Panel;
|
||||
Panel
|
||||
matrix = {0,0,0,0},
|
||||
panel[WLED_MAX_PANELS] = {{0,0,0,0}};
|
||||
matrix,
|
||||
panel[WLED_MAX_PANELS];
|
||||
#endif
|
||||
|
||||
void
|
||||
@ -776,37 +823,43 @@ class WS2812FX { // 96 bytes
|
||||
uint16_t _rand16seed;
|
||||
uint8_t _brightness;
|
||||
uint16_t _usedSegmentData;
|
||||
uint16_t _transitionDur = 750;
|
||||
uint16_t _transitionDur;
|
||||
|
||||
uint8_t _targetFps = 42;
|
||||
uint16_t _frametime = (1000/42);
|
||||
uint16_t _cumulativeFps = 2;
|
||||
uint8_t _targetFps;
|
||||
uint16_t _frametime;
|
||||
uint16_t _cumulativeFps;
|
||||
|
||||
// will require only 1 byte
|
||||
// struct {
|
||||
// byte _isServicing : 1;
|
||||
// byte _isOffRefreshRequired : 1;
|
||||
// byte _hasWhiteChannel : 1;
|
||||
// byte _triggered : 1;
|
||||
// byte _no_rgb : 1;
|
||||
// };
|
||||
bool
|
||||
_isOffRefreshRequired = false, //periodic refresh is required for the strip to remain off.
|
||||
_hasWhiteChannel = false,
|
||||
_triggered;
|
||||
_isServicing,
|
||||
_isOffRefreshRequired, //periodic refresh is required for the strip to remain off.
|
||||
_hasWhiteChannel,
|
||||
_triggered,
|
||||
_no_rgb;
|
||||
|
||||
uint8_t _modeCount = MODE_COUNT;
|
||||
uint8_t _modeCount;
|
||||
//mode_ptr *_mode; // SRAM footprint: 4 bytes per element
|
||||
//const char **_modeData; // mode (effect) name and its slider control data array
|
||||
std::vector<mode_ptr> _mode; // SRAM footprint: 4 bytes per element
|
||||
std::vector<const char*> _modeData; // mode (effect) name and its slider control data array
|
||||
|
||||
//std::vector<ModeData> _modes; // this will require substantial rewrite of code
|
||||
show_callback _callback;
|
||||
|
||||
show_callback _callback = nullptr;
|
||||
uint16_t* customMappingTable;
|
||||
uint16_t customMappingSize;
|
||||
|
||||
uint16_t* customMappingTable = nullptr;
|
||||
uint16_t customMappingSize = 0;
|
||||
uint32_t _lastPaletteChange;
|
||||
uint32_t _lastShow;
|
||||
|
||||
uint32_t _lastPaletteChange = 0;
|
||||
uint32_t _lastShow = 0;
|
||||
|
||||
bool _no_rgb = false;
|
||||
|
||||
uint8_t _segment_index = 0;
|
||||
uint8_t _segment_index_palette_last = 99;
|
||||
uint8_t _segment_index;
|
||||
uint8_t _segment_index_palette_last;
|
||||
uint8_t _mainSegment;
|
||||
|
||||
void
|
||||
|
@ -93,13 +93,17 @@ Segment::Segment(Segment &&orig) noexcept {
|
||||
memcpy(this, &orig, sizeof(Segment));
|
||||
orig.name = nullptr;
|
||||
orig.data = nullptr;
|
||||
orig._dataLen = 0;
|
||||
//orig._t = nullptr;
|
||||
}
|
||||
|
||||
Segment& Segment::operator= (const Segment &orig) {
|
||||
DEBUG_PRINTLN(F("-- Segment copied --"));
|
||||
if (this != &orig) {
|
||||
if (name) delete[] name;
|
||||
if (name) {
|
||||
DEBUG_PRINTF(" Copy Deleting %s (%p)\n", name, name);
|
||||
delete[] name;
|
||||
}
|
||||
//if (_t) delete _t;
|
||||
deallocateData();
|
||||
memcpy(this, &orig, sizeof(Segment));
|
||||
@ -110,8 +114,8 @@ Segment& Segment::operator= (const Segment &orig) {
|
||||
if (orig.name) { name = new char[strlen(orig.name)+1]; if (name) strcpy(name, orig.name); }
|
||||
if (orig.data) { allocateData(orig._dataLen); memcpy(data, orig.data, orig._dataLen); }
|
||||
//if (orig._t) { _t = new Transition(orig._t->_dur, orig._t->_briT, orig._t->_cctT, orig._t->_colorT); }
|
||||
DEBUG_PRINTF(" Copied data: %p (%d)\n", orig.data, (int)orig._dataLen);
|
||||
DEBUG_PRINTF(" New data: %p (%d)\n", data, (int)_dataLen);
|
||||
DEBUG_PRINTF(" Original data: %p (%d)\n", orig.data, (int)orig._dataLen);
|
||||
DEBUG_PRINTF(" Copied data: %p (%d)\n", data, (int)_dataLen);
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
@ -119,12 +123,16 @@ Segment& Segment::operator= (const Segment &orig) {
|
||||
Segment& Segment::operator= (Segment &&orig) noexcept {
|
||||
DEBUG_PRINTLN(F("-- Moving segment --"));
|
||||
if (this != &orig) {
|
||||
if (name) delete[] name; // free old name
|
||||
if (name) {
|
||||
DEBUG_PRINTF(" Move Deleting %s (%p)\n", name, name);
|
||||
delete[] name; // free old name
|
||||
}
|
||||
//if (_t) delete _t;
|
||||
deallocateData(); // free old runtime data
|
||||
memcpy(this, &orig, sizeof(Segment));
|
||||
orig.name = nullptr;
|
||||
orig.data = nullptr;
|
||||
orig._dataLen = 0;
|
||||
//orig._t = nullptr;
|
||||
}
|
||||
return *this;
|
||||
@ -132,8 +140,8 @@ Segment& Segment::operator= (Segment &&orig) noexcept {
|
||||
|
||||
bool Segment::allocateData(uint16_t len) {
|
||||
if (data && _dataLen == len) return true; //already allocated
|
||||
DEBUG_PRINTF("-- Allocating data (size:%d) --\n", len);
|
||||
deallocateData();
|
||||
// TODO: move out to WS2812FX class: for (seg : _segments) sum += seg.dataSize();
|
||||
if (strip.getUsedSegmentData() + len > MAX_SEGMENT_DATA) return false; //not enough memory
|
||||
// if possible use SPI RAM on ESP32
|
||||
#if defined(ARDUINO_ARCH_ESP32) && defined(WLED_USE_PSRAM)
|
||||
@ -143,19 +151,23 @@ bool Segment::allocateData(uint16_t len) {
|
||||
#endif
|
||||
data = (byte*) malloc(len);
|
||||
if (!data) return false; //allocation failed
|
||||
strip.addUsedSegmentData(len);
|
||||
strip.addUsedSegmentData(len); // TODO: move out to WS2812FX class: for (seg : _segments) sum += seg.dataSize();
|
||||
_dataLen = len;
|
||||
memset(data, 0, len);
|
||||
DEBUG_PRINTF("-- Allocated data %p (%d)\n", data, (int)len);
|
||||
return true;
|
||||
}
|
||||
|
||||
void Segment::deallocateData() {
|
||||
// NOTE: deallocating data sometimes produces corrupt heap.
|
||||
if (!data) return;
|
||||
DEBUG_PRINTF("-- Deallocating data: %p (%d) --\n", data, (int)_dataLen);
|
||||
DEBUG_PRINTF("-- Deallocating data: %p (%d)\n", data, (int)_dataLen);
|
||||
free(data);
|
||||
DEBUG_PRINTLN(F("-- Data freed."));
|
||||
data = nullptr;
|
||||
strip.addUsedSegmentData(-(int16_t)_dataLen);
|
||||
strip.addUsedSegmentData(-(int16_t)_dataLen); // TODO: move out to WS2812FX class: for (seg : _segments) sum -= seg.dataSize();
|
||||
_dataLen = 0;
|
||||
DEBUG_PRINTLN(F("-- Dealocated data."));
|
||||
}
|
||||
|
||||
/**
|
||||
@ -168,7 +180,6 @@ void Segment::deallocateData() {
|
||||
void Segment::resetIfRequired() {
|
||||
if (reset) { // (getOption(SEG_OPTION_RESET))
|
||||
next_time = 0; step = 0; call = 0; aux0 = 0; aux1 = 0;
|
||||
deallocateData();
|
||||
reset = false; // setOption(SEG_OPTION_RESET, false);
|
||||
}
|
||||
}
|
||||
@ -653,12 +664,12 @@ void WS2812FX::service() {
|
||||
if (nowUp - _lastShow < MIN_SHOW_DELAY) return;
|
||||
bool doShow = false;
|
||||
|
||||
_isServicing = true;
|
||||
_segment_index = 0;
|
||||
for (segment &seg : _segments) {
|
||||
// for (int i = 0; i < getMaxSegments(); i++) {
|
||||
// Segment &seg = getSegment(i);
|
||||
// reset the segment runtime data if needed, called before isActive to ensure deleted
|
||||
// segment's buffers are cleared
|
||||
// reset the segment runtime data if needed
|
||||
seg.resetIfRequired();
|
||||
|
||||
if (!seg.isActive()) continue;
|
||||
@ -700,6 +711,7 @@ void WS2812FX::service() {
|
||||
show();
|
||||
}
|
||||
_triggered = false;
|
||||
_isServicing = false;
|
||||
}
|
||||
|
||||
void WS2812FX::setPixelColor(int i, uint32_t col)
|
||||
@ -987,13 +999,14 @@ uint8_t WS2812FX::getLastActiveSegmentId(void) {
|
||||
return _segments.size()-1;
|
||||
}
|
||||
|
||||
//uint8_t WS2812FX::getActiveSegmentsNum(void) {
|
||||
// uint8_t c = 0;
|
||||
uint8_t WS2812FX::getActiveSegmentsNum(void) {
|
||||
uint8_t c = 0;
|
||||
// for (uint8_t i = 0; i < getMaxSegments(); i++) {
|
||||
// if (_segments[i].isActive()) c++;
|
||||
// }
|
||||
// return c;
|
||||
//}
|
||||
for (int i = 0; i < _segments.size(); i++) {
|
||||
if (_segments[i].isActive()) c++;
|
||||
}
|
||||
return c;
|
||||
}
|
||||
|
||||
uint16_t WS2812FX::getLengthPhysical(void) {
|
||||
uint16_t len = 0;
|
||||
@ -1037,17 +1050,26 @@ bool WS2812FX::hasCCTBus(void) {
|
||||
}
|
||||
|
||||
void WS2812FX::purgeSegments(void) {
|
||||
// remove inactive segments at the back
|
||||
//while (_segments.back().stop == 0 && _segments.size() > 1) _segments.pop_back();
|
||||
// remove all inactive segments (from the back)
|
||||
int deleted = 0;
|
||||
for (int i = _segments.size()-1; i > 0; i--) if (_segments[i].stop == 0) { DEBUG_PRINT(F(" Removing segment: ")); DEBUG_PRINTLN(i); deleted++; _segments.erase(_segments.begin() + i); }
|
||||
if (_segments.size() <= 1 || _isServicing) return;
|
||||
for (int i = _segments.size()-1; i > 0; i--)
|
||||
if (_segments[i].stop == 0) {
|
||||
DEBUG_PRINT(F("-- Removing segment: ")); DEBUG_PRINTLN(i);
|
||||
deleted++;
|
||||
_segments.erase(_segments.begin() + i);
|
||||
}
|
||||
if (deleted) {
|
||||
_segments.shrink_to_fit();
|
||||
if (_mainSegment >= _segments.size()) setMainSegmentId(0);
|
||||
}
|
||||
}
|
||||
|
||||
Segment& WS2812FX::getSegment(uint8_t id) {
|
||||
// return _segments[id >= getMaxSegments() ? getMainSegmentId() : id];
|
||||
return _segments[id >= _segments.size() ? getMainSegmentId() : id]; // vectors
|
||||
}
|
||||
|
||||
void WS2812FX::setSegment(uint8_t n, uint16_t i1, uint16_t i2, uint8_t grouping, uint8_t spacing, uint16_t offset, uint16_t startY, uint16_t stopY) {
|
||||
if (n >= _segments.size()) return;
|
||||
// if (n >= getMaxSegments()) return;
|
||||
@ -1067,12 +1089,12 @@ void WS2812FX::setSegment(uint8_t n, uint16_t i1, uint16_t i2, uint8_t grouping,
|
||||
if (i2 <= i1) //disable segment
|
||||
{
|
||||
// disabled segments should get removed using purgeSegments()
|
||||
DEBUG_PRINTLN(F(" Segment marked inactive."));
|
||||
DEBUG_PRINT(F("-- Segment ")); DEBUG_PRINT(n); DEBUG_PRINTLN(F(" marked inactive."));
|
||||
seg.stop = 0;
|
||||
if (seg.name) {
|
||||
delete[] seg.name;
|
||||
seg.name = nullptr;
|
||||
}
|
||||
//if (seg.name) {
|
||||
// delete[] seg.name;
|
||||
// seg.name = nullptr;
|
||||
//}
|
||||
// if main segment is deleted, set first active as main segment
|
||||
if (n == _mainSegment) setMainSegmentId(0);
|
||||
seg.markForReset();
|
||||
@ -1216,9 +1238,8 @@ void WS2812FX::makeAutoSegments(bool forceReset) {
|
||||
|
||||
void WS2812FX::fixInvalidSegments() {
|
||||
//make sure no segment is longer than total (sanity check)
|
||||
size_t i = 0;
|
||||
for (std::vector<Segment>::iterator it = _segments.begin(); it != _segments.end(); i++, it++) {
|
||||
if (_segments[i].start >= _length) { _segments.erase(it); i--; it--; continue; }
|
||||
for (int i = _segments.size()-1; i > 0; i--) {
|
||||
if (_segments[i].start >= _length) { _segments.erase(_segments.begin()+i); continue; }
|
||||
if (_segments[i].stop > _length) _segments[i].stop = _length;
|
||||
// this is always called as the last step after finalizeInit(), update covered bus types
|
||||
_segments[i].refreshLightCapabilities();
|
||||
|
@ -1179,7 +1179,8 @@ function makeWS() {
|
||||
|
||||
function readState(s,command=false)
|
||||
{
|
||||
if (!s) return false;
|
||||
if (!s || s.error) return false;
|
||||
if (s.success) return true; // no data to process
|
||||
|
||||
isOn = s.on;
|
||||
gId('sliderBri').value = s.bri;
|
||||
@ -1224,7 +1225,7 @@ function readState(s,command=false)
|
||||
if (!i) {
|
||||
showToast('No Segments!', true);
|
||||
updateUI();
|
||||
return;
|
||||
return true;
|
||||
}
|
||||
|
||||
var cd = gId('csl').children;
|
||||
@ -1271,6 +1272,7 @@ function readState(s,command=false)
|
||||
selectedFx = i.fx;
|
||||
redrawPalPrev(); // if any color changed (random palette did at least)
|
||||
updateUI();
|
||||
return true;
|
||||
}
|
||||
|
||||
// WLEDSR: control HTML elements for Slider and Color Control
|
||||
|
3521
wled00/html_ui.h
3521
wled00/html_ui.h
File diff suppressed because it is too large
Load Diff
@ -89,7 +89,7 @@ byte relativeChange(byte property, int8_t amount, byte lowerBoundary, byte highe
|
||||
void changeEffect(uint8_t fx)
|
||||
{
|
||||
if (irApplyToAllSelected) {
|
||||
for (uint8_t i = 0; i < strip.getActiveSegmentsNum(); i++) {
|
||||
for (uint8_t i = 0; i < strip.getSegmentsNum(); i++) {
|
||||
Segment& seg = strip.getSegment(i);
|
||||
if (!seg.isActive() || !seg.isSelected()) continue;
|
||||
strip.setMode(i, fx);
|
||||
@ -105,7 +105,7 @@ void changeEffect(uint8_t fx)
|
||||
void changePalette(uint8_t pal)
|
||||
{
|
||||
if (irApplyToAllSelected) {
|
||||
for (uint8_t i = 0; i < strip.getActiveSegmentsNum(); i++) {
|
||||
for (uint8_t i = 0; i < strip.getSegmentsNum(); i++) {
|
||||
Segment& seg = strip.getSegment(i);
|
||||
if (!seg.isActive() || !seg.isSelected()) continue;
|
||||
seg.palette = pal;
|
||||
@ -124,7 +124,7 @@ void changeEffectSpeed(int8_t amount)
|
||||
int16_t new_val = (int16_t) effectSpeed + amount;
|
||||
effectSpeed = (byte)constrain(new_val,0,255);
|
||||
if (irApplyToAllSelected) {
|
||||
for (uint8_t i = 0; i < strip.getActiveSegmentsNum(); i++) {
|
||||
for (uint8_t i = 0; i < strip.getSegmentsNum(); i++) {
|
||||
Segment& seg = strip.getSegment(i);
|
||||
if (!seg.isActive() || !seg.isSelected()) continue;
|
||||
seg.speed = effectSpeed;
|
||||
@ -147,7 +147,7 @@ void changeEffectSpeed(int8_t amount)
|
||||
prim_hsv.h = (byte)new_val;
|
||||
hsv2rgb_rainbow(prim_hsv, fastled_col);
|
||||
if (irApplyToAllSelected) {
|
||||
for (uint8_t i = 0; i < strip.getActiveSegmentsNum(); i++) {
|
||||
for (uint8_t i = 0; i < strip.getSegmentsNum(); i++) {
|
||||
Segment& seg = strip.getSegment(i);
|
||||
if (!seg.isActive() || !seg.isSelected()) continue;
|
||||
seg.colors[0] = RGBW32(fastled_col.red, fastled_col.green, fastled_col.blue, W(sseg.colors[0]));
|
||||
@ -171,7 +171,7 @@ void changeEffectIntensity(int8_t amount)
|
||||
int16_t new_val = (int16_t) effectIntensity + amount;
|
||||
effectIntensity = (byte)constrain(new_val,0,255);
|
||||
if (irApplyToAllSelected) {
|
||||
for (uint8_t i = 0; i < strip.getActiveSegmentsNum(); i++) {
|
||||
for (uint8_t i = 0; i < strip.getSegmentsNum(); i++) {
|
||||
Segment& seg = strip.getSegment(i);
|
||||
if (!seg.isActive() || !seg.isSelected()) continue;
|
||||
seg.intensity = effectIntensity;
|
||||
@ -192,7 +192,7 @@ void changeEffectIntensity(int8_t amount)
|
||||
prim_hsv.s = (byte)constrain(new_val,0,255); // constrain to 0-255
|
||||
hsv2rgb_rainbow(prim_hsv, fastled_col);
|
||||
if (irApplyToAllSelected) {
|
||||
for (uint8_t i = 0; i < strip.getActiveSegmentsNum(); i++) {
|
||||
for (uint8_t i = 0; i < strip.getSegmentsNum(); i++) {
|
||||
Segment& seg = strip.getSegment(i);
|
||||
if (!seg.isActive() || !seg.isSelected()) continue;
|
||||
seg.colors[0] = RGBW32(fastled_col.red, fastled_col.green, fastled_col.blue, W(sseg.colors[0]));
|
||||
@ -214,7 +214,7 @@ void changeColor(uint32_t c, int16_t cct=-1)
|
||||
{
|
||||
if (irApplyToAllSelected) {
|
||||
// main segment may not be selected!
|
||||
for (uint8_t i = 0; i < strip.getActiveSegmentsNum(); i++) {
|
||||
for (uint8_t i = 0; i < strip.getSegmentsNum(); i++) {
|
||||
Segment& seg = strip.getSegment(i);
|
||||
if (!seg.isActive() || !seg.isSelected()) continue;
|
||||
byte capabilities = seg.getLightCapabilities();
|
||||
|
@ -14,11 +14,10 @@ void deserializeSegment(JsonObject elem, byte it, byte presetId)
|
||||
int stop = elem["stop"] | -1;
|
||||
|
||||
// if using vectors use this code to append segment
|
||||
if (id >= strip.getActiveSegmentsNum()) {
|
||||
if (id >= strip.getSegmentsNum()) {
|
||||
if (stop <= 0) return; // ignore empty/inactive segments
|
||||
DEBUG_PRINT(F("Adding segment: ")); DEBUG_PRINTLN(id);
|
||||
strip.appendSegment(Segment(0, strip.getLengthTotal()));
|
||||
id = strip.getActiveSegmentsNum()-1; // segments are added at the end of list
|
||||
id = strip.getSegmentsNum()-1; // segments are added at the end of list
|
||||
}
|
||||
|
||||
Segment& seg = strip.getSegment(id);
|
||||
@ -258,7 +257,7 @@ bool deserializeState(JsonObject root, byte callMode, byte presetId)
|
||||
if (root["on"].is<const char*>() && root["on"].as<const char*>()[0] == 't') toggleOnOff();
|
||||
|
||||
if (bri && !onBefore) { // unfreeze all segments when turning on
|
||||
for (uint8_t s=0; s < strip.getActiveSegmentsNum(); s++) {
|
||||
for (uint8_t s=0; s < strip.getSegmentsNum(); s++) {
|
||||
strip.getSegment(s).setOption(SEG_OPTION_FREEZE, false);
|
||||
}
|
||||
if (realtimeMode && !realtimeOverride && useMainSegmentOnly) { // keep live segment frozen if live
|
||||
@ -336,7 +335,7 @@ bool deserializeState(JsonObject root, byte callMode, byte presetId)
|
||||
if (id < 0) {
|
||||
//apply all selected segments
|
||||
//bool didSet = false;
|
||||
for (byte s = 0; s < strip.getActiveSegmentsNum(); s++) {
|
||||
for (byte s = 0; s < strip.getSegmentsNum(); s++) {
|
||||
Segment &sg = strip.getSegment(s);
|
||||
if (sg.isSelected()) {
|
||||
deserializeSegment(segVar, s, presetId);
|
||||
@ -350,14 +349,10 @@ bool deserializeState(JsonObject root, byte callMode, byte presetId)
|
||||
}
|
||||
} else {
|
||||
JsonArray segs = segVar.as<JsonArray>();
|
||||
for (JsonObject elem : segs)
|
||||
{
|
||||
DEBUG_PRINT(F(" Deserializing segment: ")); DEBUG_PRINTLN(it);
|
||||
for (JsonObject elem : segs) {
|
||||
deserializeSegment(elem, it, presetId);
|
||||
it++;
|
||||
}
|
||||
// DEBUG_PRINTLN(F(" Purging segments."));
|
||||
// strip.purgeSegments(); // prune inactive segments (resets ESP if effect running)
|
||||
}
|
||||
|
||||
usermods.readFromJsonState(root);
|
||||
@ -505,7 +500,7 @@ void serializeState(JsonObject root, bool forPreset, bool includeBri, bool segme
|
||||
bool selectedSegmentsOnly = root[F("sc")] | false;
|
||||
JsonArray seg = root.createNestedArray("seg");
|
||||
for (byte s = 0; s < strip.getMaxSegments(); s++) {
|
||||
if (s >= strip.getActiveSegmentsNum()) {
|
||||
if (s >= strip.getSegmentsNum()) {
|
||||
if (forPreset && segmentBounds) { //disable segments not part of preset
|
||||
JsonObject seg0 = seg.createNestedObject();
|
||||
seg0["stop"] = 0;
|
||||
@ -537,7 +532,7 @@ void serializeInfo(JsonObject root)
|
||||
leds["fps"] = strip.getFps();
|
||||
leds[F("maxpwr")] = (strip.currentMilliamps)? strip.ablMilliampsMax : 0;
|
||||
leds[F("maxseg")] = strip.getMaxSegments();
|
||||
leds[F("actseg")] = strip.getActiveSegmentsNum();
|
||||
//leds[F("actseg")] = strip.getActiveSegmentsNum();
|
||||
//leds[F("seglock")] = false; //might be used in the future to prevent modifications to segment config
|
||||
|
||||
#ifndef WLED_DISABLE_2D
|
||||
|
@ -31,7 +31,7 @@ void applyValuesToSelectedSegs()
|
||||
// copy of first selected segment to tell if value was updated
|
||||
uint8_t firstSel = strip.getFirstSelectedSegId();
|
||||
Segment selsegPrev = strip.getSegment(firstSel);
|
||||
for (uint8_t i = 0; i < strip.getActiveSegmentsNum(); i++) {
|
||||
for (uint8_t i = 0; i < strip.getSegmentsNum(); i++) {
|
||||
Segment& seg = strip.getSegment(i);
|
||||
if (i != firstSel && (!seg.isActive() || !seg.isSelected())) continue;
|
||||
|
||||
|
@ -608,7 +608,7 @@ bool handleSet(AsyncWebServerRequest *request, const String& req, bool apply)
|
||||
pos = req.indexOf(F("SS="));
|
||||
if (pos > 0) {
|
||||
byte t = getNumVal(&req, pos);
|
||||
if (t < strip.getActiveSegmentsNum()) {
|
||||
if (t < strip.getSegmentsNum()) {
|
||||
selectedSeg = t;
|
||||
singleSegment = true;
|
||||
}
|
||||
@ -618,7 +618,7 @@ bool handleSet(AsyncWebServerRequest *request, const String& req, bool apply)
|
||||
pos = req.indexOf(F("SV=")); //segment selected
|
||||
if (pos > 0) {
|
||||
byte t = getNumVal(&req, pos);
|
||||
if (t == 2) for (uint8_t i = 0; i < strip.getActiveSegmentsNum(); i++) strip.getSegment(i).setOption(SEG_OPTION_SELECTED, 0); // unselect other segments
|
||||
if (t == 2) for (uint8_t i = 0; i < strip.getSegmentsNum(); i++) strip.getSegment(i).setOption(SEG_OPTION_SELECTED, 0); // unselect other segments
|
||||
selseg.setOption(SEG_OPTION_SELECTED, t);
|
||||
}
|
||||
|
||||
@ -824,7 +824,7 @@ bool handleSet(AsyncWebServerRequest *request, const String& req, bool apply)
|
||||
stateChanged |= (fxModeChanged || speedChanged || intensityChanged || paletteChanged);
|
||||
|
||||
// apply to main and all selected segments to prevent #1618.
|
||||
for (uint8_t i = 0; i < strip.getActiveSegmentsNum(); i++) {
|
||||
for (uint8_t i = 0; i < strip.getSegmentsNum(); i++) {
|
||||
Segment& seg = strip.getSegment(i);
|
||||
if (i != selectedSeg && (singleSegment || !seg.isActive() || !seg.isSelected())) continue; // skip non main segments if not applying to all
|
||||
if (fxModeChanged) strip.setMode(i, effectIn);
|
||||
|
@ -91,10 +91,12 @@ void notify(byte callMode, bool followUp)
|
||||
|
||||
udpOut[39] = strip.getActiveSegmentsNum();
|
||||
udpOut[40] = UDP_SEG_SIZE; //size of each loop iteration (one segment)
|
||||
for (uint8_t i = 0; i < strip.getActiveSegmentsNum(); i++) {
|
||||
int s = 0;
|
||||
for (uint8_t i = 0; i < strip.getSegmentsNum(); i++) {
|
||||
Segment &selseg = strip.getSegment(i);
|
||||
uint16_t ofs = 41 + i*UDP_SEG_SIZE; //start of segment offset byte
|
||||
udpOut[0 +ofs] = i;
|
||||
if (!selseg.isActive()) continue;
|
||||
uint16_t ofs = 41 + s*UDP_SEG_SIZE; //start of segment offset byte
|
||||
udpOut[0 +ofs] = s;
|
||||
udpOut[1 +ofs] = selseg.start >> 8;
|
||||
udpOut[2 +ofs] = selseg.start & 0xFF;
|
||||
udpOut[3 +ofs] = selseg.stop >> 8;
|
||||
@ -122,6 +124,7 @@ void notify(byte callMode, bool followUp)
|
||||
udpOut[25+ofs] = B(selseg.colors[2]);
|
||||
udpOut[26+ofs] = W(selseg.colors[2]);
|
||||
udpOut[27+ofs] = selseg.cct;
|
||||
++s;
|
||||
}
|
||||
|
||||
//uint16_t offs = SEG_OFFSET;
|
||||
@ -155,7 +158,7 @@ void realtimeLock(uint32_t timeoutMs, byte md)
|
||||
for (uint16_t i = start; i < stop; i++) strip.setPixelColor(i,0,0,0,0);
|
||||
// if WLED was off and using main segment only, freeze non-main segments so they stay off
|
||||
if (useMainSegmentOnly && bri == 0) {
|
||||
for (uint8_t s=0; s < strip.getActiveSegmentsNum(); s++) {
|
||||
for (uint8_t s=0; s < strip.getSegmentsNum(); s++) {
|
||||
strip.getSegment(s).setOption(SEG_OPTION_FREEZE, true);
|
||||
}
|
||||
}
|
||||
@ -342,7 +345,7 @@ void handleNotifications()
|
||||
for (uint8_t i = 0; i < numSrcSegs; i++) {
|
||||
uint16_t ofs = 41 + i*udpIn[40]; //start of segment offset byte
|
||||
uint8_t id = udpIn[0 +ofs];
|
||||
if (id > strip.getActiveSegmentsNum()) break;
|
||||
if (id > strip.getSegmentsNum()) break;
|
||||
Segment& selseg = strip.getSegment(id);
|
||||
uint16_t start = (udpIn[1+ofs] << 8 | udpIn[2+ofs]);
|
||||
uint16_t stop = (udpIn[3+ofs] << 8 | udpIn[4+ofs]);
|
||||
@ -377,7 +380,7 @@ void handleNotifications()
|
||||
|
||||
// simple effect sync, applies to all selected segments
|
||||
if (applyEffects && (version < 11 || !receiveSegmentOptions)) {
|
||||
for (uint8_t i = 0; i < strip.getActiveSegmentsNum(); i++) {
|
||||
for (uint8_t i = 0; i < strip.getSegmentsNum(); i++) {
|
||||
Segment& seg = strip.getSegment(i);
|
||||
if (!seg.isActive() || !seg.isSelected()) continue;
|
||||
if (udpIn[8] < strip.getModeCount()) strip.setMode(i, udpIn[8]);
|
||||
|
@ -118,7 +118,6 @@ void WLED::loop()
|
||||
if (stripMillis > maxStripMillis) maxStripMillis = stripMillis;
|
||||
#endif
|
||||
}
|
||||
if (offMode) strip.purgeSegments(); // remove inactive segments from memory (no effects running)
|
||||
|
||||
yield();
|
||||
#ifdef ESP8266
|
||||
@ -694,6 +693,7 @@ void WLED::handleConnection()
|
||||
DEBUG_PRINT(F("Heap too low! "));
|
||||
DEBUG_PRINTLN(heap);
|
||||
forceReconnect = true;
|
||||
strip.purgeSegments(); // remove inactive segments from memory
|
||||
}
|
||||
lastHeap = heap;
|
||||
heapTime = now;
|
||||
|
@ -8,7 +8,7 @@
|
||||
*/
|
||||
|
||||
// version code in format yymmddb (b = daily build)
|
||||
#define VERSION 2207171
|
||||
#define VERSION 2207191
|
||||
|
||||
//uncomment this if you have a "my_config.h" file you'd like to use
|
||||
//#define WLED_USE_MY_CONFIG
|
||||
|
@ -58,6 +58,10 @@ void wsEvent(AsyncWebSocket * server, AsyncWebSocketClient * client, AwsEventTyp
|
||||
if (verboseResponse) {
|
||||
sendDataWs(client);
|
||||
lastInterfaceUpdate = millis() - (INTERFACE_UPDATE_COOLDOWN -500);
|
||||
} else {
|
||||
// we have to send something back otherwise WS connection closes
|
||||
client->text(F("{\"success\":true}"));
|
||||
lastInterfaceUpdate = millis() - (INTERFACE_UPDATE_COOLDOWN -500);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
|
Loading…
Reference in New Issue
Block a user