diff --git a/plugins/Kaleidoscope-PersistentLEDMode/src/kaleidoscope/plugin/PersistentLEDMode.cpp b/plugins/Kaleidoscope-PersistentLEDMode/src/kaleidoscope/plugin/PersistentLEDMode.cpp index ce378411..be2d4f17 100644 --- a/plugins/Kaleidoscope-PersistentLEDMode/src/kaleidoscope/plugin/PersistentLEDMode.cpp +++ b/plugins/Kaleidoscope-PersistentLEDMode/src/kaleidoscope/plugin/PersistentLEDMode.cpp @@ -1,6 +1,6 @@ /* -*- mode: c++ -*- * kaleidoscope::plugin::PersistentLEDMode -- Persist the current LED mode to Storage - * Copyright (C) 2019 Keyboard.io, Inc. + * Copyright (C) 2019-2022 Keyboard.io, Inc. * Copyright (C) 2019 Dygma, Inc. * * This program is free software: you can redistribute it and/or modify it under @@ -19,6 +19,7 @@ #include "kaleidoscope/plugin/PersistentLEDMode.h" #include // for EEPROMSettings +#include // for Focus #include // for uint8_t, uint16_t #include "kaleidoscope/Runtime.h" // for Runtime, Runtime_ @@ -30,34 +31,98 @@ namespace kaleidoscope { namespace plugin { uint16_t PersistentLEDMode::settings_base_; -uint8_t PersistentLEDMode::cached_mode_index_; +struct PersistentLEDMode::settings PersistentLEDMode::settings_; EventHandlerResult PersistentLEDMode::onSetup() { - settings_base_ = ::EEPROMSettings.requestSlice(sizeof(cached_mode_index_)); + settings_base_ = ::EEPROMSettings.requestSlice(sizeof(settings_)); - Runtime.storage().get(settings_base_, cached_mode_index_); + Runtime.storage().get(settings_base_, settings_); - // If the index is max, assume an uninitialized EEPROM, and don't set the LED - // mode. We don't change the cached index here, `onLEDModeChange()` will do - // that whenever a led mode change happens. - if (cached_mode_index_ != 0xff) + // If our slice is uninitialized, then return early, without touching the + // current mode. We want auto_save by default, but because EEPROM is + // uninitialized (0xff), that'll be set anyway, so we don't need to. This + // saves us a storage commit. + if (Runtime.storage().isSliceUninitialized(settings_base_, sizeof(settings_))) return EventHandlerResult::OK; - ::LEDControl.set_mode(cached_mode_index_); + ::LEDControl.set_mode(settings_.default_mode_index); return EventHandlerResult::OK; } EventHandlerResult PersistentLEDMode::onLEDModeChange() { - if (cached_mode_index_ == ::LEDControl.get_mode_index()) + if (!settings_.auto_save) return EventHandlerResult::OK; - cached_mode_index_ = ::LEDControl.get_mode_index(); - Runtime.storage().put(settings_base_, cached_mode_index_); + if (settings_.default_mode_index == ::LEDControl.get_mode_index()) + return EventHandlerResult::OK; + + settings_.default_mode_index = ::LEDControl.get_mode_index(); + Runtime.storage().put(settings_base_, settings_); Runtime.storage().commit(); + return EventHandlerResult::OK; } +EventHandlerResult PersistentLEDMode::onFocusEvent(const char *command) { + enum { + AUTO_SAVE, + DEFAULT_MODE, + } sub_command; + + if (::Focus.handleHelp(command, PSTR("led_mode.default\nled_mode.auto_save"))) + return EventHandlerResult::OK; + + if (strncmp_P(command, PSTR("led_mode."), 9) != 0) + return EventHandlerResult::OK; + + if (strcmp_P(command + 9, PSTR("default")) == 0) + sub_command = DEFAULT_MODE; + else if (strcmp_P(command + 9, PSTR("auto_save")) == 0) + sub_command = AUTO_SAVE; + else + return EventHandlerResult::OK; + + switch (sub_command) { + case DEFAULT_MODE: { + if (::Focus.isEOL()) { + ::Focus.send(settings_.default_mode_index); + } else { + uint8_t idx; + ::Focus.read(idx); + settings_.default_mode_index = idx; + ::LEDControl.set_mode(idx); + Runtime.storage().put(settings_base_, settings_); + Runtime.storage().commit(); + } + break; + } + + case AUTO_SAVE: { + if (::Focus.isEOL()) { + ::Focus.send(settings_.auto_save); + } else { + uint8_t v; + ::Focus.read(v); + setAutoSave(v != 0); + } + break; + } + } + + return EventHandlerResult::EVENT_CONSUMED; +} + +void PersistentLEDMode::setAutoSave(bool state) { + settings_.auto_save = state; + Runtime.storage().put(settings_base_, settings_); + Runtime.storage().commit(); +} + +EventHandlerResult PersistentLEDMode::onNameQuery() { + return ::Focus.sendName(F("PersistentLEDMode")); +} + } // namespace plugin } // namespace kaleidoscope diff --git a/plugins/Kaleidoscope-PersistentLEDMode/src/kaleidoscope/plugin/PersistentLEDMode.h b/plugins/Kaleidoscope-PersistentLEDMode/src/kaleidoscope/plugin/PersistentLEDMode.h index 2254f6ac..47f6ffb5 100644 --- a/plugins/Kaleidoscope-PersistentLEDMode/src/kaleidoscope/plugin/PersistentLEDMode.h +++ b/plugins/Kaleidoscope-PersistentLEDMode/src/kaleidoscope/plugin/PersistentLEDMode.h @@ -1,6 +1,6 @@ /* -*- mode: c++ -*- * kaleidoscope::plugin::PersistentLEDMode -- Persist the current LED mode to Storage - * Copyright (C) 2019 Keyboard.io, Inc. + * Copyright (C) 2019-2022 Keyboard.io, Inc. * Copyright (C) 2019 Dygma, Inc. * * This program is free software: you can redistribute it and/or modify it under @@ -31,11 +31,21 @@ class PersistentLEDMode : public kaleidoscope::Plugin { PersistentLEDMode() {} EventHandlerResult onSetup(); + EventHandlerResult onNameQuery(); EventHandlerResult onLEDModeChange(); + EventHandlerResult onFocusEvent(const char *command); + + void setAutoSave(bool state); + bool getAutoSave() { + return settings_.auto_save == 1; + } private: static uint16_t settings_base_; - static uint8_t cached_mode_index_; + static struct settings { + uint8_t auto_save : 1; + uint8_t default_mode_index : 7; + } settings_; }; } // namespace plugin