diff --git a/src/Kaleidoscope.cpp b/src/Kaleidoscope.cpp index 61ab7483..94c687bd 100644 --- a/src/Kaleidoscope.cpp +++ b/src/Kaleidoscope.cpp @@ -1,9 +1,10 @@ #include "Kaleidoscope.h" #include +Kaleidoscope_::eventHandlerHook Kaleidoscope_::eventHandlers[HOOK_MAX]; +Kaleidoscope_::loopHook Kaleidoscope_::loopHooks[HOOK_MAX]; + Kaleidoscope_::Kaleidoscope_(void) { - memset(eventHandlers, 0, HOOK_MAX * sizeof(custom_handler_t)); - memset(loopHooks, 0, HOOK_MAX * sizeof(custom_handler_t)); } void @@ -13,20 +14,18 @@ Kaleidoscope_::setup(const byte keymap_count) { Keyboard.begin(); KeyboardHardware.setup(); - event_handler_hook_use (NULL); - loop_hook_use (NULL); + // A workaround, so that the compiler does not optimize this out... + handle_key_event (Key_NoKey, 255, 255, 0); Layer.defaultLayer (KeyboardHardware.load_primary_layer (keymap_count)); } -custom_loop_t loopHooks[HOOK_MAX]; - void Kaleidoscope_::loop(void) { KeyboardHardware.scan_matrix(); for (byte i = 0; loopHooks[i] != NULL && i < HOOK_MAX; i++) { - custom_loop_t hook = loopHooks[i]; + loopHook hook = loopHooks[i]; (*hook)(false); } @@ -34,7 +33,7 @@ Kaleidoscope_::loop(void) { Keyboard.releaseAll(); for (byte i = 0; loopHooks[i] != NULL && i < HOOK_MAX; i++) { - custom_loop_t hook = loopHooks[i]; + loopHook hook = loopHooks[i]; (*hook)(true); } } @@ -52,4 +51,52 @@ Kaleidoscope_::use(KaleidoscopePlugin *plugin, ...) { va_end(ap); } +void +Kaleidoscope_::replaceEventHandlerHook(eventHandlerHook oldHook, eventHandlerHook newHook) { + for (byte i = 0; i < HOOK_MAX; i++) { + if (eventHandlers[i] == oldHook) { + eventHandlers[i] = newHook; + return; + } + } +} + +void +Kaleidoscope_::appendEventHandlerHook (eventHandlerHook hook) { + replaceEventHandlerHook((eventHandlerHook)NULL, hook); +} + +void +Kaleidoscope_::useEventHandlerHook (eventHandlerHook hook) { + for (byte i = 0; i < HOOK_MAX; i++) { + if (eventHandlers[i] == hook) + return; + } + appendEventHandlerHook(hook); +} + +void +Kaleidoscope_::replaceLoopHook(loopHook oldHook, loopHook newHook) { + for (byte i = 0; i < HOOK_MAX; i++) { + if (loopHooks[i] == oldHook) { + loopHooks[i] = newHook; + return; + } + } +} + +void +Kaleidoscope_::appendLoopHook(loopHook hook) { + replaceLoopHook((loopHook)NULL, hook); +} + +void +Kaleidoscope_::useLoopHook(loopHook hook) { + for (byte i = 0; i < HOOK_MAX; i++) { + if (loopHooks[i] == hook) + return; + } + appendLoopHook (hook); +} + Kaleidoscope_ Kaleidoscope; diff --git a/src/Kaleidoscope.h b/src/Kaleidoscope.h index d1319b29..0f07e240 100644 --- a/src/Kaleidoscope.h +++ b/src/Kaleidoscope.h @@ -22,9 +22,10 @@ void setup(); #include KALEIDOSCOPE_HARDWARE_H #include "key_events.h" -#include "plugin.h" #include "layers.h" +#define HOOK_MAX 64 + extern HARDWARE_IMPLEMENTATION KeyboardHardware; #ifndef VERSION @@ -33,6 +34,11 @@ extern HARDWARE_IMPLEMENTATION KeyboardHardware; #define KEYMAP_SIZE (sizeof(keymaps) / ROWS / COLS / sizeof(Key)) +class KaleidoscopePlugin { + public: + virtual void begin(void) = 0; +}; + class Kaleidoscope_ { public: Kaleidoscope_(void); @@ -40,6 +46,45 @@ class Kaleidoscope_ { void setup(const byte keymap_count); void loop(void); void use(KaleidoscopePlugin *plugin, ...) __attribute__((sentinel)); + + // ---- hooks ---- + + /* + * In most cases, one only wants a single copy of a hook. On the other hand, + * plugins that depend on other plugins, may want to make it easier for the + * end-user to use the plugin, and call the setup function of the dependent + * plugins too. In case the end-user calls the same setup function, we'd end up + * with hooks registered multiple times. + * + * To avoid this, protection against double-registration has been introduced. + * The `event_handler_hook_use` and `loop_hook_use` functions will only allow + * one copy of the hook. The `event_handler_hook_append` and `loop_hook_append` + * functions will, on the other hand, just append the hooks, and not care about + * protection. + */ + typedef Key (*eventHandlerHook)(Key mappedKey, byte row, byte col, uint8_t keyState); + static eventHandlerHook eventHandlers[HOOK_MAX]; + + static void replaceEventHandlerHook(eventHandlerHook oldHook, eventHandlerHook newHook); + static void appendEventHandlerHook(eventHandlerHook hook); + static void useEventHandlerHook(eventHandlerHook hook); + + typedef void (*loopHook)(bool postClear); + static loopHook loopHooks[HOOK_MAX]; + + static void replaceLoopHook(loopHook oldHook, loopHook newHook); + static void appendLoopHook(loopHook hook); + static void useLoopHook(loopHook hook); }; extern Kaleidoscope_ Kaleidoscope; + +/* -- DEPRECATED aliases; remove them when there are no more users. -- */ + +#define event_handler_hook_use(hook) Kaleidoscope.useEventHandlerHook(hook); +#define event_handler_hook_append(hook) Kaleidoscope.appendEventHandlerHook(hook) +#define event_handler_hook_replace(oldHook, newHook) Kaleidoscope.replaceEventHandlerHook(oldHook, newHook) + +#define loop_hook_use(hook) Kaleidoscope.useLoopHook(hook) +#define loop_hook_append(hook) Kaleidoscope.appendLoopHook(hook) +#define loop_hook_replace(oldHook, newHook) Kaleidoscope.replaceLoopHook(oldHook, newHook) diff --git a/src/hooks.cpp b/src/hooks.cpp deleted file mode 100644 index f304b51a..00000000 --- a/src/hooks.cpp +++ /dev/null @@ -1,49 +0,0 @@ -#include "hooks.h" - -void -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; - } - } -} - -void -event_handler_hook_append (custom_handler_t hook) { - event_handler_hook_replace ((custom_handler_t)NULL, hook); -} - -void -event_handler_hook_use (custom_handler_t hook) { - for (byte i = 0; i < HOOK_MAX; i++) { - if (eventHandlers[i] == hook) - return; - } - event_handler_hook_append (hook); -} - -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; - } - } -} - -void -loop_hook_append (custom_loop_t hook) { - loop_hook_replace ((custom_loop_t)NULL, hook); -} - -void -loop_hook_use (custom_loop_t hook) { - for (byte i = 0; i < HOOK_MAX; i++) { - if (loopHooks[i] == hook) - return; - } - loop_hook_append (hook); -} diff --git a/src/hooks.h b/src/hooks.h deleted file mode 100644 index 29cedd61..00000000 --- a/src/hooks.h +++ /dev/null @@ -1,34 +0,0 @@ -#pragma once - -#include -#include "key_defs.h" - -#define HOOK_MAX 64 - -typedef Key (*custom_handler_t)(Key mappedKey, byte row, byte col, uint8_t keyState); -extern custom_handler_t eventHandlers[HOOK_MAX]; - -/* - * In most cases, one only wants a single copy of a hook. On the other hand, - * plugins that depend on other plugins, may want to make it easier for the - * end-user to use the plugin, and call the setup function of the dependent - * plugins too. In case the end-user calls the same setup function, we'd end up - * with hooks registered multiple times. - * - * To avoid this, protection against double-registration has been introduced. - * The `event_handler_hook_use` and `loop_hook_use` functions will only allow - * one copy of the hook. The `event_handler_hook_append` and `loop_hook_append` - * functions will, on the other hand, just append the hooks, and not care about - * protection. - */ - -void event_handler_hook_use (custom_handler_t hook); -void event_handler_hook_append (custom_handler_t hook); -void event_handler_hook_replace (custom_handler_t oldHook, custom_handler_t newHook); - -typedef void (*custom_loop_t)(bool postClear); -extern custom_loop_t loopHooks[HOOK_MAX]; - -void loop_hook_use (custom_loop_t hook); -void loop_hook_append (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 cfc2b551..0e34355c 100644 --- a/src/key_events.cpp +++ b/src/key_events.cpp @@ -1,5 +1,4 @@ -#include "key_events.h" -#include "layers.h" +#include "Kaleidoscope.h" static bool handle_synthetic_key_event(Key mappedKey, uint8_t keyState) { if (mappedKey.flags & RESERVED) @@ -24,8 +23,6 @@ static bool handle_synthetic_key_event(Key mappedKey, uint8_t keyState) { return true; } -custom_handler_t eventHandlers[HOOK_MAX]; - static bool handle_key_event_default(Key mappedKey, byte row, byte col, uint8_t keyState) { //for every newly pressed button, figure out what logical key it is and send a key down event // for every newly released button, figure out what logical key it is and send a key up event @@ -83,8 +80,8 @@ void handle_key_event(Key mappedKey, byte row, byte col, uint8_t keyState) { if (!(keyState & INJECTED)) { mappedKey = Layer.lookup(row, col); } - for (byte i = 0; eventHandlers[i] != NULL && i < HOOK_MAX; i++) { - custom_handler_t handler = eventHandlers[i]; + for (byte i = 0; Kaleidoscope.eventHandlers[i] != NULL && i < HOOK_MAX; i++) { + Kaleidoscope_::eventHandlerHook handler = Kaleidoscope.eventHandlers[i]; mappedKey = (*handler)(mappedKey, row, col, keyState); if (mappedKey.raw == Key_NoKey.raw) return; diff --git a/src/key_events.h b/src/key_events.h index 0192d494..deb3e0f1 100644 --- a/src/key_events.h +++ b/src/key_events.h @@ -5,7 +5,6 @@ #include KALEIDOSCOPE_HARDWARE_H #include "key_defs.h" #include "keyswitch_state.h" -#include "hooks.h" extern const Key keymaps[][ROWS][COLS]; diff --git a/src/layers.cpp b/src/layers.cpp index d9dfa497..7dff82d4 100644 --- a/src/layers.cpp +++ b/src/layers.cpp @@ -1,5 +1,4 @@ -#include "layers.h" -#include "key_events.h" +#include "Kaleidoscope.h" static uint8_t DefaultLayer; static uint32_t LayerState; diff --git a/src/layers.h b/src/layers.h index 74737df1..33025d3e 100644 --- a/src/layers.h +++ b/src/layers.h @@ -2,7 +2,6 @@ #include #include "key_defs.h" -#include "plugin.h" #include KALEIDOSCOPE_HARDWARE_H class Layer_ { diff --git a/src/plugin.h b/src/plugin.h deleted file mode 100644 index 87b1a817..00000000 --- a/src/plugin.h +++ /dev/null @@ -1,7 +0,0 @@ -#pragma once - -class KaleidoscopePlugin { - public: - virtual void begin(void) = 0; -}; -