diff --git a/src/base/bittorrent/session.cpp b/src/base/bittorrent/session.cpp index dec17fafc..ec8eda4f2 100644 --- a/src/base/bittorrent/session.cpp +++ b/src/base/bittorrent/session.cpp @@ -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(m_maxRatioAction.value()); + return static_cast(m_maxRatioAction.get()); } void Session::setMaxRatioAction(const MaxRatioAction act) diff --git a/src/base/settingvalue.h b/src/base/settingvalue.h index e03823755..94a82b21e 100644 --- a/src/base/settingvalue.h +++ b/src/base/settingvalue.h @@ -30,80 +30,110 @@ #include -#include #include #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 -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 - 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 &operator=(const T &newValue) + SettingValue &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 ::value, int> = 0> - U loadValue(const U &defaultValue) + U load(const U &defaultValue) const { - return SettingsStorage::instance()->loadValue(m_keyName, defaultValue).template value(); + return SettingsStorage::instance()->loadValue(m_keyName, defaultValue) + .template value(); } template ::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 ::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 ::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 +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 + 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 &operator=(const T &value) + { + if (m_cache == value) + return *this; + + m_setting = value; + m_cache = value; + return *this; + } + +private: + SettingValue m_setting; + T m_cache; }; diff --git a/src/base/torrentfileguard.cpp b/src/base/torrentfileguard.cpp index 736123b6d..1cb908f0f 100644 --- a/src/base/torrentfileguard.cpp +++ b/src/base/torrentfileguard.cpp @@ -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::autoDeleteModeSetting() +SettingValue &TorrentFileGuard::autoDeleteModeSetting() { - static CachedSettingValue setting("Core/AutoDeleteAddedTorrentFile", AutoDeleteMode::Never); + static SettingValue setting {"Core/AutoDeleteAddedTorrentFile"}; return setting; } diff --git a/src/base/torrentfileguard.h b/src/base/torrentfileguard.h index f378a01c0..da389b86a 100644 --- a/src/base/torrentfileguard.h +++ b/src/base/torrentfileguard.h @@ -31,7 +31,7 @@ #include #include -template class CachedSettingValue; +template class SettingValue; /// Utility class to defer file deletion class FileGuard @@ -75,7 +75,7 @@ public: private: TorrentFileGuard(const QString &path, AutoDeleteMode mode); - static CachedSettingValue &autoDeleteModeSetting(); + static SettingValue &autoDeleteModeSetting(); Q_ENUM(AutoDeleteMode) AutoDeleteMode m_mode; diff --git a/src/gui/addnewtorrentdialog.h b/src/gui/addnewtorrentdialog.h index 81ba949da..f68800a9e 100644 --- a/src/gui/addnewtorrentdialog.h +++ b/src/gui/addnewtorrentdialog.h @@ -118,6 +118,6 @@ private: std::unique_ptr m_torrentGuard; BitTorrent::AddTorrentParams m_torrentParams; - CachedSettingValue m_storeDialogSize; - CachedSettingValue m_storeSplitterState; + SettingValue m_storeDialogSize; + SettingValue m_storeSplitterState; }; diff --git a/src/gui/previewselectdialog.cpp b/src/gui/previewselectdialog.cpp index 7f467971c..7768c6500 100644 --- a/src/gui/previewselectdialog.cpp +++ b/src/gui/previewselectdialog.cpp @@ -159,7 +159,7 @@ void PreviewSelectDialog::loadWindowState() Utils::Gui::resize(this, m_storeDialogSize); // Restore TreeView Header state - if (!m_storeTreeHeaderState.value().isEmpty()) + if (!m_storeTreeHeaderState.get().isEmpty()) { m_headerStateInitialized = m_ui->previewList->header()->restoreState(m_storeTreeHeaderState); } diff --git a/src/gui/previewselectdialog.h b/src/gui/previewselectdialog.h index 08be86dc7..34376fc69 100644 --- a/src/gui/previewselectdialog.h +++ b/src/gui/previewselectdialog.h @@ -82,6 +82,6 @@ private: bool m_headerStateInitialized = false; // Settings - CachedSettingValue m_storeDialogSize; - CachedSettingValue m_storeTreeHeaderState; + SettingValue m_storeDialogSize; + SettingValue m_storeTreeHeaderState; }; diff --git a/src/gui/search/searchjobwidget.cpp b/src/gui/search/searchjobwidget.cpp index e469dd9a1..76111d894 100644 --- a/src/gui/search/searchjobwidget.cpp +++ b/src/gui/search/searchjobwidget.cpp @@ -358,7 +358,7 @@ void SearchJobWidget::fillFilterComboBoxes() m_ui->filterMode->addItem(tr("Torrent names only"), static_cast(NameFilteringMode::OnlyNames)); m_ui->filterMode->addItem(tr("Everywhere"), static_cast(NameFilteringMode::Everywhere)); - QVariant selectedMode = static_cast(nameFilteringModeSetting().value()); + QVariant selectedMode = static_cast(nameFilteringModeSetting().get(NameFilteringMode::OnlyNames)); int index = m_ui->filterMode->findData(selectedMode); m_ui->filterMode->setCurrentIndex((index == -1) ? 0 : index); } @@ -545,9 +545,9 @@ void SearchJobWidget::appendSearchResults(const QVector &results) updateResultsCount(); } -CachedSettingValue &SearchJobWidget::nameFilteringModeSetting() +SettingValue &SearchJobWidget::nameFilteringModeSetting() { - static CachedSettingValue setting("Search/FilteringMode", NameFilteringMode::OnlyNames); + static SettingValue setting {"Search/FilteringMode"}; return setting; } diff --git a/src/gui/search/searchjobwidget.h b/src/gui/search/searchjobwidget.h index d51806faf..ab8ea6ab7 100644 --- a/src/gui/search/searchjobwidget.h +++ b/src/gui/search/searchjobwidget.h @@ -43,7 +43,7 @@ class SearchHandler; class SearchSortModel; struct SearchResult; -template class CachedSettingValue; +template class SettingValue; namespace Ui { @@ -117,7 +117,7 @@ private: void copyField(int column) const; static QString statusText(Status st); - static CachedSettingValue &nameFilteringModeSetting(); + static SettingValue &nameFilteringModeSetting(); Ui::SearchJobWidget *m_ui; SearchHandler *m_searchHandler; diff --git a/src/gui/torrentcreatordialog.cpp b/src/gui/torrentcreatordialog.cpp index e7d67ceb0..120c67dc1 100644 --- a/src/gui/torrentcreatordialog.cpp +++ b/src/gui/torrentcreatordialog.cpp @@ -54,16 +54,16 @@ TorrentCreatorDialog::TorrentCreatorDialog(QWidget *parent, const QString &defau , m_storeStartSeeding(SETTINGS_KEY("StartSeeding")) , m_storeIgnoreRatio(SETTINGS_KEY("IgnoreRatio")) #if (LIBTORRENT_VERSION_NUM >= 20000) - , m_storeTorrentFormat(SETTINGS_KEY("TorrentFormat"), 1) + , m_storeTorrentFormat(SETTINGS_KEY("TorrentFormat")) #else - , m_storeOptimizeAlignment(SETTINGS_KEY("OptimizeAlignment"), true) - , m_paddedFileSizeLimit(SETTINGS_KEY("PaddedFileSizeLimit"), -1) + , m_storeOptimizeAlignment(SETTINGS_KEY("OptimizeAlignment")) + , m_paddedFileSizeLimit(SETTINGS_KEY("PaddedFileSizeLimit")) #endif - , m_storeLastAddPath(SETTINGS_KEY("LastAddPath"), QDir::homePath()) + , m_storeLastAddPath(SETTINGS_KEY("LastAddPath")) , m_storeTrackerList(SETTINGS_KEY("TrackerList")) , m_storeWebSeedList(SETTINGS_KEY("WebSeedList")) , m_storeComments(SETTINGS_KEY("Comments")) - , m_storeLastSavePath(SETTINGS_KEY("LastSavePath"), QDir::homePath()) + , m_storeLastSavePath(SETTINGS_KEY("LastSavePath")) , m_storeSource(SETTINGS_KEY("Source")) { m_ui->setupUi(this); @@ -184,7 +184,7 @@ void TorrentCreatorDialog::onCreateButtonClicked() input = fi.canonicalFilePath(); // get save path - const QString savePath = QString(m_storeLastSavePath) + QLatin1Char('/') + fi.fileName() + QLatin1String(".torrent"); + const QString savePath = m_storeLastSavePath.get(QDir::homePath()) + QLatin1Char('/') + fi.fileName() + QLatin1String(".torrent"); QString destination = QFileDialog::getSaveFileName(this, tr("Select where to save the new torrent"), savePath, tr("Torrent Files (*.torrent)")); if (destination.isEmpty()) return; @@ -324,7 +324,7 @@ void TorrentCreatorDialog::saveSettings() void TorrentCreatorDialog::loadSettings() { - m_ui->textInputPath->setText(m_storeLastAddPath); + m_ui->textInputPath->setText(m_storeLastAddPath.get(QDir::homePath())); m_ui->comboPieceSize->setCurrentIndex(m_storePieceSize); m_ui->checkPrivate->setChecked(m_storePrivateTorrent); @@ -332,10 +332,10 @@ void TorrentCreatorDialog::loadSettings() m_ui->checkIgnoreShareLimits->setChecked(m_storeIgnoreRatio); m_ui->checkIgnoreShareLimits->setEnabled(m_ui->checkStartSeeding->isChecked()); #if (LIBTORRENT_VERSION_NUM >= 20000) - m_ui->comboTorrentFormat->setCurrentIndex(m_storeTorrentFormat); + m_ui->comboTorrentFormat->setCurrentIndex(m_storeTorrentFormat.get(1)); #else - m_ui->checkOptimizeAlignment->setChecked(m_storeOptimizeAlignment); - m_ui->spinPaddedFileSizeLimit->setValue(m_paddedFileSizeLimit); + m_ui->checkOptimizeAlignment->setChecked(m_storeOptimizeAlignment.get(true)); + m_ui->spinPaddedFileSizeLimit->setValue(m_paddedFileSizeLimit.get(-1)); #endif m_ui->trackersList->setPlainText(m_storeTrackerList); diff --git a/src/gui/torrentcreatordialog.h b/src/gui/torrentcreatordialog.h index 25a0de3ea..1c0c67195 100644 --- a/src/gui/torrentcreatordialog.h +++ b/src/gui/torrentcreatordialog.h @@ -78,21 +78,21 @@ private: BitTorrent::TorrentCreatorThread *m_creatorThread; // settings - CachedSettingValue m_storeDialogSize; - CachedSettingValue m_storePieceSize; - CachedSettingValue m_storePrivateTorrent; - CachedSettingValue m_storeStartSeeding; - CachedSettingValue m_storeIgnoreRatio; + SettingValue m_storeDialogSize; + SettingValue m_storePieceSize; + SettingValue m_storePrivateTorrent; + SettingValue m_storeStartSeeding; + SettingValue m_storeIgnoreRatio; #if (LIBTORRENT_VERSION_NUM >= 20000) - CachedSettingValue m_storeTorrentFormat; + SettingValue m_storeTorrentFormat; #else - CachedSettingValue m_storeOptimizeAlignment; - CachedSettingValue m_paddedFileSizeLimit; + SettingValue m_storeOptimizeAlignment; + SettingValue m_paddedFileSizeLimit; #endif - CachedSettingValue m_storeLastAddPath; - CachedSettingValue m_storeTrackerList; - CachedSettingValue m_storeWebSeedList; - CachedSettingValue m_storeComments; - CachedSettingValue m_storeLastSavePath; - CachedSettingValue m_storeSource; + SettingValue m_storeLastAddPath; + SettingValue m_storeTrackerList; + SettingValue m_storeWebSeedList; + SettingValue m_storeComments; + SettingValue m_storeLastSavePath; + SettingValue m_storeSource; }; diff --git a/src/gui/trackerentriesdialog.h b/src/gui/trackerentriesdialog.h index 53d4dfe82..4f67dd081 100644 --- a/src/gui/trackerentriesdialog.h +++ b/src/gui/trackerentriesdialog.h @@ -60,5 +60,5 @@ private: void loadSettings(); Ui::TrackerEntriesDialog *m_ui; - CachedSettingValue m_storeDialogSize; + SettingValue m_storeDialogSize; };