Add a thin layer around SettingsStorage class

This new layer would be handy for saving GUI widget states as they don't
need the value cached and they store/load rarely.
This commit is contained in:
Chocobo1
2020-12-28 23:32:59 +08:00
parent 60d65d8137
commit 0b0597be0c
12 changed files with 122 additions and 92 deletions

View File

@@ -482,7 +482,7 @@ Session::Session(QObject *parent)
m_storedCategories = map_cast(m_categories);
}
m_tags = List::toSet(m_storedTags.value());
m_tags = List::toSet(m_storedTags.get());
enqueueRefresh();
updateSeedingLimitTimer();
@@ -1130,7 +1130,7 @@ void Session::initializeNativeSession()
void Session::processBannedIPs(lt::ip_filter &filter)
{
// First, import current filter
for (const QString &ip : asConst(m_bannedIPs.value()))
for (const QString &ip : asConst(m_bannedIPs.get()))
{
lt::error_code ec;
const lt::address addr = lt::make_address(ip.toLatin1().constData(), ec);
@@ -3142,7 +3142,7 @@ void Session::setPeerTurnoverInterval(const int val)
int Session::asyncIOThreads() const
{
return qBound(1, m_asyncIOThreads.value(), 1024);
return qBound(1, m_asyncIOThreads.get(), 1024);
}
void Session::setAsyncIOThreads(const int num)
@@ -3156,7 +3156,7 @@ void Session::setAsyncIOThreads(const int num)
int Session::hashingThreads() const
{
return qBound(1, m_hashingThreads.value(), 1024);
return qBound(1, m_hashingThreads.get(), 1024);
}
void Session::setHashingThreads(const int num)
@@ -3184,7 +3184,7 @@ void Session::setFilePoolSize(const int size)
int Session::checkingMemUsage() const
{
return qMax(1, m_checkingMemUsage.value());
return qMax(1, m_checkingMemUsage.get());
}
void Session::setCheckingMemUsage(int size)
@@ -3201,11 +3201,11 @@ void Session::setCheckingMemUsage(int size)
int Session::diskCacheSize() const
{
#ifdef QBT_APP_64BIT
return qMin(m_diskCacheSize.value(), 33554431); // 32768GiB
return qMin(m_diskCacheSize.get(), 33554431); // 32768GiB
#else
// When build as 32bit binary, set the maximum at less than 2GB to prevent crashes
// allocate 1536MiB and leave 512MiB to the rest of program data in RAM
return qMin(m_diskCacheSize.value(), 1536);
return qMin(m_diskCacheSize.get(), 1536);
#endif
}
@@ -3737,7 +3737,7 @@ bool Session::isListening() const
MaxRatioAction Session::maxRatioAction() const
{
return static_cast<MaxRatioAction>(m_maxRatioAction.value());
return static_cast<MaxRatioAction>(m_maxRatioAction.get());
}
void Session::setMaxRatioAction(const MaxRatioAction act)

View File

@@ -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 SettingValue
{
public:
explicit SettingValue(const char *keyName)
: m_keyName {QLatin1String {keyName}}
{
}
T get(const T &defaultValue = {}) const
{
return load(defaultValue);
}
operator T() const
{
return get();
}
SettingValue<T> &operator=(const T &value)
{
store(value);
return *this;
}
private:
// regular load/store pair
template <typename U, typename std::enable_if_t<!std::is_enum<U>::value, int> = 0>
U load(const U &defaultValue) const
{
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 store(const U &value)
{
SettingsStorage::instance()->storeValue(m_keyName, value);
}
// 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 load(const U defaultValue) const
{
return Utils::String::toEnum(load(QString {}), defaultValue);
}
template <typename U, typename std::enable_if_t<std::is_enum<U>::value, int> = 0>
void store(const U value)
{
store(Utils::String::fromEnum(value));
}
const QString m_keyName;
};
template <typename T>
class CachedSettingValue
{
public:
explicit CachedSettingValue(const char *keyName, const T &defaultValue = T())
: m_keyName(QLatin1String(keyName))
, m_value(loadValue(defaultValue))
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_keyName(QLatin1String(keyName))
, m_value(proxyFunc(loadValue(defaultValue)))
explicit CachedSettingValue(const char *keyName, const T &defaultValue, ProxyFunc &&proxyFunc)
: m_setting {keyName}
, m_cache {proxyFunc(m_setting.get(defaultValue))}
{
}
T value() const
T get() const
{
return m_value;
return m_cache;
}
operator T() const
{
return value();
return get();
}
CachedSettingValue<T> &operator=(const T &newValue)
CachedSettingValue<T> &operator=(const T &value)
{
if (m_value == newValue)
if (m_cache == value)
return *this;
m_value = newValue;
storeValue(m_value);
m_setting = value;
m_cache = value;
return *this;
}
private:
// regular load/save pair
template <typename U, typename std::enable_if_t<!std::is_enum<U>::value, int> = 0>
U loadValue(const U &defaultValue)
{
return SettingsStorage::instance()->loadValue(m_keyName, defaultValue).template value<T>();
}
template <typename U, typename std::enable_if_t<!std::is_enum<U>::value, int> = 0>
void storeValue(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
template <typename U, typename std::enable_if_t<std::is_enum<U>::value, int> = 0>
U loadValue(const U &defaultValue)
{
return Utils::String::toEnum(SettingsStorage::instance()->loadValue(m_keyName).toString(), defaultValue);
}
template <typename U, typename std::enable_if_t<std::is_enum<U>::value, int> = 0>
void storeValue(const U &value)
{
SettingsStorage::instance()->storeValue(m_keyName, Utils::String::fromEnum(value));
}
const QString m_keyName;
T m_value;
SettingValue<T> m_setting;
T m_cache;
};

View File

@@ -73,7 +73,7 @@ void TorrentFileGuard::markAsAddedToSession()
TorrentFileGuard::AutoDeleteMode TorrentFileGuard::autoDeleteMode()
{
return autoDeleteModeSetting();
return autoDeleteModeSetting().get(AutoDeleteMode::Never);
}
void TorrentFileGuard::setAutoDeleteMode(TorrentFileGuard::AutoDeleteMode mode)
@@ -81,8 +81,8 @@ void TorrentFileGuard::setAutoDeleteMode(TorrentFileGuard::AutoDeleteMode mode)
autoDeleteModeSetting() = mode;
}
CachedSettingValue<TorrentFileGuard::AutoDeleteMode> &TorrentFileGuard::autoDeleteModeSetting()
SettingValue<TorrentFileGuard::AutoDeleteMode> &TorrentFileGuard::autoDeleteModeSetting()
{
static CachedSettingValue<AutoDeleteMode> setting("Core/AutoDeleteAddedTorrentFile", AutoDeleteMode::Never);
static SettingValue<AutoDeleteMode> setting {"Core/AutoDeleteAddedTorrentFile"};
return setting;
}

View File

@@ -31,7 +31,7 @@
#include <QObject>
#include <QString>
template <typename T> class CachedSettingValue;
template <typename T> class SettingValue;
/// Utility class to defer file deletion
class FileGuard
@@ -75,7 +75,7 @@ public:
private:
TorrentFileGuard(const QString &path, AutoDeleteMode mode);
static CachedSettingValue<AutoDeleteMode> &autoDeleteModeSetting();
static SettingValue<AutoDeleteMode> &autoDeleteModeSetting();
Q_ENUM(AutoDeleteMode)
AutoDeleteMode m_mode;