Let's make the rom list process on a separate thread so the emulator doesnt take ages to load.

This commit is contained in:
2026-06-12 15:30:47 +02:00
parent fc306967f9
commit 95d202f378
2 changed files with 75 additions and 47 deletions
+52 -40
View File
@@ -11,12 +11,28 @@
#include <Options.hpp>
#include <Scheduler.hpp>
void KaizenGui::populateRomsList(const std::string &romsPath) {
centralWidget->setCurrentWidget(romPathNotSet);
if (!romsPath.empty()) {
int i = 0;
centralWidget->setCurrentWidget(romsList);
RomsListTable::RomsListTable() {
verticalHeader()->hide();
horizontalHeader()->setSectionResizeMode(QHeaderView::Interactive);
setSizePolicy({QSizePolicy::Maximum, QSizePolicy::Maximum});
setSelectionMode(QAbstractItemView::SingleSelection);
setSelectionBehavior(QAbstractItemView::SelectRows);
setEditTriggers(QAbstractItemView::NoEditTriggers);
setSortingEnabled(true);
setColumnCount(4);
setHorizontalHeaderItem(0, new QTableWidgetItem("Name"));
setHorizontalHeaderItem(1, new QTableWidgetItem("Regions"));
setHorizontalHeaderItem(2, new QTableWidgetItem("Last played"));
setHorizontalHeaderItem(3, new QTableWidgetItem("Time played"));
std::jthread([&] {
populate(Options::GetRomsPath());
emit populateFinished();
});
}
void RomsListTable::populate(const std::string &romsPath) {
if (!romsPath.empty()) {
for (const auto &file : fs::recursive_directory_iterator{romsPath}) {
if (!file.is_regular_file())
continue;
@@ -37,24 +53,12 @@ void KaizenGui::populateRomsList(const std::string &romsPath) {
auto regions = n64::GameDB::match(rom);
if (rom.gameNameDB.empty())
rom.gameNameDB = fs::path(filename).stem();
rom.gameNameDB = fs::path(filename).stem().string();
romsListPaths.push_back(filename);
romsList->insertRow(i);
romsList->setItem(
i, 0,
new QTableWidgetItem(std::format("{} ({}) (Rev {})", rom.gameNameDB,
n64::GameDB::regionCodeToReadable(rom.header.countryCode),
rom.header.version)
.c_str()));
romsList->setItem(i, 1, new QTableWidgetItem(regions.c_str()));
romsList->setItem(i, 2, new QTableWidgetItem("Never"));
romsList->setItem(i, 3, new QTableWidgetItem("0h 0m 0s"));
i++;
romsList.push_back(
{rom.header.countryCode, rom.header.version, filename, rom.gameNameDB, regions, "Never", "0h 00m 00s"});
}
}
currentHomeWidget = centralWidget->currentWidget();
}
KaizenGui::KaizenGui() noexcept : QMainWindow(nullptr), settings(QSettings::UserScope) {
@@ -63,33 +67,40 @@ KaizenGui::KaizenGui() noexcept : QMainWindow(nullptr), settings(QSettings::User
SDL_AddGamepadMapping(gamecontrollerdb_str);
hide();
romsList->verticalHeader()->hide();
romsList->setSizePolicy({QSizePolicy::Maximum, QSizePolicy::Maximum});
romsList->setSelectionMode(QAbstractItemView::SingleSelection);
romsList->setSelectionBehavior(QAbstractItemView::SelectRows);
romsList->setEditTriggers(QAbstractItemView::NoEditTriggers);
romsList->setSortingEnabled(true);
romsList->setColumnCount(4);
romsList->setHorizontalHeaderItem(0, new QTableWidgetItem("Name"));
romsList->setHorizontalHeaderItem(1, new QTableWidgetItem("Regions"));
romsList->setHorizontalHeaderItem(2, new QTableWidgetItem("Last played"));
romsList->setHorizontalHeaderItem(3, new QTableWidgetItem("Time played"));
vulkanWidget = new RenderWidget();
vulkanWidget->hide();
centralWidget->addWidget(vulkanWidget);
centralWidget->addWidget(romsList);
centralWidget->addWidget(romsListTable);
centralWidget->addWidget(romPathNotSet);
populateRomsList(Options::GetRomsPath());
connect(romsList, &QTableWidget::cellDoubleClicked, this, [&](int row, int) {
auto fileToLoad = fs::path(Options::GetRomsPath()) / romsListPaths[row];
std::println("{}", fileToLoad.string());
LoadROM(fileToLoad.string());
populateRomsListThread = QThread::create([&] {
populateRomsList(Options::GetRomsPath());
emit populateRomsListFinished();
});
populateRomsListThread->start();
connect(this, &KaizenGui::populateRomsListFinished, this, [&] {
for (int i = 0; i < romsList.size(); i++) {
const auto &[countryCode, version, _, name, regions, lastPlayed, timePlayed] = romsList[i];
romsListTable->insertRow(i);
romsListTable->setItem(
i, 0,
new QTableWidgetItem(
std::format("{} ({}) (Rev {})", name, n64::GameDB::regionCodeToReadable(countryCode), version)
.c_str()));
romsListTable->setItem(i, 1, new QTableWidgetItem(regions.c_str()));
romsListTable->setItem(i, 2, new QTableWidgetItem(lastPlayed.c_str()));
romsListTable->setItem(i, 3, new QTableWidgetItem(timePlayed.c_str()));
}
});
connect(this, &KaizenGui::romsListNeedsPopulation, this, [&] { populateRomsListThread->start(); });
connect(romsListTable, &QTableWidget::cellDoubleClicked, this, [&](int row, int) { LoadROM(romsList[row].path); });
installEventFilter(this);
restoreGeometry(settings.value("geometry").toByteArray());
@@ -112,6 +123,7 @@ KaizenGui::KaizenGui() noexcept : QMainWindow(nullptr), settings(QSettings::User
setWindowTitle("Kaizen " KAIZEN_VERSION_STR);
setMinimumSize(640, 480);
setCentralWidget(centralWidget);
centralWidget->setLayout(new QVBoxLayout());
setAcceptDrops(true);
@@ -184,7 +196,7 @@ KaizenGui::KaizenGui() noexcept : QMainWindow(nullptr), settings(QSettings::User
settingsWindow = new SettingsWindow();
connect(settingsMenu, &QAction::triggered, settingsWindow, &SettingsWindow::show);
connect(settingsWindow->general, &GeneralSettings::romFolderSelected, this,
[&] { populateRomsList(Options::GetRomsPath()); });
[&] { emit romsListNeedsPopulation(); });
connect(settingsWindow->cpu, &CPUSettings::cpuTypeChanged, this, [&] {
core.cpuType = Options::GetCpuType();
+23 -7
View File
@@ -13,17 +13,35 @@
class EmuThread;
struct RomsListEntry {
u8 countryCode, version;
std::string path;
std::string name;
std::string region;
std::string lastPlayed;
std::string timePlayed;
};
class RomsListTable : public QTableWidget {
Q_OBJECT
std::vector<RomsListEntry> romsList;
public:
RomsListTable();
public slots:
void populate(const std::string &);
signals:
void populateFinished();
};
class KaizenGui final : QMainWindow {
Q_OBJECT
void updateKeys();
void updateAxis();
bool eventFilter(QObject *, QEvent *) override;
void populateRomsList(const std::string &);
bool fastForward = false;
bool minimized = false;
std::vector<std::string> romsListPaths{};
SDL_Gamepad *gamepad = nullptr;
bool gamepadConnected;
float elapsed = 0.f;
@@ -33,12 +51,12 @@ class KaizenGui final : QMainWindow {
QWidget *currentHomeWidget;
QLabel *romPathNotSet = new QLabel(R"(Kaizen could not find any ROMs. Set the path in "Settings -> General")");
QTableWidget *romsList = new QTableWidget();
RomsListTable *romsListTable = new RomsListTable();
QStackedWidget *centralWidget = new QStackedWidget();
SettingsWindow *settingsWindow;
RenderWidget *vulkanWidget;
QSettings settings;
QThread *emuThread;
QThread *emuThread, *populateRomsListThread;
QTimer *statusBarTimer, *SDLeventsTimer;
QLabel *fpsLabel;
QLabel *cpuTypeLabel;
@@ -59,6 +77,4 @@ class KaizenGui final : QMainWindow {
void LoadTAS(const std::string &path) noexcept;
void LoadROM(const std::string &path) noexcept;
signals:
void paused();
};