fix: CLI QT Issue w/ booting directly from a file

This commit is contained in:
collecting
2026-05-19 05:01:44 -04:00
parent 8138e4d5af
commit 9531249345
4 changed files with 23 additions and 77 deletions
+13 -12
View File
@@ -1166,6 +1166,9 @@ GameList::GameList(std::shared_ptr<FileSys::VfsFilesystem> vfs_,
GMainWindow* parent)
: QWidget{parent}, vfs{std::move(vfs_)}, provider{provider_},
play_time_manager{play_time_manager_}, system{system_} {
qRegisterMetaType<GameListDir*>("GameListDir*");
qRegisterMetaType<QList<QStandardItem*>>("QList<QStandardItem*>");
watcher = new QFileSystemWatcher(this);
connect(watcher, &QFileSystemWatcher::directoryChanged, this, &GameList::RefreshGameDirectory);
@@ -2192,9 +2195,6 @@ void GameList::ClearFilter() {
search_field->clear();
}
void GameList::WorkerEvent() {
current_worker->ProcessEvents(this);
}
void GameList::AddDirEntry(GameListDir* entry_items) {
if (!entry_items)
@@ -2950,9 +2950,7 @@ void GameList::DonePopulating(const QStringList& watch_list) {
QTimer::singleShot(0, this, [this]() { current_worker.reset(); });
}
for (const auto& watch_dir : watch_list) {
watcher->addPath(watch_dir);
}
emit PopulatingCompleted();
if (progress_bar) {
@@ -3004,15 +3002,13 @@ void GameList::DonePopulating(const QStringList& watch_list) {
watcher->removePaths(watch_dirs);
}
constexpr int LIMIT_WATCH_DIRECTORIES = 5000;
constexpr int SLICE_SIZE = 25;
int len = std::min(static_cast<int>(watch_list.size()), LIMIT_WATCH_DIRECTORIES);
tree_view->setEnabled(true);
tree_view->setFocus();
for (int i = 0; i < len; i += SLICE_SIZE) {
watcher->addPaths(watch_list.mid(i, i + SLICE_SIZE));
QCoreApplication::processEvents();
}
const bool old_signals_blocked = watcher->blockSignals(true);
watcher->addPaths(watch_list.mid(0, len));
watcher->blockSignals(old_signals_blocked);
int children_total = 0;
for (int i = 1; i < item_model->rowCount() - 1; ++i) {
children_total += item_model->item(i, 0)->rowCount();
@@ -3869,7 +3865,11 @@ void GameList::PopulateAsync(QVector<UISettings::GameDir>& game_dirs, bool is_sm
current_worker = std::make_unique<GameListWorker>(
vfs, provider, game_dirs, compatibility_list, play_time_manager, system,
main_window->GetMultiplayerState()->GetSession());
connect(current_worker.get(), &GameListWorker::DataAvailable, this, &GameList::WorkerEvent,
connect(current_worker.get(), &GameListWorker::DirEntryReady, this, &GameList::AddDirEntry,
Qt::QueuedConnection);
connect(current_worker.get(), &GameListWorker::EntryReady, this, &GameList::AddEntry,
Qt::QueuedConnection);
connect(current_worker.get(), &GameListWorker::Finished, this, &GameList::DonePopulating,
Qt::QueuedConnection);
if (progress_bar) {
@@ -3923,6 +3923,7 @@ void GameList::RefreshGameDirectory() {
void GameList::CancelPopulation() {
if (current_worker) {
current_worker->disconnect();
current_worker->Cancel();
}
current_worker.reset();
-1
View File
@@ -209,7 +209,6 @@ protected:
private:
friend class GameListWorker;
void WorkerEvent();
void AddDirEntry(GameListDir* entry_items);
void AddEntry(const QList<QStandardItem*>& entry_items, const QString& parent_path);
+7 -44
View File
@@ -540,41 +540,6 @@ void GameListWorker::Cancel() {
stop_requested.store(true);
}
void GameListWorker::ProcessEvents(GameList* game_list) {
while (true) {
std::function<void(GameList*)> func;
{
// Lock queue to protect concurrent modification.
std::scoped_lock lk(lock);
// If we can't pop a function, return.
if (queued_events.empty()) {
return;
}
// Pop a function.
func = std::move(queued_events.back());
queued_events.pop_back();
}
// Run the function.
func(game_list);
}
}
template <typename F>
void GameListWorker::RecordEvent(F&& func) {
{
// Lock queue to protect concurrent modification.
std::scoped_lock lk(lock);
// Add the function into the front of the queue.
queued_events.emplace_front(std::move(func));
}
// Data now available.
emit DataAvailable();
}
void GameListWorker::AddTitlesToGameList(const QString& parent_path,
const std::map<u64, std::pair<int, int>>& online_stats) {
@@ -631,7 +596,7 @@ void GameListWorker::AddTitlesToGameList(const QString& parent_path,
auto entry = MakeGameListEntry(file->GetFullPath(), name, original_name, file->GetSize(),
icon, *loader, program_id, compatibility_list,
play_time_manager, patch, online_stats);
RecordEvent([=](GameList* game_list) { game_list->AddEntry(entry, parent_path); });
emit EntryReady(entry, parent_path);
}
}
@@ -721,8 +686,7 @@ void GameListWorker::ScanFileSystem(ScanTarget target, const std::string& dir_pa
MakeGameListEntry(physical_name, name, original_name, cached->file_size,
icon, *loader, cached->program_id, compatibility_list,
play_time_manager, patch, online_stats);
RecordEvent(
[=](GameList* game_list) { game_list->AddEntry(entry, parent_path); });
emit EntryReady(entry, parent_path);
}
}
}
@@ -803,8 +767,7 @@ void GameListWorker::ScanFileSystem(ScanTarget target, const std::string& dir_pa
auto entry = MakeGameListEntry(physical_name, name, original_name, file_size,
icon, *loader, program_id, compatibility_list,
play_time_manager, patch, online_stats);
RecordEvent(
[=](GameList* game_list) { game_list->AddEntry(entry, parent_path); });
emit EntryReady(entry, parent_path);
}
}
}
@@ -876,8 +839,8 @@ void GameListWorker::run() {
if (total_files <= 0)
total_files = 1;
const auto DirEntryReady = [&](GameListDir* game_list_dir) {
RecordEvent([=](GameList* game_list) { game_list->AddDirEntry(game_list_dir); });
const auto TriggerDirEntryReady = [&](GameListDir* game_list_dir) {
emit DirEntryReady(game_list_dir);
};
for (UISettings::GameDir& game_dir : game_dirs) {
@@ -890,13 +853,13 @@ void GameListWorker::run() {
watch_list.append(QString::fromStdString(game_dir.path));
auto* const game_list_dir = new GameListDir(game_dir);
const QString dir_path_q = game_list_dir->data(GameListDir::FullPathRole).toString();
DirEntryReady(game_list_dir);
TriggerDirEntryReady(game_list_dir);
ScanFileSystem(ScanTarget::Both, game_dir.path, game_dir.deep_scan, dir_path_q,
online_stats, processed_files, total_files);
}
RecordEvent([this](GameList* game_list) { game_list->DonePopulating(watch_list); });
emit Finished(watch_list);
SaveGameMetadataCache();
processing_completed.Set();
}
+3 -20
View File
@@ -11,7 +11,6 @@
#include <string>
#include <utility> // Required for std::pair
#include <QList>
#include <QObject>
#include <QRunnable>
@@ -23,7 +22,6 @@
#include "common/thread.h"
#include "network/announce_multiplayer_session.h"
namespace Core {
class System;
}
@@ -67,24 +65,12 @@ public:
/// Request the worker to stop.
void Cancel();
public:
/**
* Synchronously processes any events queued by the worker.
*
* AddDirEntry is called on the game list for every discovered directory.
* AddEntry is called on the game list for every discovered program.
* DonePopulating is called on the game list when processing completes.
*/
void ProcessEvents(GameList* game_list);
signals:
void DataAvailable();
void DirEntryReady(GameListDir* entry_items);
void EntryReady(const QList<QStandardItem*>& entry_items, const QString& parent_path);
void Finished(const QStringList& watch_list);
void ProgressUpdated(int percent);
private:
template <typename F>
void RecordEvent(F&& func);
private:
void AddTitlesToGameList(const QString& parent_path,
const std::map<u64, std::pair<int, int>>& online_stats);
@@ -102,9 +88,6 @@ private:
QStringList watch_list;
std::mutex lock;
std::condition_variable cv;
std::deque<std::function<void(GameList*)>> queued_events;
std::atomic_bool stop_requested = false;
Common::Event processing_completed;