From d794035f6c94d9af8deebf79e3cc6b86bb18d9bc Mon Sep 17 00:00:00 2001 From: Gergely Polonkai Date: Tue, 5 Jul 2022 11:27:59 +0200 Subject: [PATCH] Heatmap: Make Heatmap data persist between LED effect changes Signed-off-by: Gergely Polonkai --- .../src/kaleidoscope/plugin/Heatmap.cpp | 32 +++++++++---------- .../src/kaleidoscope/plugin/Heatmap.h | 8 +++-- 2 files changed, 22 insertions(+), 18 deletions(-) diff --git a/plugins/Kaleidoscope-Heatmap/src/kaleidoscope/plugin/Heatmap.cpp b/plugins/Kaleidoscope-Heatmap/src/kaleidoscope/plugin/Heatmap.cpp index 1aed3a3b..4eb510ca 100644 --- a/plugins/Kaleidoscope-Heatmap/src/kaleidoscope/plugin/Heatmap.cpp +++ b/plugins/Kaleidoscope-Heatmap/src/kaleidoscope/plugin/Heatmap.cpp @@ -41,13 +41,13 @@ uint8_t Heatmap::heat_colors_length = 4; // number of millisecond to wait between each heatmap computation uint16_t Heatmap::update_delay = 1000; +uint16_t Heatmap::highest_ = 1; +uint16_t Heatmap::heatmap_[]; + Heatmap::TransientLEDMode::TransientLEDMode(const Heatmap *parent) - : // store the number of times each key has been strock - heatmap_{}, - // max of heatmap_ (we divide by it so we start at 1) - highest_(1), - // last heatmap computation time - last_heatmap_comp_time_(Runtime.millisAtCycleStart()) {} + : // last heatmap computation time + last_heatmap_comp_time_(Runtime.millisAtCycleStart()), + parent_(parent) {} cRGB Heatmap::TransientLEDMode::computeColor(float v) { // compute the color corresponding to a value between 0 and 1 @@ -114,11 +114,11 @@ void Heatmap::TransientLEDMode::shiftStats() { // we divide every heatmap element by 2 for (auto key_addr : KeyAddr::all()) { - heatmap_[key_addr.toInt()] = heatmap_[key_addr.toInt()] >> 1; + parent_->heatmap_[key_addr.toInt()] = parent_->heatmap_[key_addr.toInt()] >> 1; } // and also divide highest_ accordingly - highest_ = highest_ >> 1; + parent_->highest_ = parent_->highest_ >> 1; } void Heatmap::resetMap() { @@ -134,10 +134,10 @@ void Heatmap::TransientLEDMode::resetMap() { // this method can be used as a way to work around an existing bug with a single key // getting special attention or if the user just wants a button to reset the map for (auto key_addr : KeyAddr::all()) { - heatmap_[key_addr.toInt()] = 0; + parent_->heatmap_[key_addr.toInt()] = 0; } - highest_ = 1; + parent_->highest_ = 1; } // It may be better to use `onKeyswitchEvent()` here @@ -167,17 +167,17 @@ EventHandlerResult Heatmap::onKeyEvent(KeyEvent &event) { EventHandlerResult Heatmap::TransientLEDMode::onKeyEvent(KeyEvent &event) { // increment the heatmap_ value related to the key - heatmap_[event.addr.toInt()]++; + parent_->heatmap_[event.addr.toInt()]++; // check highest_ - if (highest_ < heatmap_[event.addr.toInt()]) { - highest_ = heatmap_[event.addr.toInt()]; + if (parent_->highest_ < parent_->heatmap_[event.addr.toInt()]) { + parent_->highest_ = parent_->heatmap_[event.addr.toInt()]; // if highest_ (and so heatmap_ value related to the key) // is close to overflow: call shiftStats // NOTE: this is barely impossible since shiftStats should be // called much sooner by Heatmap::loopHook - if (highest_ == INT16_MAX) + if (parent_->highest_ == INT16_MAX) shiftStats(); } @@ -204,7 +204,7 @@ EventHandlerResult Heatmap::TransientLEDMode::beforeEachCycle() { // didn't lose any precision in our heatmap since between each color we have a // maximum precision of 256 ; said differently, there is 256 state (at max) // between heat_colors[x] and heat_colors[x+1]. - if (highest_ > (static_cast(heat_colors_length) << 9)) + if (parent_->highest_ > (static_cast(heat_colors_length) << 9)) shiftStats(); return EventHandlerResult::OK; @@ -229,7 +229,7 @@ void Heatmap::TransientLEDMode::update() { for (auto key_addr : KeyAddr::all()) { // how much the key was pressed compared to the others (between 0 and 1) // (total_keys_ can't be equal to 0) - float v = static_cast(heatmap_[key_addr.toInt()]) / highest_; + float v = static_cast(parent_->heatmap_[key_addr.toInt()]) / parent_->highest_; // we could have used an interger instead of a float, but then we would // have had to change some multiplication in division. // / on uint is slower than * on float, so I stay with the float diff --git a/plugins/Kaleidoscope-Heatmap/src/kaleidoscope/plugin/Heatmap.h b/plugins/Kaleidoscope-Heatmap/src/kaleidoscope/plugin/Heatmap.h index 618021ed..7f3f90a6 100644 --- a/plugins/Kaleidoscope-Heatmap/src/kaleidoscope/plugin/Heatmap.h +++ b/plugins/Kaleidoscope-Heatmap/src/kaleidoscope/plugin/Heatmap.h @@ -37,6 +37,7 @@ class Heatmap : public Plugin, static uint16_t update_delay; static const cRGB *heat_colors; static uint8_t heat_colors_length; + void resetMap(); EventHandlerResult onKeyEvent(KeyEvent &event); @@ -60,15 +61,18 @@ class Heatmap : public Plugin, void update() final; private: - uint16_t heatmap_[Runtime.device().numKeys()]; - uint16_t highest_; uint16_t last_heatmap_comp_time_; + const Heatmap *parent_; void shiftStats(); cRGB computeColor(float v); friend class Heatmap; }; + + private: + static uint16_t heatmap_[Runtime.device().numKeys()]; + static uint16_t highest_; }; } // namespace plugin