From e43d2cb391b24fb7488721b602cafba844b14022 Mon Sep 17 00:00:00 2001 From: Gergely Nagy Date: Tue, 15 May 2018 08:48:44 +0200 Subject: [PATCH] Introduce Kaleidoscope.millisAtCycleStart() Many plugins use timers, and most of them will call `millis()`, which isn't wrong, but isn't the most efficient either. While `millis()` isn't terribly expensive, it's not cheap either. For most cases, we do not need an exact timer, and one updated once per cycle is enough - which is what `.millisAtCycleStart()` is. Having a timer that is consistent throughout the whole cycle may also be beneficial. Signed-off-by: Gergely Nagy --- UPGRADING.md | 13 +++++++++++++ src/Kaleidoscope.cpp | 3 +++ src/Kaleidoscope.h | 16 ++++++++++++++++ 3 files changed, 32 insertions(+) diff --git a/UPGRADING.md b/UPGRADING.md index 49a78077..b89d24b8 100644 --- a/UPGRADING.md +++ b/UPGRADING.md @@ -15,6 +15,19 @@ easier to use and develop for: - The new system has more hook points, and the method names are much more clear now. +### Kaleidoscope.millisAtCycleStart() + +Many plugins use timers, and most of them will call `millis()`, which isn't +wrong, but isn't the most efficient either. While `millis()` isn't terribly +expensive, it's not cheap either. For most cases, we do not need an exact timer, +and one updated once per cycle is enough - which is what `.millisAtCycleStart()` +is. Having a timer that is consistent throughout the whole cycle may also be +beneficial. + +While `millis()` should continue to work forever, plugins and user code should, +as a general rule, use `Kaleidoscope.millisAtCycleStart()` rather than +`millis()`. + ### KALEIDOSCOPE_API_VERSION bump `KALEIDOSCOPE_API_VERSION` has been bumped to **2** due to the plugin API diff --git a/src/Kaleidoscope.cpp b/src/Kaleidoscope.cpp index a823c845..7e26109c 100644 --- a/src/Kaleidoscope.cpp +++ b/src/Kaleidoscope.cpp @@ -5,6 +5,7 @@ namespace kaleidoscope { Kaleidoscope_::eventHandlerHook Kaleidoscope_::eventHandlers[HOOK_MAX]; Kaleidoscope_::loopHook Kaleidoscope_::loopHooks[HOOK_MAX]; +uint32_t Kaleidoscope_::millis_at_cycle_start_; Kaleidoscope_::Kaleidoscope_(void) { } @@ -35,6 +36,8 @@ Kaleidoscope_::setup(void) { void Kaleidoscope_::loop(void) { + millis_at_cycle_start_ = millis(); + kaleidoscope::Hooks::beforeEachCycle(); KeyboardHardware.scanMatrix(); diff --git a/src/Kaleidoscope.h b/src/Kaleidoscope.h index 18351add..c3d262b6 100644 --- a/src/Kaleidoscope.h +++ b/src/Kaleidoscope.h @@ -82,6 +82,19 @@ class Kaleidoscope_ { void setup(void); void loop(void); + /** Returns the timer as it was at the start of the cycle. + * The goal of this method is two-fold: + * - To reduce the amount of calls to millis(), providing something cheaper. + * - To have a consistent timer value for the whole duration of a cycle. + * + * This cached value is updated at the start of each cycle as the name + * implies. It is recommended to use this in plugins over millis() unless + * there is good reason not to. + */ + static uint32_t millisAtCycleStart() { + return millis_at_cycle_start_; + } + // ---- Kaleidoscope.use() ---- #if KALEIDOSCOPE_ENABLE_V1_PLUGIN_API @@ -151,6 +164,9 @@ class Kaleidoscope_ { DEPRECATED(LOOP_HOOK); static bool focusHook(const char *command); + + private: + static uint32_t millis_at_cycle_start_; }; extern kaleidoscope::Kaleidoscope_ Kaleidoscope;