- /*
-
- SETTINGS MODULE
-
- Copyright (C) 2016-2019 by Xose Pérez <xose dot perez at gmail dot com>
-
- */
-
- #pragma once
-
- #include <Arduino.h>
-
- #include <functional>
- #include <utility>
- #include <vector>
- #include <type_traits>
-
- #include <ArduinoJson.h>
-
- #include "broker.h"
- #include "storage_eeprom.h"
- #include "settings_embedis.h"
-
- BrokerDeclare(ConfigBroker, void(const String& key, const String& value));
-
- // --------------------------------------------------------------------------
-
- void resetSettings();
- void saveSettings();
- void autosaveSettings();
-
- namespace settings {
-
- class EepromStorage {
- public:
-
- uint8_t read(size_t pos) {
- return eepromRead(pos);
- }
-
- void write(size_t pos, uint8_t value) {
- eepromWrite(pos, value);
- }
-
- void commit() {
- autosaveSettings();
- }
-
- };
-
- using kvs_type = embedis::KeyValueStore<EepromStorage>;
-
- extern kvs_type kv_store;
-
- } // namespace settings
-
- // --------------------------------------------------------------------------
-
- class SettingsKey {
- public:
- SettingsKey(const char* key) :
- _key(key)
- {}
-
- SettingsKey(const String& key) :
- _key(key)
- {}
-
- SettingsKey(String&& key) :
- _key(std::move(key))
- {}
-
- SettingsKey(const String& prefix, unsigned char index) {
- _key.reserve(prefix.length());
- _key += prefix;
- _key += index;
- }
-
- SettingsKey(String&& prefix, unsigned char index) :
- _key(std::move(prefix))
- {
- _key += index;
- }
-
- SettingsKey(const char* prefix, unsigned char index) :
- _key(prefix)
- {
- _key += index;
- }
-
- bool operator==(const char* other) const {
- return _key == other;
- }
-
- bool operator==(const String& other) const {
- return _key == other;
- }
-
- const String& toString() const {
- return _key;
- }
-
- explicit operator String() const & {
- return _key;
- }
-
- explicit operator String() && {
- return std::move(_key);
- }
-
- private:
- String _key;
- };
-
- using settings_move_key_t = std::pair<SettingsKey, SettingsKey>;
- using settings_filter_t = std::function<String(String& value)>;
-
- // --------------------------------------------------------------------------
-
- struct settings_cfg_t {
- String& setting;
- const char* key;
- const char* default_value;
- };
-
- using settings_cfg_list_t = std::initializer_list<settings_cfg_t>;
-
- // --------------------------------------------------------------------------
-
- namespace settings {
- namespace internal {
-
- template <typename T>
- using is_arduino_string = std::is_same<String, typename std::decay<T>::type>;
-
- template <typename T>
- using enable_if_arduino_string = std::enable_if<is_arduino_string<T>::value>;
-
- template <typename T>
- using enable_if_not_arduino_string = std::enable_if<!is_arduino_string<T>::value>;
-
- // --------------------------------------------------------------------------
-
- uint32_t u32fromString(const String& string, int base);
-
- template <typename T>
- T convert(const String& value);
-
- // --------------------------------------------------------------------------
-
- template <>
- float convert(const String& value);
-
- template <>
- double convert(const String& value);
-
- template <>
- int convert(const String& value);
-
- template <>
- long convert(const String& value);
-
- template <>
- bool convert(const String& value);
-
- template <>
- unsigned long convert(const String& value);
-
- template <>
- unsigned int convert(const String& value);
-
- template <>
- unsigned short convert(const String& value);
-
- template <>
- unsigned char convert(const String& value);
-
- template<typename T>
- String serialize(const T& value);
-
- } // namespace internal
- } // namespace settings
-
- // --------------------------------------------------------------------------
-
- struct settings_key_match_t {
- using match_f = bool(*)(const char* key);
- using key_f = const String(*)(const String& key);
-
- match_f match;
- key_f key;
- };
-
- void settingsRegisterDefaults(const settings_key_match_t& matcher);
- String settingsQueryDefaults(const String& key);
-
- // --------------------------------------------------------------------------
-
- void moveSetting(const String& from, const String& to);
- void moveSetting(const String& from, const String& to, unsigned int index);
- void moveSettings(const String& from, const String& to);
-
- template <typename T, typename = typename settings::internal::enable_if_not_arduino_string<T>::type>
- T getSetting(const SettingsKey& key, T defaultValue) __attribute__((noinline));
-
- template <typename T, typename = typename settings::internal::enable_if_not_arduino_string<T>::type>
- T getSetting(const SettingsKey& key, T defaultValue) {
- auto result = settings::kv_store.get(key.toString());
- if (!result) {
- return defaultValue;
- }
- return settings::internal::convert<T>(result.value);
- }
-
- String getSetting(const char* key);
- String getSetting(const String& key);
- String getSetting(const __FlashStringHelper* key);
-
- String getSetting(const SettingsKey& key);
- String getSetting(const SettingsKey& key, const char* defaultValue);
- String getSetting(const SettingsKey& key, const __FlashStringHelper* defaultValue);
- String getSetting(const SettingsKey& key, const String& defaultValue);
- String getSetting(const SettingsKey& key, const String& defaultValue);
- String getSetting(const SettingsKey& key, String&& defaultValue);
-
- template<typename T, typename = typename settings::internal::enable_if_arduino_string<T>::type>
- bool setSetting(const SettingsKey& key, T&& value) {
- return settings::kv_store.set(key.toString(), value);
- }
-
- template<typename T, typename = typename settings::internal::enable_if_not_arduino_string<T>::type>
- bool setSetting(const SettingsKey& key, T value) {
- return setSetting(key, std::move(String(value)));
- }
-
- bool delSetting(const char* key);
- bool delSetting(const String& key);
- bool delSetting(const __FlashStringHelper* key);
- bool delSetting(const SettingsKey& key);
-
- void delSettingPrefix(const std::initializer_list<const char*>&);
- void delSettingPrefix(const char* prefix);
- void delSettingPrefix(const String& prefix);
-
- bool hasSetting(const char* key);
- bool hasSetting(const String& key);
- bool hasSetting(const __FlashStringHelper* key);
- bool hasSetting(const SettingsKey& key);
-
- void settingsGetJson(JsonObject& data);
- bool settingsRestoreJson(char* json_string, size_t json_buffer_size = 1024);
- bool settingsRestoreJson(JsonObject& data);
-
- size_t settingsKeyCount();
- std::vector<String> settingsKeys();
-
- void settingsProcessConfig(const settings_cfg_list_t& config, settings_filter_t filter = nullptr);
-
- size_t settingsSize();
-
- void settingsSetup();
-
- // -----------------------------------------------------------------------------
- // Configuration updates
- // -----------------------------------------------------------------------------
-
- int migrateVersion();
- void migrate();
-
- // -----------------------------------------------------------------------------
- // Deprecated implementation
- // -----------------------------------------------------------------------------
-
- template <typename T>
- String getSetting(const String& key, unsigned char index, T defaultValue)
- __attribute__((deprecated("getSetting({key, index}, default) should be used instead")));
-
- template<typename T>
- bool setSetting(const String& key, unsigned char index, T value)
- __attribute__((deprecated("setSetting({key, index}, value) should be used instead")));
-
- template<typename T>
- bool hasSetting(const String& key, unsigned char index)
- __attribute__((deprecated("hasSetting({key, index}) should be used instead")));
-
- template<typename T>
- bool delSetting(const String& key, unsigned char index)
- __attribute__((deprecated("delSetting({key, index}) should be used instead")));
-
- // --------------------------------------------------------------------------
-
- template<typename T>
- String getSetting(const String& key, unsigned char index, T defaultValue) {
- return getSetting({key, index}, defaultValue);
- }
-
- template<typename T>
- bool setSetting(const String& key, unsigned char index, T value) {
- return setSetting({key, index}, value);
- }
-
- template<typename T>
- bool hasSetting(const String& key, unsigned char index) {
- return hasSetting({key, index});
- }
-
- template<typename T>
- bool delSetting(const String& key, unsigned char index) {
- return delSetting({key, index});
- }
-
|