Qt: fix memory leak in confg_database

This commit is contained in:
Megamouse 2026-04-27 21:14:32 +02:00
parent 6d058586c4
commit b14c76c1c5
11 changed files with 51 additions and 62 deletions

View File

@ -2,7 +2,6 @@
#include "main_application.h"
#include "display_sleep_control.h"
#include "gamemode_control.h"
#include "rpcs3qt/gui_settings.h"
#include "rpcs3qt/config_database.h"
#include "util/types.hpp"
@ -418,8 +417,7 @@ EmuCallbacks main_application::CreateCallbacks()
sys_log.notice("Trying to retrieve database config for: '%s'", title_id);
const auto settings = std::make_shared<gui_settings>();
config_database config_db(settings, nullptr);
config_database config_db(nullptr);
config_db.request_config_database(false);
if (!config_db.has_config(title_id))

View File

@ -6,17 +6,19 @@
LOG_CHANNEL(gui_log, "GUI");
config_database::config_database(std::shared_ptr<gui_settings> settings, QWidget* parent)
config_database::config_database(QWidget* parent)
: QObject(parent)
, m_gui_settings(std::move(settings))
{
m_filepath = m_gui_settings->GetSettingsDir() + "/config_database.dat";
m_downloader = new downloader(parent);
m_filepath = gui_settings::GetSettingsDir() + "config_database.dat";
request_config_database();
connect(m_downloader, &downloader::signal_download_error, this, &config_database::handle_download_error);
connect(m_downloader, &downloader::signal_download_finished, this, &config_database::handle_download_finished);
connect(m_downloader, &downloader::signal_download_canceled, this, &config_database::handle_download_canceled);
if (parent)
{
m_downloader = new downloader(parent);
connect(m_downloader, &downloader::signal_download_error, this, &config_database::handle_download_error);
connect(m_downloader, &downloader::signal_download_finished, this, &config_database::handle_download_finished);
connect(m_downloader, &downloader::signal_download_canceled, this, &config_database::handle_download_canceled);
}
}
config_database::~config_database()
@ -89,7 +91,7 @@ void config_database::request_config_database(bool online)
const std::string url = "https://api.rpcs3.net/config/?api=v1";
gui_log.notice("Beginning config database download from: %s", url);
m_downloader->start(url, true, true, true, tr("Downloading Config Database"));
ensure(m_downloader)->start(url, true, true, true, tr("Downloading Config Database"));
Q_EMIT download_started();
}

View File

@ -4,14 +4,13 @@
#include <optional>
class downloader;
class gui_settings;
class config_database : public QObject
{
Q_OBJECT
public:
config_database(std::shared_ptr<gui_settings> settings, QWidget* parent);
config_database(QWidget* parent);
virtual ~config_database();
bool has_config(const std::string& title_id) const;
@ -35,7 +34,6 @@ private:
/** Creates new set from the database. Returns config for the optional serial. */
std::optional<std::string> read_json(const QByteArray& data, bool after_download, const std::string& serial = "");
std::shared_ptr<gui_settings> m_gui_settings;
QString m_filepath;
downloader* m_downloader = nullptr;

View File

@ -13,17 +13,19 @@
LOG_CHANNEL(compat_log, "Compat");
game_compatibility::game_compatibility(std::shared_ptr<gui_settings> settings, QWidget* parent)
game_compatibility::game_compatibility(QWidget* parent)
: QObject(parent)
, m_gui_settings(std::move(settings))
{
m_filepath = m_gui_settings->GetSettingsDir() + "/compat_database.dat";
m_downloader = new downloader(parent);
m_filepath = gui_settings::GetSettingsDir() + "compat_database.dat";
RequestCompatibility();
connect(m_downloader, &downloader::signal_download_error, this, &game_compatibility::handle_download_error);
connect(m_downloader, &downloader::signal_download_finished, this, &game_compatibility::handle_download_finished);
connect(m_downloader, &downloader::signal_download_canceled, this, &game_compatibility::handle_download_canceled);
if (parent)
{
m_downloader = new downloader(parent);
connect(m_downloader, &downloader::signal_download_error, this, &game_compatibility::handle_download_error);
connect(m_downloader, &downloader::signal_download_finished, this, &game_compatibility::handle_download_finished);
connect(m_downloader, &downloader::signal_download_canceled, this, &game_compatibility::handle_download_canceled);
}
}
void game_compatibility::handle_download_error(const QString& error)
@ -227,7 +229,7 @@ void game_compatibility::RequestCompatibility(bool online)
const std::string url = "https://rpcs3.net/compatibility?api=v1&export";
compat_log.notice("Beginning compatibility database download from: %s", url);
m_downloader->start(url, true, true, true, tr("Downloading Database"));
ensure(m_downloader)->start(url, true, true, true, tr("Downloading Database"));
// We want to retrieve a new database, therefore refresh game list and indicate that
Q_EMIT DownloadStarted();

View File

@ -7,7 +7,6 @@
#include <QJsonObject>
class downloader;
class gui_settings;
namespace compat
{
@ -120,29 +119,9 @@ class game_compatibility : public QObject
{
Q_OBJECT
private:
const std::map<QString, compat::status> Status_Data =
{
{ "Playable", { 0, "", "#1ebc61", tr("Playable"), tr("Games that can be properly played from start to finish") } },
{ "Ingame", { 1, "", "#f9b32f", tr("Ingame"), tr("Games that either can't be finished, have serious glitches or have insufficient performance") } },
{ "Intro", { 2, "", "#e08a1e", tr("Intro"), tr("Games that display image but don't make it past the menus") } },
{ "Loadable", { 3, "", "#e74c3c", tr("Loadable"), tr("Games that display a black screen with a framerate on the window's title") } },
{ "Nothing", { 4, "", "#455556", tr("Nothing"), tr("Games that don't initialize properly, not loading at all and/or crashing the emulator") } },
{ "NoResult", { 5, "", "", tr("No results found"), tr("There is no entry for this game or application in the compatibility database yet.") } },
{ "NoData", { 6, "", "", tr("Database missing"), tr("Right click here and download the current database.\nMake sure you are connected to the internet.") } },
{ "Download", { 7, "", "", tr("Retrieving..."), tr("Downloading the compatibility database. Please wait...") } }
};
std::shared_ptr<gui_settings> m_gui_settings;
QString m_filepath;
downloader* m_downloader = nullptr;
std::map<std::string, compat::status> m_compat_database;
/** Creates new map from the database */
bool handle_json(const QByteArray& data, bool after_download);
public:
/** Handles reads, writes and downloads for the compatibility database */
game_compatibility(std::shared_ptr<gui_settings> settings, QWidget* parent);
game_compatibility(QWidget* parent);
/** Reads database. If online set to true: Downloads and writes the database to file */
void RequestCompatibility(bool online = false);
@ -166,4 +145,23 @@ private Q_SLOTS:
void handle_download_error(const QString& error);
void handle_download_finished(const QByteArray& content);
void handle_download_canceled();
private:
/** Creates new map from the database */
bool handle_json(const QByteArray& data, bool after_download);
const std::map<QString, compat::status> Status_Data =
{
{ "Playable", { 0, "", "#1ebc61", tr("Playable"), tr("Games that can be properly played from start to finish") } },
{ "Ingame", { 1, "", "#f9b32f", tr("Ingame"), tr("Games that either can't be finished, have serious glitches or have insufficient performance") } },
{ "Intro", { 2, "", "#e08a1e", tr("Intro"), tr("Games that display image but don't make it past the menus") } },
{ "Loadable", { 3, "", "#e74c3c", tr("Loadable"), tr("Games that display a black screen with a framerate on the window's title") } },
{ "Nothing", { 4, "", "#455556", tr("Nothing"), tr("Games that don't initialize properly, not loading at all and/or crashing the emulator") } },
{ "NoResult", { 5, "", "", tr("No results found"), tr("There is no entry for this game or application in the compatibility database yet.") } },
{ "NoData", { 6, "", "", tr("Database missing"), tr("Right click here and download the current database.\nMake sure you are connected to the internet.") } },
{ "Download", { 7, "", "", tr("Retrieving..."), tr("Downloading the compatibility database. Please wait...") } }
};
QString m_filepath;
downloader* m_downloader = nullptr;
std::map<std::string, compat::status> m_compat_database;
};

View File

@ -75,8 +75,8 @@ game_list_frame::game_list_frame(std::shared_ptr<gui_settings> gui_settings, std
m_game_list->verticalScrollBar()->installEventFilter(this);
m_iso_integrity = new iso_integrity(this);
m_game_compat = new game_compatibility(m_gui_settings, this);
m_config_db = new config_database(m_gui_settings, this);
m_game_compat = new game_compatibility(this);
m_config_db = new config_database(this);
m_central_widget = new QStackedWidget(this);
m_central_widget->addWidget(m_game_list);

View File

@ -106,7 +106,7 @@ namespace gui
gui_settings::gui_settings(QObject* parent) : settings(parent)
{
m_settings = std::make_unique<QSettings>(ComputeSettingsDir() + gui::Settings + ".ini", QSettings::Format::IniFormat, parent);
m_settings = std::make_unique<QSettings>(GetSettingsDir() + gui::Settings + ".ini", QSettings::Format::IniFormat, parent);
}
QStringList gui_settings::GetGameListCategoryFilters(bool is_list_mode) const
@ -307,7 +307,7 @@ QColor gui_settings::GetCustomColor(int col) const
QStringList gui_settings::GetStylesheetEntries() const
{
const QStringList name_filter = QStringList("*.qss");
QStringList res = gui::utils::get_dir_entries(m_settings_dir, name_filter);
QStringList res = gui::utils::get_dir_entries(QDir(GetSettingsDir()), name_filter);
#if !defined(_WIN32)
// Makes stylesheets load if using AppImage (App Bundle) or installed to /usr/bin
#ifdef __APPLE__

View File

@ -8,7 +8,7 @@ LOG_CHANNEL(cfg_log, "CFG");
persistent_settings::persistent_settings(QObject* parent) : settings(parent)
{
// Don't use the .ini file ending for now, as it will be confused for a regular gui_settings file.
m_settings = std::make_unique<QSettings>(ComputeSettingsDir() + gui::persistent::persistent_file_name + ".dat", QSettings::Format::IniFormat, parent);
m_settings = std::make_unique<QSettings>(GetSettingsDir() + gui::persistent::persistent_file_name + ".dat", QSettings::Format::IniFormat, parent);
}
void persistent_settings::SetPlaytime(const QString& serial, quint64 playtime, bool sync)

View File

@ -166,7 +166,7 @@ namespace gui
QStringList get_dir_entries(const QDir& dir, const QStringList& name_filters, bool full_path)
{
QFileInfoList entries = dir.entryInfoList(name_filters, QDir::Files);
const QFileInfoList entries = dir.entryInfoList(name_filters, QDir::Files);
QStringList res;
for (const QFileInfo& entry : entries)
{

View File

@ -2,8 +2,7 @@
#include "Utilities/File.h"
settings::settings(QObject* parent) : QObject(parent),
m_settings_dir(ComputeSettingsDir())
settings::settings(QObject* parent) : QObject(parent)
{
}
@ -20,12 +19,7 @@ void settings::sync()
}
}
QString settings::GetSettingsDir() const
{
return m_settings_dir.absolutePath();
}
QString settings::ComputeSettingsDir()
QString settings::GetSettingsDir()
{
return QString::fromStdString(fs::get_config_dir()) + "/GuiConfigs/";
}

View File

@ -31,7 +31,7 @@ public:
void sync();
QString GetSettingsDir() const;
static QString GetSettingsDir();
QVariant GetValue(const QString& key, const QString& name, const QVariant& def) const;
QVariant GetValue(const gui_save& entry) const;
@ -49,8 +49,5 @@ public Q_SLOTS:
void SetValue(const QString& key, const QString& name, const QVariant& value, bool sync = true) const;
protected:
static QString ComputeSettingsDir();
std::unique_ptr<QSettings> m_settings;
QDir m_settings_dir;
};