Skip to content

Commit

Permalink
ActiveModColor: Improve latency by caching interesting keys on layer …
Browse files Browse the repository at this point in the history
…change

Keys normally only change when switching layers, so instead of going through
every key in every cycle to look for modifiers, do that once, when layers
change (using the new `onLayerChange` event), and store the coordinates of keys
we consider modifiers in an array (currently limited to 16 items).

Then, when we want to highlight them, go over this array only, significantly
reducing the work we need to do. In a typical case, on a full-size keyboard, one
would have eight modifiers and a few layer keys, so instead of going through a
hundred keys, we go through sixteen at most, but usually considerably less.

This fixes #403, at the cost of noticeably higher PROGMEM and RAM use.

Signed-off-by: Gergely Nagy <algernon@keyboard.io>
  • Loading branch information
algernon committed Nov 20, 2018
1 parent 7214cc0 commit 38681b9
Show file tree
Hide file tree
Showing 2 changed files with 55 additions and 24 deletions.
72 changes: 48 additions & 24 deletions src/kaleidoscope/plugin/LED-ActiveModColor.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -22,48 +22,72 @@
namespace kaleidoscope {
namespace plugin {

uint8_t ActiveModColorEffect::mod_keys_[MAX_MODS_PER_LAYER];
uint8_t ActiveModColorEffect::mod_key_count_;

cRGB ActiveModColorEffect::highlight_color = (cRGB) {
0xff, 0xff, 0xff
};

cRGB ActiveModColorEffect::sticky_color = CRGB(0xff, 0x00, 0x00);

EventHandlerResult ActiveModColorEffect::beforeReportingState() {
EventHandlerResult ActiveModColorEffect::onLayerChange() {
if (!Kaleidoscope.has_leds)
return EventHandlerResult::OK;

mod_key_count_ = 0;

for (byte r = 0; r < ROWS; r++) {
for (byte c = 0; c < COLS; c++) {
Key k = Layer.lookupOnActiveLayer(r, c);

if (::OneShot.isOneShotKey(k)) {
if (::OneShot.isSticky(k))
::LEDControl.setCrgbAt(r, c, sticky_color);
else if (::OneShot.isActive(k))
::LEDControl.setCrgbAt(r, c, highlight_color);
else
::LEDControl.refreshAt(r, c);
} else if (k.raw >= Key_LeftControl.raw && k.raw <= Key_RightGui.raw) {
if (hid::isModifierKeyActive(k))
::LEDControl.setCrgbAt(r, c, highlight_color);
else
::LEDControl.refreshAt(r, c);
} else if (k.flags == (SYNTHETIC | SWITCH_TO_KEYMAP)) {
uint8_t layer = k.keyCode;
if (layer >= LAYER_SHIFT_OFFSET)
layer -= LAYER_SHIFT_OFFSET;

if (Layer.isOn(layer))
::LEDControl.setCrgbAt(r, c, highlight_color);
else
::LEDControl.refreshAt(r, c);
Key k = Layer.lookup(r, c);

if (::OneShot.isOneShotKey(k) ||
(k.raw >= Key_LeftControl.raw && k.raw <= Key_RightGui.raw) ||
(k.flags == (SYNTHETIC | SWITCH_TO_KEYMAP))) {
uint8_t coords = r * COLS + c;
mod_keys_[mod_key_count_++] = coords;
}
}
}

return EventHandlerResult::OK;
}

EventHandlerResult ActiveModColorEffect::beforeReportingState() {
for (uint8_t i = 0; i < mod_key_count_; i++) {
uint8_t coords = mod_keys_[i];
byte c = coords % COLS;
byte r = (coords - c) / COLS;

Key k = Layer.lookup(r, c);

if (::OneShot.isOneShotKey(k)) {
if (::OneShot.isSticky(k))
::LEDControl.setCrgbAt(r, c, sticky_color);
else if (::OneShot.isActive(k))
::LEDControl.setCrgbAt(r, c, highlight_color);
else
::LEDControl.refreshAt(r, c);
} else if (k.raw >= Key_LeftControl.raw && k.raw <= Key_RightGui.raw) {
if (hid::isModifierKeyActive(k))
::LEDControl.setCrgbAt(r, c, highlight_color);
else
::LEDControl.refreshAt(r, c);
} else if (k.flags == (SYNTHETIC | SWITCH_TO_KEYMAP)) {
uint8_t layer = k.keyCode;
if (layer >= LAYER_SHIFT_OFFSET)
layer -= LAYER_SHIFT_OFFSET;

if (Layer.isOn(layer))
::LEDControl.setCrgbAt(r, c, highlight_color);
else
::LEDControl.refreshAt(r, c);
}
}

return EventHandlerResult::OK;
}

}
}

Expand Down
7 changes: 7 additions & 0 deletions src/kaleidoscope/plugin/LED-ActiveModColor.h
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,8 @@
#include <Kaleidoscope.h>
#include <Kaleidoscope-LEDControl.h>

#define MAX_MODS_PER_LAYER 16

namespace kaleidoscope {
namespace plugin {
class ActiveModColorEffect : public kaleidoscope::Plugin {
Expand All @@ -30,6 +32,11 @@ class ActiveModColorEffect : public kaleidoscope::Plugin {
static cRGB sticky_color;

EventHandlerResult beforeReportingState();
EventHandlerResult onLayerChange();

private:
static uint8_t mod_keys_[MAX_MODS_PER_LAYER];
static uint8_t mod_key_count_;
};
}
}
Expand Down

0 comments on commit 38681b9

Please sign in to comment.