Minor fixes:

- optimized setPixelSegment()
- moved extractModeName() to util.cpp
- optimized extractModeName()
- removed SR extensions from /json/effects endpoint (compatibility estabished)
This commit is contained in:
Blaz Kristan 2022-01-31 20:35:11 +01:00
parent 026a53f3ff
commit d31271fee3
6 changed files with 60 additions and 75 deletions

View File

@ -657,7 +657,6 @@ class WS2812FX {
setPixelColor(uint16_t n, uint8_t r, uint8_t g, uint8_t b, uint8_t w = 0), setPixelColor(uint16_t n, uint8_t r, uint8_t g, uint8_t b, uint8_t w = 0),
show(void), show(void),
setTargetFps(uint8_t fps), setTargetFps(uint8_t fps),
setPixelSegment(uint8_t n),
deserializeMap(uint8_t n=0); deserializeMap(uint8_t n=0);
bool bool
@ -688,6 +687,7 @@ class WS2812FX {
//getFirstSelectedSegment(void), //getFirstSelectedSegment(void),
getMainSegmentId(void), getMainSegmentId(void),
getTargetFps(void), getTargetFps(void),
setPixelSegment(uint8_t n),
gamma8(uint8_t), gamma8(uint8_t),
gamma8_cal(uint8_t, float), gamma8_cal(uint8_t, float),
sin_gap(uint16_t), sin_gap(uint16_t),

View File

@ -135,7 +135,7 @@ void WS2812FX::service() {
uint16_t delay = FRAMETIME; uint16_t delay = FRAMETIME;
if (!SEGMENT.getOption(SEG_OPTION_FREEZE)) { //only run effect function if not frozen if (!SEGMENT.getOption(SEG_OPTION_FREEZE)) { //only run effect function if not frozen
_virtualSegmentLength = SEGMENT.virtualLength(); SEGLEN = SEGMENT.virtualLength();
_bri_t = SEGMENT.opacity; _colors_t[0] = SEGMENT.colors[0]; _colors_t[1] = SEGMENT.colors[1]; _colors_t[2] = SEGMENT.colors[2]; _bri_t = SEGMENT.opacity; _colors_t[0] = SEGMENT.colors[0]; _colors_t[1] = SEGMENT.colors[1]; _colors_t[2] = SEGMENT.colors[2];
uint8_t _cct_t = SEGMENT.cct; uint8_t _cct_t = SEGMENT.cct;
if (!IS_SEGMENT_ON) _bri_t = 0; if (!IS_SEGMENT_ON) _bri_t = 0;
@ -156,7 +156,7 @@ void WS2812FX::service() {
SEGENV.next_time = nowUp + delay; SEGENV.next_time = nowUp + delay;
} }
} }
_virtualSegmentLength = 0; SEGLEN = 0;
busses.setSegmentCCT(-1); busses.setSegmentCCT(-1);
if(doShow) { if(doShow) {
yield(); yield();
@ -716,36 +716,16 @@ bool WS2812FX::checkSegmentAlignment() {
} }
//After this function is called, setPixelColor() will use that segment (offsets, grouping, ... will apply) //After this function is called, setPixelColor() will use that segment (offsets, grouping, ... will apply)
//Note: If called in an interrupt (e.g. JSON API), it must be reset with "setPixelColor(255)", //Note: If called in an interrupt (e.g. JSON API), original segment must be restored,
//otherwise it can lead to a crash on ESP32 because _segment_index is modified while in use by the main thread //otherwise it can lead to a crash on ESP32 because _segment_index is modified while in use by the main thread
#ifdef ARDUINO_ARCH_ESP32 uint8_t WS2812FX::setPixelSegment(uint8_t n)
uint8_t _segment_index_prev = 0;
uint16_t _virtualSegmentLength_prev = 0;
bool _ps_set = false;
#endif
void WS2812FX::setPixelSegment(uint8_t n)
{ {
uint8_t prevSegId = _segment_index;
if (n < MAX_NUM_SEGMENTS) { if (n < MAX_NUM_SEGMENTS) {
#ifdef ARDUINO_ARCH_ESP32
if (!_ps_set) {
_segment_index_prev = _segment_index;
_virtualSegmentLength_prev = _virtualSegmentLength;
_ps_set = true;
}
#endif
_segment_index = n; _segment_index = n;
_virtualSegmentLength = SEGMENT.virtualLength(); SEGLEN = SEGMENT.virtualLength();
} else {
_virtualSegmentLength = 0;
#ifdef ARDUINO_ARCH_ESP32
if (_ps_set) {
_segment_index = _segment_index_prev;
_virtualSegmentLength = _virtualSegmentLength_prev;
_ps_set = false;
}
#endif
} }
return prevSegId;
} }
void WS2812FX::setRange(uint16_t i, uint16_t i2, uint32_t col) void WS2812FX::setRange(uint16_t i, uint16_t i2, uint32_t col)

View File

@ -138,7 +138,6 @@ void serializeState(JsonObject root, bool forPreset = false, bool includeBri = t
void serializeInfo(JsonObject root); void serializeInfo(JsonObject root);
void serializeModeNames(JsonArray arr, const char *qstring); void serializeModeNames(JsonArray arr, const char *qstring);
void serializeModeData(JsonObject root); void serializeModeData(JsonObject root);
uint8_t extractModeName(uint8_t mode, const char *src, char *dest, uint8_t maxLen);
void serveJson(AsyncWebServerRequest* request); void serveJson(AsyncWebServerRequest* request);
bool serveLiveLeds(AsyncWebServerRequest* request, uint32_t wsClient = 0); bool serveLiveLeds(AsyncWebServerRequest* request, uint32_t wsClient = 0);
@ -283,6 +282,7 @@ void _setRandomColor(bool _sec,bool fromButton=false);
bool isAsterisksOnly(const char* str, byte maxLen); bool isAsterisksOnly(const char* str, byte maxLen);
bool requestJSONBufferLock(uint8_t module=255); bool requestJSONBufferLock(uint8_t module=255);
void releaseJSONBufferLock(); void releaseJSONBufferLock();
uint8_t extractModeName(uint8_t mode, const char *src, char *dest, uint8_t maxLen);
//wled_eeprom.cpp //wled_eeprom.cpp
void applyMacro(byte index); void applyMacro(byte index);

View File

@ -174,7 +174,7 @@ void deserializeSegment(JsonObject elem, byte it, byte presetId)
JsonArray iarr = elem[F("i")]; //set individual LEDs JsonArray iarr = elem[F("i")]; //set individual LEDs
if (!iarr.isNull()) { if (!iarr.isNull()) {
strip.setPixelSegment(id); uint8_t oldSegId = strip.setPixelSegment(id);
//freeze and init to black //freeze and init to black
if (!seg.getOption(SEG_OPTION_FREEZE)) { if (!seg.getOption(SEG_OPTION_FREEZE)) {
@ -220,7 +220,7 @@ void deserializeSegment(JsonObject elem, byte it, byte presetId)
set = 0; set = 0;
} }
} }
strip.setPixelSegment(255); strip.setPixelSegment(oldSegId);
strip.trigger(); strip.trigger();
} else if (!elem["frz"] && iarr.isNull()) { //return to regular effect } else if (!elem["frz"] && iarr.isNull()) { //return to regular effect
seg.setOption(SEG_OPTION_FREEZE, false); seg.setOption(SEG_OPTION_FREEZE, false);
@ -874,41 +874,6 @@ void serializeModeNames(JsonArray arr, const char *qstring) {
} }
} }
// extracts effect mode (or palette) name from names serialized string
// caller must provide large enough buffer!
uint8_t extractModeName(uint8_t mode, const char *src, char *dest, uint8_t maxLen)
{
uint8_t qComma = 0;
bool insideQuotes = false;
uint8_t printedChars = 0;
char singleJsonSymbol;
size_t len = strlen_P(src);
// Find the mode name in JSON
for (size_t i = 0; i < len; i++) {
singleJsonSymbol = pgm_read_byte_near(src + i);
if (singleJsonSymbol == '\0') break;
switch (singleJsonSymbol) {
case '"':
insideQuotes = !insideQuotes;
break;
case '[':
case ']':
break;
case ',':
if (!insideQuotes) qComma++;
default:
if (!insideQuotes || (qComma != mode)) break;
dest[printedChars++] = singleJsonSymbol;
}
if ((qComma > mode) || (printedChars >= maxLen)) break;
}
dest[printedChars] = '\0';
char *pos = strchr(dest,'@');
if (pos) *pos = '\0';
return strlen(dest);
}
void serveJson(AsyncWebServerRequest* request) void serveJson(AsyncWebServerRequest* request)
{ {
byte subJson = 0; byte subJson = 0;
@ -925,14 +890,16 @@ void serveJson(AsyncWebServerRequest* request)
} }
else if (url.indexOf(F("eff")) > 0) { else if (url.indexOf(F("eff")) > 0) {
// this is going to serve raw effect names which will include WLED-SR extensions in names // this is going to serve raw effect names which will include WLED-SR extensions in names
request->send_P(200, "application/json", JSON_mode_names); if (requestJSONBufferLock(19)) {
// if we want parsed effect names use this (warning, this will prevent UI from receiving this extension making it useless) AsyncJsonResponse* response = new AsyncJsonResponse(&doc, true); // array document
//AsyncJsonResponse* response = new AsyncJsonResponse(JSON_BUFFER_SIZE, true); // array document JsonArray lDoc = response->getRoot();
//JsonArray doc = response->getRoot(); serializeModeNames(lDoc, JSON_mode_names); // remove WLED-SR extensions from effect names
//deserializeModeNames(doc, JSON_mode_names); // remove WLED-SR extensions from effect names response->setLength();
//response->setLength(); request->send(response);
//request->send(response); releaseJSONBufferLock();
//delete response; } else {
request->send_P(200, "application/json", JSON_mode_names);
}
return; return;
} }
else if (url.indexOf("pal") > 0) { else if (url.indexOf("pal") > 0) {

View File

@ -231,3 +231,41 @@ void releaseJSONBufferLock()
fileDoc = nullptr; fileDoc = nullptr;
jsonBufferLock = 0; jsonBufferLock = 0;
} }
// extracts effect mode (or palette) name from names serialized string
// caller must provide large enough buffer!
uint8_t extractModeName(uint8_t mode, const char *src, char *dest, uint8_t maxLen)
{
uint8_t qComma = 0;
bool insideQuotes = false;
uint8_t printedChars = 0;
char singleJsonSymbol;
size_t len = strlen_P(src);
// Find the mode name in JSON
for (size_t i = 0; i < len; i++) {
singleJsonSymbol = pgm_read_byte_near(src + i);
if (singleJsonSymbol == '\0') break;
if (singleJsonSymbol == '@' && insideQuotes && qComma == mode) break; //stop when SR extension encountered
switch (singleJsonSymbol) {
case '"':
insideQuotes = !insideQuotes;
break;
case '[':
case ']':
break;
case ',':
if (!insideQuotes) qComma++;
default:
if (!insideQuotes || (qComma != mode)) break;
dest[printedChars++] = singleJsonSymbol;
break;
}
if ((qComma > mode) || (printedChars >= maxLen)) break;
}
dest[printedChars] = '\0';
//char *pos = strchr(dest,'@');
//if (pos) *pos = '\0';
return strlen(dest);
}

View File

@ -8,7 +8,7 @@
*/ */
// version code in format yymmddb (b = daily build) // version code in format yymmddb (b = daily build)
#define VERSION 2201281 #define VERSION 2201311
//uncomment this if you have a "my_config.h" file you'd like to use //uncomment this if you have a "my_config.h" file you'd like to use
//#define WLED_USE_MY_CONFIG //#define WLED_USE_MY_CONFIG