Merge pull request #1213 from gergelypolonkai/persist-heatmap-between-ledmodes

Heatmap: Make Heatmap data persist between LED effect changes
pull/1215/head
Gergely Nagy 2 years ago committed by GitHub
commit dde7caeee9
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

@ -41,13 +41,13 @@ uint8_t Heatmap::heat_colors_length = 4;
// number of millisecond to wait between each heatmap computation // number of millisecond to wait between each heatmap computation
uint16_t Heatmap::update_delay = 1000; uint16_t Heatmap::update_delay = 1000;
uint16_t Heatmap::highest_ = 1;
uint16_t Heatmap::heatmap_[];
Heatmap::TransientLEDMode::TransientLEDMode(const Heatmap *parent) Heatmap::TransientLEDMode::TransientLEDMode(const Heatmap *parent)
: // store the number of times each key has been strock : // last heatmap computation time
heatmap_{}, last_heatmap_comp_time_(Runtime.millisAtCycleStart()),
// max of heatmap_ (we divide by it so we start at 1) parent_(parent) {}
highest_(1),
// last heatmap computation time
last_heatmap_comp_time_(Runtime.millisAtCycleStart()) {}
cRGB Heatmap::TransientLEDMode::computeColor(float v) { cRGB Heatmap::TransientLEDMode::computeColor(float v) {
// compute the color corresponding to a value between 0 and 1 // 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 // we divide every heatmap element by 2
for (auto key_addr : KeyAddr::all()) { 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 // and also divide highest_ accordingly
highest_ = highest_ >> 1; parent_->highest_ = parent_->highest_ >> 1;
} }
void Heatmap::resetMap() { 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 // 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 // getting special attention or if the user just wants a button to reset the map
for (auto key_addr : KeyAddr::all()) { 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 // It may be better to use `onKeyswitchEvent()` here
@ -167,17 +167,17 @@ EventHandlerResult Heatmap::onKeyEvent(KeyEvent &event) {
EventHandlerResult Heatmap::TransientLEDMode::onKeyEvent(KeyEvent &event) { EventHandlerResult Heatmap::TransientLEDMode::onKeyEvent(KeyEvent &event) {
// increment the heatmap_ value related to the key // increment the heatmap_ value related to the key
heatmap_[event.addr.toInt()]++; parent_->heatmap_[event.addr.toInt()]++;
// check highest_ // check highest_
if (highest_ < heatmap_[event.addr.toInt()]) { if (parent_->highest_ < parent_->heatmap_[event.addr.toInt()]) {
highest_ = heatmap_[event.addr.toInt()]; parent_->highest_ = parent_->heatmap_[event.addr.toInt()];
// if highest_ (and so heatmap_ value related to the key) // if highest_ (and so heatmap_ value related to the key)
// is close to overflow: call shiftStats // is close to overflow: call shiftStats
// NOTE: this is barely impossible since shiftStats should be // NOTE: this is barely impossible since shiftStats should be
// called much sooner by Heatmap::loopHook // called much sooner by Heatmap::loopHook
if (highest_ == INT16_MAX) if (parent_->highest_ == INT16_MAX)
shiftStats(); shiftStats();
} }
@ -204,7 +204,7 @@ EventHandlerResult Heatmap::TransientLEDMode::beforeEachCycle() {
// didn't lose any precision in our heatmap since between each color we have a // 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) // maximum precision of 256 ; said differently, there is 256 state (at max)
// between heat_colors[x] and heat_colors[x+1]. // between heat_colors[x] and heat_colors[x+1].
if (highest_ > (static_cast<uint16_t>(heat_colors_length) << 9)) if (parent_->highest_ > (static_cast<uint16_t>(heat_colors_length) << 9))
shiftStats(); shiftStats();
return EventHandlerResult::OK; return EventHandlerResult::OK;
@ -229,7 +229,7 @@ void Heatmap::TransientLEDMode::update() {
for (auto key_addr : KeyAddr::all()) { for (auto key_addr : KeyAddr::all()) {
// how much the key was pressed compared to the others (between 0 and 1) // how much the key was pressed compared to the others (between 0 and 1)
// (total_keys_ can't be equal to 0) // (total_keys_ can't be equal to 0)
float v = static_cast<float>(heatmap_[key_addr.toInt()]) / highest_; float v = static_cast<float>(parent_->heatmap_[key_addr.toInt()]) / parent_->highest_;
// we could have used an interger instead of a float, but then we would // we could have used an interger instead of a float, but then we would
// have had to change some multiplication in division. // have had to change some multiplication in division.
// / on uint is slower than * on float, so I stay with the float // / on uint is slower than * on float, so I stay with the float

@ -37,6 +37,7 @@ class Heatmap : public Plugin,
static uint16_t update_delay; static uint16_t update_delay;
static const cRGB *heat_colors; static const cRGB *heat_colors;
static uint8_t heat_colors_length; static uint8_t heat_colors_length;
void resetMap(); void resetMap();
EventHandlerResult onKeyEvent(KeyEvent &event); EventHandlerResult onKeyEvent(KeyEvent &event);
@ -60,15 +61,18 @@ class Heatmap : public Plugin,
void update() final; void update() final;
private: private:
uint16_t heatmap_[Runtime.device().numKeys()];
uint16_t highest_;
uint16_t last_heatmap_comp_time_; uint16_t last_heatmap_comp_time_;
const Heatmap *parent_;
void shiftStats(); void shiftStats();
cRGB computeColor(float v); cRGB computeColor(float v);
friend class Heatmap; friend class Heatmap;
}; };
private:
static uint16_t heatmap_[Runtime.device().numKeys()];
static uint16_t highest_;
}; };
} // namespace plugin } // namespace plugin

Loading…
Cancel
Save