From d5e79ff36cf666b49d760ecc5ff4ea4819864a11 Mon Sep 17 00:00:00 2001 From: Phil Bolduc Date: Wed, 9 Dec 2020 17:55:14 -0800 Subject: [PATCH] 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. --- wled00/FX.h | 24 +++++++++++++++++++++++- wled00/FX_fcn.cpp | 5 +++++ 2 files changed, 28 insertions(+), 1 deletion(-) diff --git a/wled00/FX.h b/wled00/FX.h index 6e0b46435..a3e1547cf 100644 --- a/wled00/FX.h +++ b/wled00/FX.h @@ -316,9 +316,31 @@ class WS2812FX { WS2812FX::_usedSegmentData -= _dataLen; _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: uint16_t _dataLen = 0; + bool _requiresReset = false; } segment_runtime; WS2812FX() { diff --git a/wled00/FX_fcn.cpp b/wled00/FX_fcn.cpp index ddb49f6f0..340b047ff 100644 --- a/wled00/FX_fcn.cpp +++ b/wled00/FX_fcn.cpp @@ -76,6 +76,11 @@ void WS2812FX::service() { for(uint8_t i=0; i < MAX_NUM_SEGMENTS; 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(nowUp > SEGENV.next_time || _triggered || (doShow && SEGMENT.mode == 0)) //last is temporary