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.
This commit is contained in:
Chocobo1 2020-02-11 10:56:04 +08:00
parent 8b330e3ac0
commit 5de75eff05
No known key found for this signature in database
GPG Key ID: 210D9C873253A68C
9 changed files with 39 additions and 34 deletions

View File

@ -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);

View File

@ -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();

View File

@ -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");

View File

@ -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<int>(m_ratioLimit * 1000);
resumeData["qBt-seedingTimeLimit"] = m_seedingTimeLimit;
resumeData["qBt-category"] = m_category.toStdString();

View File

@ -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<Private::Profile> profile(rootProfilePath.isEmpty()
? static_cast<Private::Profile *>(new Private::DefaultProfile(configurationName))
: static_cast<Private::Profile *>(new Private::CustomProfile(rootProfilePath, configurationName)));
if (m_instance)
return;
std::unique_ptr<Private::Profile> profile(rootProfilePath.isEmpty()
? static_cast<Private::Profile *>(new Private::DefaultProfile(configurationName))
: static_cast<Private::Profile *>(new Private::CustomProfile(rootProfilePath, configurationName)));
std::unique_ptr<Private::PathConverter> converter(convertPathsToProfileRelative
? static_cast<Private::PathConverter *>(new Private::Converter(profile->baseDirectory()))
: static_cast<Private::PathConverter *>(new Private::NoConvertConverter()));
? static_cast<Private::PathConverter *>(new Private::Converter(profile->baseDirectory()))
: static_cast<Private::PathConverter *>(new Private::NoConvertConverter()));
m_instance = new Profile(profile.release(), converter.release());
}
const Profile &Profile::instance()
void Profile::freeInstance()
{
return *m_instance;
delete m_instance;
m_instance = nullptr;
}
const Profile *Profile::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);
}

View File

@ -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<Private::Profile> m_profileImpl;
const std::unique_ptr<Private::PathConverter> m_pathConverterImpl;

View File

@ -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());

View File

@ -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())) {

View File

@ -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());