From f013e04e2206be7b2cd7fa86e65021630337808a Mon Sep 17 00:00:00 2001 From: Maxim Prokhorov Date: Fri, 26 Feb 2021 20:53:58 +0300 Subject: [PATCH] lights: make sure channel target stays consistent Make gamma & invert flags only apply to the transition itself. Revert to previous behaviour, where the modified value is only ever seen by the provider function. --- code/espurna/light.cpp | 36 ++++++++++++++++++++++-------------- 1 file changed, 22 insertions(+), 14 deletions(-) diff --git a/code/espurna/light.cpp b/code/espurna/light.cpp index 702c8fc4..13af9662 100644 --- a/code/espurna/light.cpp +++ b/code/espurna/light.cpp @@ -879,7 +879,10 @@ uint8_t _lightGammaMap(uint8_t value) { 191, 193, 195, 197, 199, 201, 203, 205, 207, 209, 211, 213, 215, 217, 219, 221, 223, 225, 227, 229, 231, 233, 235, 238, 240, 242, 244, 246, 248, 251, 253, 255 }; + static_assert(Light::ValueMax < (sizeof(gamma) / sizeof(gamma[0])), "Out-of-bounds array access"); + static_assert(Light::ValueMin >= 0, "Minimal value can't be negative"); + static_assert(Light::ValueMin < Light::ValueMax, ""); return pgm_read_byte(&gamma[value]); } @@ -890,14 +893,9 @@ public: struct Transition { float& value; - unsigned char target; + long target; float step; size_t count; - - void debug() const { - DEBUG_MSG_P(PSTR("[LIGHT] Transition from %s to %u (step %s, %u times)\n"), - String(value, 2).c_str(), target, String(step, 2).c_str(), count); - } }; explicit LightTransitionHandler(Channels& channels, bool state, LightTransition transition) : @@ -921,19 +919,20 @@ public: bool prepare(channel_t& channel, bool state) { bool target_state = state && channel.state; + long target = target_state ? channel.value : Light::ValueMin; - channel.target = target_state ? channel.value : Light::ValueMin; + channel.target = target; if (channel.gamma) { - channel.target = _lightGammaMap(channel.target); + target = _lightGammaMap(static_cast(target)); } if (channel.inverse) { - channel.target = Light::ValueMax - channel.target; + target = Light::ValueMax - target; } - float diff = static_cast(channel.target) - channel.current; + float diff = static_cast(target) - channel.current; if (isImmediate(target_state, diff)) { - Transition transition { channel.current, channel.target, diff, 1}; + Transition transition { channel.current, target, diff, 1}; _transitions.push_back(std::move(transition)); return false; } @@ -947,11 +946,11 @@ public: } size_t count = _time / every; - Transition transition { channel.current, channel.target, step, count }; - transition.debug(); - + Transition transition { channel.current, target, step, count }; _transitions.push_back(std::move(transition)); + show(transition); + return true; } @@ -1012,6 +1011,15 @@ private: return (!_time || (_step >= _time) || (std::abs(diff) <= std::numeric_limits::epsilon())); } + static void show(const Transition& transition [[gnu::unused]]) { + DEBUG_MSG_P(PSTR("[LIGHT] Transition from %s to %ld (step %s, %u times)\n"), + String(transition.value, 2).c_str(), + transition.target, + String(transition.step, 2).c_str(), + transition.count + ); + } + std::vector _transitions; bool _state_notified { false };