From 5de75eff050695c3418c00864ea805e4968ca1fa Mon Sep 17 00:00:00 2001 From: Chocobo1 Date: Tue, 11 Feb 2020 10:56:04 +0800 Subject: [PATCH] Unify singleton pattern in Profile class 1. Use unified function names `initInstance()` and `freeInstance()` and make them public. 2. Add `freeInstance()` to avoid noise from memory leak detectors. 3. Let `instance()`return a pointer directly to avoid unnecessary indirections when invoking functions. --- src/app/application.cpp | 6 ++-- src/base/bittorrent/private/statistics.cpp | 4 +-- src/base/bittorrent/session.cpp | 2 +- src/base/bittorrent/torrenthandle.cpp | 4 +-- src/base/profile.cpp | 33 +++++++++++++--------- src/base/profile.h | 16 +++++------ src/base/rss/rss_autodownloader.cpp | 2 +- src/base/rss/rss_feed.cpp | 2 +- src/base/settingsstorage.cpp | 4 +-- 9 files changed, 39 insertions(+), 34 deletions(-) diff --git a/src/app/application.cpp b/src/app/application.cpp index 81986c4e0..d3555e840 100644 --- a/src/app/application.cpp +++ b/src/app/application.cpp @@ -149,7 +149,7 @@ Application::Application(const QString &id, int &argc, char **argv) const QString profileDir = portableModeEnabled ? QDir(QCoreApplication::applicationDirPath()).absoluteFilePath(DEFAULT_PORTABLE_MODE_PROFILE_DIR) : m_commandLineArgs.profileDir; - Profile::initialize(profileDir, m_commandLineArgs.configurationName, + Profile::initInstance(profileDir, m_commandLineArgs.configurationName, (m_commandLineArgs.relativeFastresumePaths || portableModeEnabled)); Logger::initInstance(); @@ -177,7 +177,7 @@ Application::Application(const QString &id, int &argc, char **argv) Logger::instance()->addMessage(tr("Redundant command line flag detected: \"%1\". Portable mode implies relative fastresume.").arg("--relative-fastresume"), Log::WARNING); // to avoid translating the `--relative-fastresume` string } else { - Logger::instance()->addMessage(tr("Using config directory: %1").arg(Profile::instance().location(SpecialFolder::Config))); + Logger::instance()->addMessage(tr("Using config directory: %1").arg(Profile::instance()->location(SpecialFolder::Config))); } } @@ -764,6 +764,8 @@ void Application::cleanup() } #endif // DISABLE_GUI + Profile::freeInstance(); + if (m_shutdownAct != ShutdownDialogAction::Exit) { qDebug() << "Sending computer shutdown/suspend/hibernate signal..."; Utils::Misc::shutdownComputer(m_shutdownAct); diff --git a/src/base/bittorrent/private/statistics.cpp b/src/base/bittorrent/private/statistics.cpp index b2a60b207..c16f998f9 100644 --- a/src/base/bittorrent/private/statistics.cpp +++ b/src/base/bittorrent/private/statistics.cpp @@ -90,7 +90,7 @@ void Statistics::save() const if (!m_dirty || ((now - m_lastWrite) < SAVE_INTERVAL)) return; - SettingsPtr s = Profile::instance().applicationSettings(QLatin1String("qBittorrent-data")); + SettingsPtr s = Profile::instance()->applicationSettings(QLatin1String("qBittorrent-data")); QVariantHash v; v.insert("AlltimeDL", m_alltimeDL + m_sessionDL); v.insert("AlltimeUL", m_alltimeUL + m_sessionUL); @@ -101,7 +101,7 @@ void Statistics::save() const void Statistics::load() { - const SettingsPtr s = Profile::instance().applicationSettings(QLatin1String("qBittorrent-data")); + const SettingsPtr s = Profile::instance()->applicationSettings(QLatin1String("qBittorrent-data")); const QVariantHash v = s->value("Stats/AllStats").toHash(); m_alltimeDL = v["AlltimeDL"].toULongLong(); diff --git a/src/base/bittorrent/session.cpp b/src/base/bittorrent/session.cpp index e75588270..21b85ea31 100644 --- a/src/base/bittorrent/session.cpp +++ b/src/base/bittorrent/session.cpp @@ -156,7 +156,7 @@ namespace torrentParams.restored = true; torrentParams.skipChecking = false; torrentParams.name = fromLTString(root.dict_find_string_value("qBt-name")); - torrentParams.savePath = Profile::instance().fromPortablePath( + torrentParams.savePath = Profile::instance()->fromPortablePath( Utils::Fs::toUniformPath(fromLTString(root.dict_find_string_value("qBt-savePath")))); torrentParams.disableTempPath = root.dict_find_int_value("qBt-tempPathDisabled"); torrentParams.sequential = root.dict_find_int_value("qBt-sequential"); diff --git a/src/base/bittorrent/torrenthandle.cpp b/src/base/bittorrent/torrenthandle.cpp index 442821fdf..0fd0bd6c1 100644 --- a/src/base/bittorrent/torrenthandle.cpp +++ b/src/base/bittorrent/torrenthandle.cpp @@ -1763,9 +1763,9 @@ void TorrentHandle::handleSaveResumeDataAlert(const lt::save_resume_data_alert * } else { const auto savePath = resumeData.find_key("save_path")->string(); - resumeData["save_path"] = Profile::instance().toPortablePath(QString::fromStdString(savePath)).toStdString(); + resumeData["save_path"] = Profile::instance()->toPortablePath(QString::fromStdString(savePath)).toStdString(); } - resumeData["qBt-savePath"] = m_useAutoTMM ? "" : Profile::instance().toPortablePath(m_savePath).toStdString(); + resumeData["qBt-savePath"] = m_useAutoTMM ? "" : Profile::instance()->toPortablePath(m_savePath).toStdString(); resumeData["qBt-ratioLimit"] = static_cast(m_ratioLimit * 1000); resumeData["qBt-seedingTimeLimit"] = m_seedingTimeLimit; resumeData["qBt-category"] = m_category.toStdString(); diff --git a/src/base/profile.cpp b/src/base/profile.cpp index f8261a578..44408d295 100644 --- a/src/base/profile.cpp +++ b/src/base/profile.cpp @@ -42,25 +42,30 @@ Profile::Profile(Private::Profile *impl, Private::PathConverter *pathConverter) ensureDirectoryExists(SpecialFolder::Data); } -// to generate correct call to ProfilePrivate::~ProfileImpl() -Profile::~Profile() = default; - -void Profile::initialize(const QString &rootProfilePath, const QString &configurationName, - bool convertPathsToProfileRelative) +void Profile::initInstance(const QString &rootProfilePath, const QString &configurationName, + const bool convertPathsToProfileRelative) { - std::unique_ptr profile(rootProfilePath.isEmpty() - ? static_cast(new Private::DefaultProfile(configurationName)) - : static_cast(new Private::CustomProfile(rootProfilePath, configurationName))); + if (m_instance) + return; + std::unique_ptr profile(rootProfilePath.isEmpty() + ? static_cast(new Private::DefaultProfile(configurationName)) + : static_cast(new Private::CustomProfile(rootProfilePath, configurationName))); std::unique_ptr converter(convertPathsToProfileRelative - ? static_cast(new Private::Converter(profile->baseDirectory())) - : static_cast(new Private::NoConvertConverter())); + ? static_cast(new Private::Converter(profile->baseDirectory())) + : static_cast(new Private::NoConvertConverter())); m_instance = new Profile(profile.release(), converter.release()); } -const Profile &Profile::instance() +void Profile::freeInstance() +{ + delete m_instance; + m_instance = nullptr; +} + +const Profile *Profile::instance() { - return *m_instance; + return m_instance; } QString Profile::location(const SpecialFolder folder) const @@ -96,7 +101,7 @@ SettingsPtr Profile::applicationSettings(const QString &name) const return m_profileImpl->applicationSettings(name); } -void Profile::ensureDirectoryExists(const SpecialFolder folder) +void Profile::ensureDirectoryExists(const SpecialFolder folder) const { const QString locationPath = location(folder); if (!locationPath.isEmpty() && !QDir().mkpath(locationPath)) @@ -115,5 +120,5 @@ QString Profile::fromPortablePath(const QString &portablePath) const QString specialFolderLocation(const SpecialFolder folder) { - return Profile::instance().location(folder); + return Profile::instance()->location(folder); } diff --git a/src/base/profile.h b/src/base/profile.h index 40f672fc1..6568f3eef 100644 --- a/src/base/profile.h +++ b/src/base/profile.h @@ -36,8 +36,6 @@ class QString; -class Application; - namespace Private { class Profile; @@ -57,6 +55,11 @@ enum class SpecialFolder class Profile { public: + static void initInstance(const QString &rootProfilePath, const QString &configurationName, + bool convertPathsToProfileRelative); + static void freeInstance(); + static const Profile *instance(); + QString location(SpecialFolder folder) const; SettingsPtr applicationSettings(const QString &name) const; @@ -67,16 +70,11 @@ public: QString toPortablePath(const QString &absolutePath) const; QString fromPortablePath(const QString &portablePath) const; - static const Profile &instance(); - private: Profile(Private::Profile *impl, Private::PathConverter *pathConverter); - ~Profile(); + ~Profile() = default; // to generate correct call to ProfilePrivate::~ProfileImpl() - friend class ::Application; - static void initialize(const QString &rootProfilePath, const QString &configurationName, - bool convertPathsToProfileRelative); - void ensureDirectoryExists(SpecialFolder folder); + void ensureDirectoryExists(SpecialFolder folder) const; const std::unique_ptr m_profileImpl; const std::unique_ptr m_pathConverterImpl; diff --git a/src/base/rss/rss_autodownloader.cpp b/src/base/rss/rss_autodownloader.cpp index 9e7a566f1..ffa888531 100644 --- a/src/base/rss/rss_autodownloader.cpp +++ b/src/base/rss/rss_autodownloader.cpp @@ -435,7 +435,7 @@ void AutoDownloader::loadRules(const QByteArray &data) void AutoDownloader::loadRulesLegacy() { - const SettingsPtr settings = Profile::instance().applicationSettings(QStringLiteral("qBittorrent-rss")); + const SettingsPtr settings = Profile::instance()->applicationSettings(QStringLiteral("qBittorrent-rss")); const QVariantHash rules = settings->value(QStringLiteral("download_rules")).toHash(); for (const QVariant &ruleVar : rules) { const auto rule = AutoDownloadRule::fromLegacyDict(ruleVar.toHash()); diff --git a/src/base/rss/rss_feed.cpp b/src/base/rss/rss_feed.cpp index 57a34b691..afad3d83e 100644 --- a/src/base/rss/rss_feed.cpp +++ b/src/base/rss/rss_feed.cpp @@ -299,7 +299,7 @@ void Feed::loadArticles(const QByteArray &data) void Feed::loadArticlesLegacy() { - const SettingsPtr qBTRSSFeeds = Profile::instance().applicationSettings(QStringLiteral("qBittorrent-rss-feeds")); + const SettingsPtr qBTRSSFeeds = Profile::instance()->applicationSettings(QStringLiteral("qBittorrent-rss-feeds")); const QVariantHash allOldItems = qBTRSSFeeds->value("old_items").toHash(); for (const QVariant &var : asConst(allOldItems.value(m_url).toList())) { diff --git a/src/base/settingsstorage.cpp b/src/base/settingsstorage.cpp index 618b05253..7b5b7d37e 100644 --- a/src/base/settingsstorage.cpp +++ b/src/base/settingsstorage.cpp @@ -279,7 +279,7 @@ bool TransactionalSettings::write(const QVariantHash &data) const QString TransactionalSettings::deserialize(const QString &name, QVariantHash &data) const { - SettingsPtr settings = Profile::instance().applicationSettings(name); + SettingsPtr settings = Profile::instance()->applicationSettings(name); if (settings->allKeys().isEmpty()) return {}; @@ -295,7 +295,7 @@ QString TransactionalSettings::deserialize(const QString &name, QVariantHash &da QString TransactionalSettings::serialize(const QString &name, const QVariantHash &data) const { - SettingsPtr settings = Profile::instance().applicationSettings(name); + SettingsPtr settings = Profile::instance()->applicationSettings(name); for (auto i = data.begin(); i != data.end(); ++i) settings->setValue(i.key(), i.value());