From 2734edb2b05a8783777887747f75d8370a9ab6a3 Mon Sep 17 00:00:00 2001 From: Gergely Nagy Date: Wed, 16 Nov 2016 21:46:21 +0100 Subject: [PATCH] hooks: Add a way to replace hooks To make replacing work sanely, we first NULL out both the eventHandlers and loopHooks arrays in the Keyboardio_ constructor. This allows the replace functions to just run through the whole array, and either see hook pointers there, or NULL. So they don't need to be afraid of garbage being there. This makes the replacing very easy: run through the array, and replace the first occurrence of the old hook with the new. This further simplifies addition: the old hook we pass in, will be NULL. If we run out of space, it silently fails, like before. Replacing hooks is important for cases where one wants to build features that can be toggled off, or their behaviour otherwise changed at run-time. In this case, the most efficent way is to replace the hook, which is what these new helpers allow us to do. This closes #36. Signed-off-by: Gergely Nagy --- src/KeyboardioFirmware.cpp | 6 ++++-- src/hooks.cpp | 36 ++++++++++++++++++++---------------- src/hooks.h | 2 ++ src/key_events.cpp | 2 +- 4 files changed, 27 insertions(+), 19 deletions(-) diff --git a/src/KeyboardioFirmware.cpp b/src/KeyboardioFirmware.cpp index 6909c0df..dc0e046a 100644 --- a/src/KeyboardioFirmware.cpp +++ b/src/KeyboardioFirmware.cpp @@ -3,11 +3,13 @@ byte NUMPAD_KEYMAP = 0; Keyboardio_::Keyboardio_(void) { + memset(eventHandlers, 0, HOOK_MAX * sizeof(custom_handler_t)); + memset(loopHooks, 0, HOOK_MAX * sizeof(custom_handler_t)); } void Keyboardio_::setup(const byte keymap_count, const byte numpad_layer) { - event_handler_hook_add (handle_key_event_default); + event_handler_hook_add(handle_key_event_default); wdt_disable(); delay(100); Keyboard.begin(); @@ -20,7 +22,7 @@ Keyboardio_::setup(const byte keymap_count, const byte numpad_layer) { temporary_keymap = primary_keymap = Storage.load_primary_keymap(keymap_count); } -custom_loop_t loopHooks[HOOK_MAX] = {NULL}; +custom_loop_t loopHooks[HOOK_MAX]; void Keyboardio_::loop(void) { diff --git a/src/hooks.cpp b/src/hooks.cpp index 182cabde..ed638e76 100644 --- a/src/hooks.cpp +++ b/src/hooks.cpp @@ -1,27 +1,31 @@ #include "hooks.h" void -event_handler_hook_add (custom_handler_t hook) { - byte i; - - for (i = 0; i < HOOK_MAX && eventHandlers[i] != NULL; i++) { +event_handler_hook_replace (custom_handler_t oldHook, custom_handler_t newHook) { + for (byte i = 0; i < HOOK_MAX; i++) { + if (eventHandlers[i] == oldHook) { + eventHandlers[i] = newHook; + return; + } } - - if (i == HOOK_MAX) - return; - - eventHandlers[i] = hook; } void -loop_hook_add (custom_loop_t hook) { - byte i; +event_handler_hook_add (custom_handler_t hook) { + event_handler_hook_replace ((custom_handler_t)NULL, hook); +} - for (i = 0; i < HOOK_MAX && loopHooks[i] != NULL; i++) { +void +loop_hook_replace (custom_loop_t oldHook, custom_loop_t newHook) { + for (byte i = 0; i < HOOK_MAX; i++) { + if (loopHooks[i] == oldHook) { + loopHooks[i] = newHook; + return; + } } +} - if (i == HOOK_MAX) - return; - - loopHooks[i] = hook; +void +loop_hook_add (custom_loop_t hook) { + loop_hook_replace ((custom_loop_t)NULL, hook); } diff --git a/src/hooks.h b/src/hooks.h index cec4da50..133d91f2 100644 --- a/src/hooks.h +++ b/src/hooks.h @@ -9,8 +9,10 @@ typedef bool (*custom_handler_t)(Key mappedKey, byte row, byte col, uint8_t curr extern custom_handler_t eventHandlers[HOOK_MAX]; void event_handler_hook_add (custom_handler_t hook); +void event_handler_hook_replace (custom_handler_t oldHook, custom_handler_t newHook); typedef void (*custom_loop_t)(void); extern custom_loop_t loopHooks[HOOK_MAX]; void loop_hook_add (custom_loop_t hook); +void loop_hook_replace (custom_loop_t oldHook, custom_loop_t newHook); diff --git a/src/key_events.cpp b/src/key_events.cpp index 09c24aa6..43c8afe8 100644 --- a/src/key_events.cpp +++ b/src/key_events.cpp @@ -39,7 +39,7 @@ void handle_synthetic_key_event(Key mappedKey, uint8_t currentState, uint8_t pre } } -custom_handler_t eventHandlers[HOOK_MAX] = {NULL}; +custom_handler_t eventHandlers[HOOK_MAX]; Key lookup_key(byte keymap, byte row, byte col) { Key mappedKey;