code robustness improvements plus minor speedup
* make XY() and _setPixelColorXY_raw() const (minor speedup) * segment is a struct not a class: friend class Segment --> friend struct Segment * fix missing braces around two macros * use non-throwing "new" where possible * improve robustness of transition code
This commit is contained in:
10
wled00/FX.h
10
wled00/FX.h
@@ -610,7 +610,7 @@ typedef struct Segment {
|
||||
uint16_t progress(void) const; //transition progression between 0-65535
|
||||
|
||||
// WLEDMM method inlined for speed (its called at each setPixelColor)
|
||||
inline uint8_t currentBri(uint8_t briNew, bool useCct = false) {
|
||||
[[gnu::hot]] inline uint8_t currentBri(uint8_t briNew, bool useCct = false) {
|
||||
uint32_t prog = (transitional && _t) ? progress() : 0xFFFFU;
|
||||
if (transitional && _t && prog < 0xFFFFU) {
|
||||
if (useCct) return ((briNew * prog) + _t->_cctT * (0xFFFFU - prog)) >> 16;
|
||||
@@ -703,7 +703,7 @@ typedef struct Segment {
|
||||
void deletejMap(); //WLEDMM jMap
|
||||
|
||||
#ifndef WLED_DISABLE_2D
|
||||
inline uint16_t XY(uint_fast16_t x, uint_fast16_t y) const { // support function to get relative index within segment (for leds[]) // WLEDMM inline for speed
|
||||
[[gnu::hot]] inline uint16_t XY(uint_fast16_t x, uint_fast16_t y) const { // support function to get relative index within segment (for leds[]) // WLEDMM inline for speed
|
||||
uint_fast16_t width = max(uint16_t(1), virtualWidth()); // segment width in logical pixels -- softhack007 avoid div/0
|
||||
uint_fast16_t height = max(uint16_t(1), virtualHeight()); // segment height in logical pixels -- softhack007 avoid div/0
|
||||
return (x%width) + (y%height) * width;
|
||||
@@ -711,7 +711,7 @@ typedef struct Segment {
|
||||
|
||||
#ifdef WLEDMM_FASTPATH
|
||||
// WLEDMM this is a "gateway" function - we either call _fast or fall back to "slow"
|
||||
inline void setPixelColorXY(int x, int y, uint32_t col) {
|
||||
[[gnu::hot]] inline void setPixelColorXY(int x, int y, uint32_t col) {
|
||||
if (!_isSimpleSegment) { // slow path
|
||||
setPixelColorXY_slow(x, y, col);
|
||||
} else { // fast path
|
||||
@@ -724,7 +724,7 @@ typedef struct Segment {
|
||||
setPixelColorXY_fast(x, y, col, scaled_col, int(_2dWidth), int(_2dHeight)); // call "fast" function
|
||||
}
|
||||
}
|
||||
inline uint32_t getPixelColorXY(int x, int y) const {
|
||||
[[gnu::hot]] inline uint32_t getPixelColorXY(int x, int y) const {
|
||||
// minimal sanity checks
|
||||
if (!_isValid2D) return 0; // not active
|
||||
if ((unsigned(x) >= _2dWidth) || (unsigned(y) >= _2dHeight)) return 0 ; // check if (x,y) are out-of-range - due to 2's complement, this also catches negative values
|
||||
@@ -1080,7 +1080,7 @@ class WS2812FX { // 96 bytes
|
||||
#endif
|
||||
|
||||
std::vector<segment> _segments;
|
||||
friend class Segment;
|
||||
friend struct Segment;
|
||||
|
||||
uint32_t getPixelColorXYRestored(uint16_t x, uint16_t y) const; // WLEDMM gets the original color from the driver (without downscaling by _bri)
|
||||
|
||||
|
||||
@@ -68,7 +68,7 @@ void WS2812FX::setUpMatrix() {
|
||||
if (!needLedMap) size = 0; // softhack007
|
||||
USER_PRINTF("setupmatrix customMappingTable alloc %d from %d\n", size, customMappingTableSize);
|
||||
//if (customMappingTable != nullptr) delete[] customMappingTable;
|
||||
//customMappingTable = new uint16_t[size];
|
||||
//customMappingTable = new(std::nothrow) uint16_t[size];
|
||||
|
||||
// don't use new / delete
|
||||
if ((size > 0) && (customMappingTable != nullptr)) { // resize
|
||||
@@ -118,7 +118,7 @@ void WS2812FX::setUpMatrix() {
|
||||
JsonArray map = doc.as<JsonArray>();
|
||||
gapSize = map.size();
|
||||
if (!map.isNull() && (gapSize > 0) && gapSize >= customMappingSize) { // not an empty map //softhack also check gapSize>0
|
||||
gapTable = new int8_t[gapSize];
|
||||
gapTable = new(std::nothrow) int8_t[gapSize];
|
||||
if (gapTable) for (size_t i = 0; i < gapSize; i++) {
|
||||
gapTable[i] = constrain(map[i], -1, 1);
|
||||
}
|
||||
|
||||
@@ -93,9 +93,9 @@ Segment::Segment(const Segment &orig) {
|
||||
_dataLen = 0;
|
||||
_t = nullptr;
|
||||
if (ledsrgb && !Segment::_globalLeds) {ledsrgb = nullptr; ledsrgbSize = 0;} // WLEDMM
|
||||
if (orig.name) { name = new char[strlen(orig.name)+1]; if (name) strcpy(name, orig.name); }
|
||||
if (orig.name) { name = new(std::nothrow) char[strlen(orig.name)+1]; if (name) strcpy(name, orig.name); }
|
||||
if (orig.data) { if (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); }
|
||||
//if (orig._t) { _t = new(std::nothrow) Transition(orig._t->_dur, orig._t->_briT, orig._t->_cctT, orig._t->_colorT); }
|
||||
//else markForReset(); // WLEDMM
|
||||
// if (orig.ledsrgb && !Segment::_globalLeds) { allocLeds(); if (ledsrgb) memcpy(ledsrgb, orig.ledsrgb, sizeof(CRGB)*length()); } // WLEDMM
|
||||
jMap = nullptr; //WLEDMM jMap
|
||||
@@ -178,9 +178,9 @@ Segment& Segment::operator= (const Segment &orig) {
|
||||
//if (!Segment::_globalLeds) {ledsrgb = oldLeds; ledsrgbSize = oldLedsSize;}; // WLEDMM reuse leds instead of ledsrgb = nullptr;
|
||||
if (!Segment::_globalLeds) {ledsrgb = nullptr; ledsrgbSize = 0;}; // WLEDMM copy has no buffers (yet)
|
||||
// copy source data
|
||||
if (orig.name) { name = new char[strlen(orig.name)+1]; if (name) strcpy(name, orig.name); }
|
||||
if (orig.name) { name = new(std::nothrow) char[strlen(orig.name)+1]; if (name) strcpy(name, orig.name); }
|
||||
if (orig.data) { if (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); }
|
||||
//if (orig._t) { _t = new(std::nothrow) Transition(orig._t->_dur, orig._t->_briT, orig._t->_cctT, orig._t->_colorT); }
|
||||
//else markForReset(); // WLEDMM
|
||||
//if (orig.ledsrgb && !Segment::_globalLeds) { allocLeds(); if (ledsrgb) memcpy(ledsrgb, orig.ledsrgb, sizeof(CRGB)*length()); } // WLEDMM don't copy old buffer
|
||||
jMap = nullptr; //WLEDMM jMap
|
||||
@@ -441,7 +441,7 @@ void Segment::startTransition(uint16_t dur) {
|
||||
uint32_t _colorT[NUM_COLORS];
|
||||
for (size_t i=0; i<NUM_COLORS; i++) _colorT[i] = currentColor(i, colors[i]);
|
||||
|
||||
if (!_t) _t = new Transition(dur); // no previous transition running
|
||||
if (!_t) _t = new(std::nothrow) Transition(dur); // no previous transition running
|
||||
if (!_t) return; // failed to allocate data
|
||||
_t->_briT = _briT;
|
||||
_t->_cctT = _cctT;
|
||||
@@ -473,7 +473,7 @@ uint8_t IRAM_ATTR_YN Segment::currentBri(uint8_t briNew, bool useCct) {
|
||||
#endif
|
||||
|
||||
uint8_t Segment::currentMode(uint8_t newMode) {
|
||||
return (progress()>32767U) ? newMode : _t->_modeP; // change effect in the middle of transition
|
||||
return (progress()>32767U) ? newMode : (_t ? _t->_modeP : newMode); // change effect in the middle of transition
|
||||
}
|
||||
|
||||
uint32_t Segment::currentColor(uint8_t slot, uint32_t colorNew) {
|
||||
@@ -755,7 +755,7 @@ class JMapC {
|
||||
ArrayAndSize arrayAndSize;
|
||||
arrayAndSize.size = 0;
|
||||
if (arrayChunk[0].is<JsonArray>()) { //if array of arrays
|
||||
arrayAndSize.array = new XandY[arrayChunk.size()];
|
||||
arrayAndSize.array = new(std::nothrow) XandY[arrayChunk.size()];
|
||||
for (JsonVariant arrayElement: arrayChunk) {
|
||||
maxWidth = max((uint16_t)maxWidth, arrayElement[0].as<uint16_t>()); // WLEDMM use native min/max
|
||||
maxHeight = max((uint16_t)maxHeight, arrayElement[1].as<uint16_t>()); // WLEDMM
|
||||
@@ -766,7 +766,7 @@ class JMapC {
|
||||
}
|
||||
}
|
||||
else { // if array (of x and y)
|
||||
arrayAndSize.array = new XandY[1];
|
||||
arrayAndSize.array = new(std::nothrow) XandY[1];
|
||||
maxWidth = max((uint16_t)maxWidth, arrayChunk[0].as<uint16_t>()); // WLEDMM use native min/max
|
||||
maxHeight = max((uint16_t)maxHeight, arrayChunk[1].as<uint16_t>()); // WLEDMM
|
||||
arrayAndSize.array[arrayAndSize.size].x = arrayChunk[0].as<uint8_t>();
|
||||
@@ -798,7 +798,7 @@ class JMapC {
|
||||
void Segment::createjMap() {
|
||||
if (!jMap) {
|
||||
DEBUG_PRINTLN("createjMap");
|
||||
jMap = new JMapC();
|
||||
jMap = new(std::nothrow) JMapC();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1704,14 +1704,14 @@ void WS2812FX::enumerateLedmaps() {
|
||||
if (len > 0 && len < 33) {
|
||||
(void) cleanUpName(name);
|
||||
len = strlen(name);
|
||||
ledmapNames[i-1] = new char[len+1]; // +1 to include terminating \0
|
||||
ledmapNames[i-1] = new(std::nothrow) char[len+1]; // +1 to include terminating \0
|
||||
if (ledmapNames[i-1]) strlcpy(ledmapNames[i-1], name, 33);
|
||||
}
|
||||
if (!ledmapNames[i-1]) {
|
||||
char tmp[33];
|
||||
snprintf_P(tmp, 32, PSTR("ledmap%d.json"), i);
|
||||
len = strlen(tmp);
|
||||
ledmapNames[i-1] = new char[len+1];
|
||||
ledmapNames[i-1] = new(std::nothrow) char[len+1];
|
||||
if (ledmapNames[i-1]) strlcpy(ledmapNames[i-1], tmp, 33);
|
||||
}
|
||||
|
||||
@@ -2638,7 +2638,7 @@ bool WS2812FX::deserializeMap(uint8_t n) {
|
||||
size_t size = max(ledmapMaxSize, size_t(Segment::maxWidth * Segment::maxHeight)); // TroyHacks
|
||||
USER_PRINTF("deserializemap customMappingTable alloc %u from %u\n", size, customMappingTableSize);
|
||||
//if (customMappingTable != nullptr) delete[] customMappingTable;
|
||||
//customMappingTable = new uint16_t[size];
|
||||
//customMappingTable = new(std::nothrow) uint16_t[size];
|
||||
|
||||
// don't use new / delete
|
||||
if ((size > 0) && (customMappingTable != nullptr)) {
|
||||
|
||||
@@ -146,7 +146,7 @@ bool deserializeSegment(JsonObject elem, byte it, byte presetId)
|
||||
size_t len = 0;
|
||||
if (name != nullptr) len = strlen(name);
|
||||
if (len > 0 && len < 32) {
|
||||
seg.name = new char[len+1];
|
||||
seg.name = new(std::nothrow) char[len+1];
|
||||
if (seg.name) strlcpy(seg.name, name, len+1);
|
||||
} else {
|
||||
// but is empty (already deleted above)
|
||||
|
||||
@@ -68,7 +68,7 @@ int16_t loadPlaylist(JsonObject playlistObj, byte presetId) {
|
||||
if (playlistLen == 0) return -1;
|
||||
if (playlistLen > 100) playlistLen = 100;
|
||||
|
||||
playlistEntries = new PlaylistEntry[playlistLen];
|
||||
playlistEntries = new(std::nothrow) PlaylistEntry[playlistLen];
|
||||
if (playlistEntries == nullptr) return -1;
|
||||
|
||||
byte it = 0;
|
||||
|
||||
Reference in New Issue
Block a user