From 4abcec8a2b0ffa86a229c9e27287d8a3709b5130 Mon Sep 17 00:00:00 2001 From: Maxim Prokhorov Date: Wed, 20 Jan 2021 15:44:36 +0300 Subject: [PATCH] settings: fix indirect conversions and getSetting specializations --- code/espurna/relay.cpp | 2 +- code/espurna/rfbridge.cpp | 6 +- code/espurna/sensor.cpp | 4 +- code/espurna/settings.cpp | 80 +++++++++++---------- code/espurna/settings.h | 144 +++++++++++++++++++++----------------- code/espurna/ws.cpp | 6 +- 6 files changed, 134 insertions(+), 108 deletions(-) diff --git a/code/espurna/relay.cpp b/code/espurna/relay.cpp index f0fe7d48..c3a8d46f 100644 --- a/code/espurna/relay.cpp +++ b/code/espurna/relay.cpp @@ -1096,7 +1096,7 @@ PayloadStatus relayParsePayload(const char * payload) { void _relayBackwards() { for (unsigned char id = 0; id < _relays.size(); ++id) { - const settings_key_t key {"mqttGroupInv", id}; + SettingsKey key {"mqttGroupInv", id}; if (!hasSetting(key)) continue; setSetting({"mqttGroupSync", id}, getSetting(key)); delSetting(key); diff --git a/code/espurna/rfbridge.cpp b/code/espurna/rfbridge.cpp index a24abc07..52c23f84 100644 --- a/code/espurna/rfbridge.cpp +++ b/code/espurna/rfbridge.cpp @@ -1131,7 +1131,7 @@ void _rfbInitCommands() { // ----------------------------------------------------------------------------- void rfbStore(unsigned char id, bool status, const char * code) { - settings_key_t key { status ? F("rfbON") : F("rfbOFF"), id }; + SettingsKey key { status ? F("rfbON") : F("rfbOFF"), id }; setSetting(key, code); DEBUG_MSG_P(PSTR("[RF] Saved %s => \"%s\"\n"), key.toString().c_str(), code); } @@ -1214,12 +1214,12 @@ void _rfbSettingsMigrate(int version) { String buffer; for (unsigned char index = 0; index < relayCount(); ++index) { - const settings_key_t on_key {F("rfbON"), index}; + SettingsKey on_key {F("rfbON"), index}; if (migrate_code(buffer, getSetting(on_key))) { setSetting(on_key, buffer); } - const settings_key_t off_key {F("rfbOFF"), index}; + SettingsKey off_key {F("rfbOFF"), index}; if (migrate_code(buffer, getSetting(off_key))) { setSetting(off_key, buffer); } diff --git a/code/espurna/sensor.cpp b/code/espurna/sensor.cpp index 7814c05c..936b3f2e 100644 --- a/code/espurna/sensor.cpp +++ b/code/espurna/sensor.cpp @@ -1051,7 +1051,7 @@ const String _sensorQueryDefault(const String& key) { } }; - auto magnitude_key = [](const sensor_magnitude_t& magnitude) -> settings_key_t { + auto magnitude_key = [](const sensor_magnitude_t& magnitude) -> SettingsKey { switch (magnitude.type) { case MAGNITUDE_CURRENT: return {"pwrRatioC", magnitude.index_global}; @@ -1076,7 +1076,7 @@ const String _sensorQueryDefault(const String& key) { case MAGNITUDE_POWER_ACTIVE: case MAGNITUDE_ENERGY: { auto ratioKey(magnitude_key(magnitude)); - if (ratioKey.match(key)) { + if (ratioKey == key) { target = magnitude.sensor; type = magnitude.type; goto return_defaults; diff --git a/code/espurna/settings.cpp b/code/espurna/settings.cpp index e56fd7d2..f75b68cb 100644 --- a/code/espurna/settings.cpp +++ b/code/espurna/settings.cpp @@ -235,14 +235,6 @@ String settingsQueryDefaults(const String& key) { // Key-value API // ----------------------------------------------------------------------------- -String settings_key_t::toString() const { - if (_index < 0) { - return _value; - } else { - return _value + _index; - } -} - settings_move_key_t _moveKeys(const String& from, const String& to, unsigned char index) { return settings_move_key_t {{from, index}, {to, index}}; } @@ -273,65 +265,81 @@ void moveSettings(const String& from, const String& to) { } } -template<> -String getSetting(const settings_key_t& key, String defaultValue) { - auto result = settings::kv_store.get(key.toString()); - if (!result) { - return defaultValue; - } - return result.value; -} - template -bool getSetting(const settings_key_t& key, bool defaultValue); +bool getSetting(const SettingsKey& key, bool defaultValue); template -int getSetting(const settings_key_t& key, int defaultValue); +int getSetting(const SettingsKey& key, int defaultValue); template -long getSetting(const settings_key_t& key, long defaultValue); +long getSetting(const SettingsKey& key, long defaultValue); template -unsigned char getSetting(const settings_key_t& key, unsigned char defaultValue); +unsigned char getSetting(const SettingsKey& key, unsigned char defaultValue); template -unsigned short getSetting(const settings_key_t& key, unsigned short defaultValue); +unsigned short getSetting(const SettingsKey& key, unsigned short defaultValue); template -unsigned int getSetting(const settings_key_t& key, unsigned int defaultValue); +unsigned int getSetting(const SettingsKey& key, unsigned int defaultValue); template -unsigned long getSetting(const settings_key_t& key, unsigned long defaultValue); +unsigned long getSetting(const SettingsKey& key, unsigned long defaultValue); template -float getSetting(const settings_key_t& key, float defaultValue); +float getSetting(const SettingsKey& key, float defaultValue); template -double getSetting(const settings_key_t& key, double defaultValue); +double getSetting(const SettingsKey& key, double defaultValue); + +String getSetting(const String& key) { + return settings::kv_store.get(key).value; +} -String getSetting(const settings_key_t& key) { +String getSetting(const __FlashStringHelper* key) { + return getSetting(String(key)); +} + +String getSetting(const char* key) { + return getSetting(String(key)); +} + +String getSetting(const SettingsKey& key) { static const String defaultValue(""); return getSetting(key, defaultValue); } -String getSetting(const settings_key_t& key, const char* defaultValue) { - return getSetting(key, String(defaultValue)); +String getSetting(const SettingsKey& key, const char* defaultValue) { + return getSetting(key, std::move(String(defaultValue))); } -String getSetting(const settings_key_t& key, const __FlashStringHelper* defaultValue) { - return getSetting(key, String(defaultValue)); +String getSetting(const SettingsKey& key, const __FlashStringHelper* defaultValue) { + return getSetting(key, std::move(String(defaultValue))); } -template<> -bool setSetting(const settings_key_t& key, const String& value) { - return settings::kv_store.set(key.toString(), value); +String getSetting(const SettingsKey& key, const String& defaultValue) { + auto result = settings::kv_store.get(key.toString()); + if (!result) { + result.value = defaultValue; + } + + return result.value; +} + +String getSetting(const SettingsKey& key, String&& defaultValue) { + auto result = settings::kv_store.get(key.toString()); + if (!result) { + result.value = std::move(defaultValue); + } + + return result.value; } -bool delSetting(const settings_key_t& key) { +bool delSetting(const SettingsKey& key) { return settings::kv_store.del(key.toString()); } -bool hasSetting(const settings_key_t& key) { +bool hasSetting(const SettingsKey& key) { return settings::kv_store.has(key.toString()); } diff --git a/code/espurna/settings.h b/code/espurna/settings.h index 4fe78d3e..51a6d961 100644 --- a/code/espurna/settings.h +++ b/code/espurna/settings.h @@ -53,51 +53,63 @@ extern kvs_type kv_store; // -------------------------------------------------------------------------- -class settings_key_t { - - public: - settings_key_t(const char* value, unsigned char index) : - _value(value), _index(index) - {} - settings_key_t(const String& value, unsigned char index) : - _value(value), _index(index) - {} - settings_key_t(String&& value, unsigned char index) : - _value(std::move(value)), _index(index) - {} - settings_key_t(const char* value) : - _value(value), _index(-1) - {} - settings_key_t(const String& value) : - _value(value), _index(-1) - {} - settings_key_t(const __FlashStringHelper* value) : - _value(value), _index(-1) - {} - settings_key_t() : - _value(), _index(-1) - {} - - bool match(const char* value) const { - return (_value == value) || (toString() == value); - } - - bool match(const String& value) const { - return (_value == value) || (toString() == value); - } - - String toString() const; - - explicit operator String () const { - return toString(); - } - - private: - const String _value; - int _index; +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; +using settings_move_key_t = std::pair; using settings_filter_t = std::function; // -------------------------------------------------------------------------- @@ -121,13 +133,13 @@ using is_arduino_string = std::is_same::type>; template using enable_if_arduino_string = std::enable_if::value>; +template +using enable_if_not_arduino_string = std::enable_if::value>; + // -------------------------------------------------------------------------- uint32_t u32fromString(const String& string, int base); -template -using convert_t = T(*)(const String& value); - template T convert(const String& value); @@ -188,35 +200,41 @@ 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 Rfunc = settings::internal::convert> -R getSetting(const settings_key_t& key, R defaultValue) __attribute__((noinline)); +template ::type> +T getSetting(const SettingsKey& key, T defaultValue) __attribute__((noinline)); -template Rfunc = settings::internal::convert> -R getSetting(const settings_key_t& key, R defaultValue) { +template ::type> +T getSetting(const SettingsKey& key, T defaultValue) { auto result = settings::kv_store.get(key.toString()); if (!result) { return defaultValue; } - return Rfunc(result.value); + return settings::internal::convert(result.value); } -template<> -String getSetting(const settings_key_t& key, String defaultValue); +String getSetting(const char* key); +String getSetting(const String& key); +String getSetting(const __FlashStringHelper* key); -String getSetting(const settings_key_t& key); -String getSetting(const settings_key_t& key, const char* defaultValue); -String getSetting(const settings_key_t& key, const __FlashStringHelper* defaultValue); +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 -bool setSetting(const settings_key_t& key, const T& value) { - return settings::kv_store.set(key.toString(), String(value)); +template::type> +bool setSetting(const SettingsKey& key, T&& value) { + return settings::kv_store.set(key.toString(), value); } -template<> -bool setSetting(const settings_key_t& key, const String& value); +template::type> +bool setSetting(const SettingsKey& key, T value) { + return setSetting(key, std::move(String(value))); +} -bool delSetting(const settings_key_t& key); -bool hasSetting(const settings_key_t& key); +bool delSetting(const SettingsKey& key); +bool hasSetting(const SettingsKey& key); void saveSettings(); void resetSettings(); diff --git a/code/espurna/ws.cpp b/code/espurna/ws.cpp index ac4fc6f4..b1855171 100644 --- a/code/espurna/ws.cpp +++ b/code/espurna/ws.cpp @@ -271,9 +271,9 @@ bool _wsStore(const String& key, JsonArray& values) { unsigned char index = 0; for (auto& element : values) { const auto value = element.as(); - const auto keyobj = settings_key_t {key, index}; - if (!hasSetting(keyobj) || value != getSetting(keyobj)) { - setSetting(keyobj, value); + auto setting = SettingsKey {key, index}; + if (!hasSetting(setting) || value != getSetting(setting)) { + setSetting(setting, value); changed = true; } ++index;