mirror of
https://github.com/RPCS3/rpcs3.git
synced 2025-07-08 16:01:42 +12:00
Load trophies in another thread
This commit is contained in:
parent
f505ac7b63
commit
bf0e6ca174
2 changed files with 105 additions and 19 deletions
|
@ -29,6 +29,7 @@
|
||||||
#include <QUrl>
|
#include <QUrl>
|
||||||
#include <QScrollBar>
|
#include <QScrollBar>
|
||||||
#include <QWheelEvent>
|
#include <QWheelEvent>
|
||||||
|
#include <QProgressDialog>
|
||||||
|
|
||||||
namespace
|
namespace
|
||||||
{
|
{
|
||||||
|
@ -321,7 +322,22 @@ trophy_manager_dialog::trophy_manager_dialog(std::shared_ptr<gui_settings> gui_s
|
||||||
m_game_combo->setCurrentText(m_game_table->item(m_game_table->selectedItems().first()->row(), GameColumns::GameName)->text());
|
m_game_combo->setCurrentText(m_game_table->item(m_game_table->selectedItems().first()->row(), GameColumns::GameName)->text());
|
||||||
});
|
});
|
||||||
|
|
||||||
RepaintUI(true);
|
RepaintUI();
|
||||||
|
|
||||||
|
StartTrophyLoadThread();
|
||||||
|
}
|
||||||
|
|
||||||
|
trophy_manager_dialog::~trophy_manager_dialog()
|
||||||
|
{
|
||||||
|
if (m_thread_state != TrophyThreadState::CLOSED)
|
||||||
|
{
|
||||||
|
TrophyThreadState expected = TrophyThreadState::RUNNING;
|
||||||
|
m_thread_state.compare_exchange_strong(expected, TrophyThreadState::CLOSING);
|
||||||
|
while (m_thread_state != TrophyThreadState::CLOSED)
|
||||||
|
{
|
||||||
|
std::this_thread::yield();
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
bool trophy_manager_dialog::LoadTrophyFolderToDB(const std::string& trop_name)
|
bool trophy_manager_dialog::LoadTrophyFolderToDB(const std::string& trop_name)
|
||||||
|
@ -395,7 +411,7 @@ bool trophy_manager_dialog::LoadTrophyFolderToDB(const std::string& trop_name)
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
void trophy_manager_dialog::RepaintUI(bool refresh_trophies)
|
void trophy_manager_dialog::RepaintUI()
|
||||||
{
|
{
|
||||||
if (m_gui_settings->GetValue(gui::m_enableUIColors).toBool())
|
if (m_gui_settings->GetValue(gui::m_enableUIColors).toBool())
|
||||||
{
|
{
|
||||||
|
@ -406,11 +422,6 @@ void trophy_manager_dialog::RepaintUI(bool refresh_trophies)
|
||||||
m_game_icon_color = gui::utils::get_label_color("gamelist_icon_background_color");
|
m_game_icon_color = gui::utils::get_label_color("gamelist_icon_background_color");
|
||||||
}
|
}
|
||||||
|
|
||||||
if (refresh_trophies)
|
|
||||||
{
|
|
||||||
PopulateTrophyDB();
|
|
||||||
}
|
|
||||||
|
|
||||||
PopulateGameTable();
|
PopulateGameTable();
|
||||||
|
|
||||||
if (!restoreGeometry(m_gui_settings->GetValue(gui::tr_geometry).toByteArray()))
|
if (!restoreGeometry(m_gui_settings->GetValue(gui::tr_geometry).toByteArray()))
|
||||||
|
@ -581,18 +592,62 @@ void trophy_manager_dialog::ShowContextMenu(const QPoint& loc)
|
||||||
menu->exec(globalPos);
|
menu->exec(globalPos);
|
||||||
}
|
}
|
||||||
|
|
||||||
void trophy_manager_dialog::PopulateTrophyDB()
|
void trophy_manager_dialog::StartTrophyLoadThread()
|
||||||
{
|
{
|
||||||
m_trophies_db.clear();
|
auto progressDialog = new QProgressDialog(
|
||||||
|
tr("Loading trophy data, please wait..."), tr("Cancel"), 0, 1, this,
|
||||||
|
Qt::Dialog | Qt::WindowTitleHint | Qt::CustomizeWindowHint);
|
||||||
|
progressDialog->setWindowTitle(tr("Loading trophies"));
|
||||||
|
connect(progressDialog, &QProgressDialog::canceled, [this]()
|
||||||
|
{
|
||||||
|
TrophyThreadState expected = TrophyThreadState::RUNNING;
|
||||||
|
m_thread_state.compare_exchange_strong(expected, TrophyThreadState::CLOSING);
|
||||||
|
this->close(); // It's pointless to show an empty window
|
||||||
|
});
|
||||||
|
progressDialog->show();
|
||||||
|
|
||||||
QDirIterator dir_iter(qstr(vfs::get(m_trophy_dir)), QDir::Dirs | QDir::NoDotAndDotDot);
|
auto trophyThread = new trophy_manager_dialog::trophy_load_thread(this);
|
||||||
while (dir_iter.hasNext())
|
connect(trophyThread, &QThread::finished, trophyThread, &QThread::deleteLater);
|
||||||
{
|
connect(trophyThread, &QThread::finished, progressDialog, &QProgressDialog::deleteLater);
|
||||||
dir_iter.next();
|
connect(trophyThread, &trophy_manager_dialog::trophy_load_thread::TotalCountChanged, progressDialog, &QProgressDialog::setMaximum);
|
||||||
std::string dirName = sstr(dir_iter.fileName());
|
connect(trophyThread, &trophy_manager_dialog::trophy_load_thread::ProcessedCountChanged, progressDialog, &QProgressDialog::setValue);
|
||||||
LOG_TRACE(GENERAL, "Loading trophy dir: %s", dirName);
|
connect(trophyThread, &trophy_manager_dialog::trophy_load_thread::FinishedSuccessfully, this, &trophy_manager_dialog::HandleRepaintUiRequest);
|
||||||
LoadTrophyFolderToDB(dirName);
|
m_thread_state = TrophyThreadState::RUNNING;
|
||||||
|
trophyThread->start();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void trophy_manager_dialog::trophy_load_thread::run()
|
||||||
|
{
|
||||||
|
m_manager->m_trophies_db.clear();
|
||||||
|
|
||||||
|
QDir trophy_dir(qstr(vfs::get(m_manager->m_trophy_dir)));
|
||||||
|
const auto folder_list = trophy_dir.entryList(QDir::Dirs | QDir::NoDotAndDotDot);
|
||||||
|
const int count = folder_list.count();
|
||||||
|
Q_EMIT TotalCountChanged(count);
|
||||||
|
|
||||||
|
for (int i = 0; m_manager->m_thread_state == TrophyThreadState::RUNNING && i < count; i++)
|
||||||
|
{
|
||||||
|
std::string dir_name = sstr(folder_list.value(i));
|
||||||
|
LOG_TRACE(GENERAL, "Loading trophy dir: %s", dir_name);
|
||||||
|
try
|
||||||
|
{
|
||||||
|
m_manager->LoadTrophyFolderToDB(dir_name);
|
||||||
|
}
|
||||||
|
catch (const std::exception& e)
|
||||||
|
{
|
||||||
|
// TODO: Add error checks & throws to LoadTrophyFolderToDB so that they can be caught here.
|
||||||
|
// Also add a way of showing the number of corrupted/invalid folders in UI somewhere.
|
||||||
|
LOG_ERROR(GENERAL, "Exception occurred while parsing folder %s for trophies: %s", dir_name, e.what());
|
||||||
|
}
|
||||||
|
Q_EMIT ProcessedCountChanged(i + 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (m_manager->m_thread_state == TrophyThreadState::RUNNING)
|
||||||
|
{
|
||||||
|
Q_EMIT FinishedSuccessfully();
|
||||||
|
}
|
||||||
|
|
||||||
|
m_manager->m_thread_state = TrophyThreadState::CLOSED;
|
||||||
}
|
}
|
||||||
|
|
||||||
void trophy_manager_dialog::PopulateGameTable()
|
void trophy_manager_dialog::PopulateGameTable()
|
||||||
|
|
|
@ -13,6 +13,7 @@
|
||||||
#include <QTableWidget>
|
#include <QTableWidget>
|
||||||
#include <QSlider>
|
#include <QSlider>
|
||||||
#include <QSplitter>
|
#include <QSplitter>
|
||||||
|
#include <QThread>
|
||||||
|
|
||||||
struct GameTrophiesData
|
struct GameTrophiesData
|
||||||
{
|
{
|
||||||
|
@ -44,8 +45,17 @@ enum GameColumns
|
||||||
GameColumnsCount
|
GameColumnsCount
|
||||||
};
|
};
|
||||||
|
|
||||||
|
enum TrophyThreadState
|
||||||
|
{
|
||||||
|
RUNNING,
|
||||||
|
CLOSING,
|
||||||
|
CLOSED
|
||||||
|
};
|
||||||
|
|
||||||
class trophy_manager_dialog : public QWidget
|
class trophy_manager_dialog : public QWidget
|
||||||
{
|
{
|
||||||
|
Q_OBJECT
|
||||||
|
|
||||||
const QString Bronze = "Bronze";
|
const QString Bronze = "Bronze";
|
||||||
const QString Silver = "Silver";
|
const QString Silver = "Silver";
|
||||||
const QString Gold = "Gold";
|
const QString Gold = "Gold";
|
||||||
|
@ -53,7 +63,8 @@ class trophy_manager_dialog : public QWidget
|
||||||
|
|
||||||
public:
|
public:
|
||||||
explicit trophy_manager_dialog(std::shared_ptr<gui_settings> gui_settings);
|
explicit trophy_manager_dialog(std::shared_ptr<gui_settings> gui_settings);
|
||||||
void RepaintUI(bool refresh_trophies = false);
|
~trophy_manager_dialog() override;
|
||||||
|
void RepaintUI();
|
||||||
|
|
||||||
public Q_SLOTS:
|
public Q_SLOTS:
|
||||||
void HandleRepaintUiRequest();
|
void HandleRepaintUiRequest();
|
||||||
|
@ -71,8 +82,8 @@ private:
|
||||||
*/
|
*/
|
||||||
bool LoadTrophyFolderToDB(const std::string& trop_name);
|
bool LoadTrophyFolderToDB(const std::string& trop_name);
|
||||||
|
|
||||||
/** Populate the trophy database */
|
/** Populate the trophy database (in another thread). */
|
||||||
void PopulateTrophyDB();
|
void StartTrophyLoadThread();
|
||||||
|
|
||||||
/** Fills game table with information.
|
/** Fills game table with information.
|
||||||
Takes results from LoadTrophyFolderToDB and puts it into the UI.
|
Takes results from LoadTrophyFolderToDB and puts it into the UI.
|
||||||
|
@ -99,6 +110,9 @@ private:
|
||||||
QTableWidget* m_trophy_table; //! UI element to display trophy stuff.
|
QTableWidget* m_trophy_table; //! UI element to display trophy stuff.
|
||||||
QTableWidget* m_game_table; //! UI element to display games.
|
QTableWidget* m_game_table; //! UI element to display games.
|
||||||
|
|
||||||
|
class trophy_load_thread; //Qt cannot parse nested classes, declaration is below
|
||||||
|
std::atomic<TrophyThreadState> m_thread_state = TrophyThreadState::CLOSED;
|
||||||
|
|
||||||
bool m_show_hidden_trophies = false;
|
bool m_show_hidden_trophies = false;
|
||||||
bool m_show_unlocked_trophies = true;
|
bool m_show_unlocked_trophies = true;
|
||||||
bool m_show_locked_trophies = true;
|
bool m_show_locked_trophies = true;
|
||||||
|
@ -118,3 +132,20 @@ private:
|
||||||
QSlider* m_game_icon_slider = nullptr;
|
QSlider* m_game_icon_slider = nullptr;
|
||||||
QColor m_game_icon_color;
|
QColor m_game_icon_color;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
class trophy_manager_dialog::trophy_load_thread : public QThread
|
||||||
|
{
|
||||||
|
Q_OBJECT
|
||||||
|
|
||||||
|
public:
|
||||||
|
explicit trophy_load_thread(trophy_manager_dialog *manager) : m_manager(manager) {}
|
||||||
|
void run() override;
|
||||||
|
|
||||||
|
Q_SIGNALS:
|
||||||
|
void TotalCountChanged(int count);
|
||||||
|
void ProcessedCountChanged(int processed);
|
||||||
|
void FinishedSuccessfully();
|
||||||
|
|
||||||
|
private:
|
||||||
|
trophy_manager_dialog *m_manager;
|
||||||
|
};
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue