|
|
|
@ -30,80 +30,110 @@
@@ -30,80 +30,110 @@
|
|
|
|
|
|
|
|
|
|
#include <type_traits> |
|
|
|
|
|
|
|
|
|
#include <QMetaEnum> |
|
|
|
|
#include <QString> |
|
|
|
|
|
|
|
|
|
#include "settingsstorage.h" |
|
|
|
|
#include "utils/string.h" |
|
|
|
|
|
|
|
|
|
// This is a thin/handy wrapper over `SettingsStorage`. Use it when store/load value
|
|
|
|
|
// rarely occurs, otherwise use `CachedSettingValue`.
|
|
|
|
|
template <typename T> |
|
|
|
|
class CachedSettingValue |
|
|
|
|
class SettingValue |
|
|
|
|
{ |
|
|
|
|
public: |
|
|
|
|
explicit CachedSettingValue(const char *keyName, const T &defaultValue = T()) |
|
|
|
|
: m_keyName(QLatin1String(keyName)) |
|
|
|
|
, m_value(loadValue(defaultValue)) |
|
|
|
|
{ |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
// The signature of the ProxyFunc should be equivalent to the following:
|
|
|
|
|
// T proxyFunc(const T &a);
|
|
|
|
|
template <typename ProxyFunc> |
|
|
|
|
explicit CachedSettingValue(const char *keyName, const T &defaultValue |
|
|
|
|
, ProxyFunc &&proxyFunc) |
|
|
|
|
: m_keyName(QLatin1String(keyName)) |
|
|
|
|
, m_value(proxyFunc(loadValue(defaultValue))) |
|
|
|
|
explicit SettingValue(const char *keyName) |
|
|
|
|
: m_keyName {QLatin1String {keyName}} |
|
|
|
|
{ |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
T value() const |
|
|
|
|
T get(const T &defaultValue = {}) const |
|
|
|
|
{ |
|
|
|
|
return m_value; |
|
|
|
|
return load(defaultValue); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
operator T() const |
|
|
|
|
{ |
|
|
|
|
return value(); |
|
|
|
|
return get(); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
CachedSettingValue<T> &operator=(const T &newValue) |
|
|
|
|
SettingValue<T> &operator=(const T &value) |
|
|
|
|
{ |
|
|
|
|
if (m_value == newValue) |
|
|
|
|
return *this; |
|
|
|
|
|
|
|
|
|
m_value = newValue; |
|
|
|
|
storeValue(m_value); |
|
|
|
|
store(value); |
|
|
|
|
return *this; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
private: |
|
|
|
|
// regular load/save pair
|
|
|
|
|
// regular load/store pair
|
|
|
|
|
template <typename U, typename std::enable_if_t<!std::is_enum<U>::value, int> = 0> |
|
|
|
|
U loadValue(const U &defaultValue) |
|
|
|
|
U load(const U &defaultValue) const |
|
|
|
|
{ |
|
|
|
|
return SettingsStorage::instance()->loadValue(m_keyName, defaultValue).template value<T>(); |
|
|
|
|
return SettingsStorage::instance()->loadValue(m_keyName, defaultValue) |
|
|
|
|
.template value<U>(); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
template <typename U, typename std::enable_if_t<!std::is_enum<U>::value, int> = 0> |
|
|
|
|
void storeValue(const U &value) |
|
|
|
|
void store(const U &value) |
|
|
|
|
{ |
|
|
|
|
SettingsStorage::instance()->storeValue(m_keyName, value); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
// load/save pair for an enum
|
|
|
|
|
// saves literal value of the enum constant, obtained from QMetaEnum
|
|
|
|
|
// load/store pair for enum type, saves literal value of the enum constant
|
|
|
|
|
// TODO: merge the load/store functions with `if constexpr` in C++17
|
|
|
|
|
template <typename U, typename std::enable_if_t<std::is_enum<U>::value, int> = 0> |
|
|
|
|
U loadValue(const U &defaultValue) |
|
|
|
|
U load(const U defaultValue) const |
|
|
|
|
{ |
|
|
|
|
return Utils::String::toEnum(SettingsStorage::instance()->loadValue(m_keyName).toString(), defaultValue); |
|
|
|
|
return Utils::String::toEnum(load(QString {}), defaultValue); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
template <typename U, typename std::enable_if_t<std::is_enum<U>::value, int> = 0> |
|
|
|
|
void storeValue(const U &value) |
|
|
|
|
void store(const U value) |
|
|
|
|
{ |
|
|
|
|
SettingsStorage::instance()->storeValue(m_keyName, Utils::String::fromEnum(value)); |
|
|
|
|
store(Utils::String::fromEnum(value)); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
const QString m_keyName; |
|
|
|
|
T m_value; |
|
|
|
|
}; |
|
|
|
|
|
|
|
|
|
template <typename T> |
|
|
|
|
class CachedSettingValue |
|
|
|
|
{ |
|
|
|
|
public: |
|
|
|
|
explicit CachedSettingValue(const char *keyName, const T &defaultValue = {}) |
|
|
|
|
: m_setting {keyName} |
|
|
|
|
, m_cache {m_setting.get(defaultValue)} |
|
|
|
|
{ |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
// The signature of the ProxyFunc should be equivalent to the following:
|
|
|
|
|
// T proxyFunc(const T &a);
|
|
|
|
|
template <typename ProxyFunc> |
|
|
|
|
explicit CachedSettingValue(const char *keyName, const T &defaultValue, ProxyFunc &&proxyFunc) |
|
|
|
|
: m_setting {keyName} |
|
|
|
|
, m_cache {proxyFunc(m_setting.get(defaultValue))} |
|
|
|
|
{ |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
T get() const |
|
|
|
|
{ |
|
|
|
|
return m_cache; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
operator T() const |
|
|
|
|
{ |
|
|
|
|
return get(); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
CachedSettingValue<T> &operator=(const T &value) |
|
|
|
|
{ |
|
|
|
|
if (m_cache == value) |
|
|
|
|
return *this; |
|
|
|
|
|
|
|
|
|
m_setting = value; |
|
|
|
|
m_cache = value; |
|
|
|
|
return *this; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
private: |
|
|
|
|
SettingValue<T> m_setting; |
|
|
|
|
T m_cache; |
|
|
|
|
}; |
|
|
|
|