Fixes an issue where switching effects causes crash

When change effect, flag the the segment's runtime state needs to be cleared. Only clear data that before processing the segment in the main loop.
This commit is contained in:
Phil Bolduc 2020-12-09 17:55:14 -08:00
parent 3a3948e74f
commit d5e79ff36c
2 changed files with 28 additions and 1 deletions

View File

@ -316,9 +316,31 @@ class WS2812FX {
WS2812FX::_usedSegmentData -= _dataLen; WS2812FX::_usedSegmentData -= _dataLen;
_dataLen = 0; _dataLen = 0;
} }
void reset(){next_time = 0; step = 0; call = 0; aux0 = 0; aux1 = 0; deallocateData();}
/**
* If reset of this segment was request, clears runtime
* settings of this segment.
* Must not be called while an effect mode function is running
* because it could access the data buffer and this method
* may free that data buffer.
*/
void resetIfRequired() {
if (_requiresReset) {
next_time = 0; step = 0; call = 0; aux0 = 0; aux1 = 0;
deallocateData();
_requiresReset = false;
}
}
/**
* Flags that before the next effect is calculated,
* the internal segment state should be reset.
* Call resetIfRequired before calling the next effect function.
*/
void reset() { _requiresReset = true; }
private: private:
uint16_t _dataLen = 0; uint16_t _dataLen = 0;
bool _requiresReset = false;
} segment_runtime; } segment_runtime;
WS2812FX() { WS2812FX() {

View File

@ -76,6 +76,11 @@ void WS2812FX::service() {
for(uint8_t i=0; i < MAX_NUM_SEGMENTS; i++) for(uint8_t i=0; i < MAX_NUM_SEGMENTS; i++)
{ {
_segment_index = i; _segment_index = i;
// reset the segment runtime data if needed, called before isActive to ensure deleted
// segment's buffers are cleared
SEGENV.resetIfRequired();
if (SEGMENT.isActive()) if (SEGMENT.isActive())
{ {
if(nowUp > SEGENV.next_time || _triggered || (doShow && SEGMENT.mode == 0)) //last is temporary if(nowUp > SEGENV.next_time || _triggered || (doShow && SEGMENT.mode == 0)) //last is temporary