mirror of
https://github.com/wheremyfoodat/Panda3DS.git
synced 2025-04-17 19:21:30 +12:00
Use mutex for synchronizing the UI with the emulator thread
This commit is contained in:
parent
ab2ff18290
commit
6ae8d084b4
2 changed files with 41 additions and 14 deletions
|
@ -6,8 +6,9 @@
|
||||||
#include <QPalette>
|
#include <QPalette>
|
||||||
#include <QtWidgets>
|
#include <QtWidgets>
|
||||||
#include <atomic>
|
#include <atomic>
|
||||||
#include <thread>
|
|
||||||
#include <filesystem>
|
#include <filesystem>
|
||||||
|
#include <thread>
|
||||||
|
#include <mutex>
|
||||||
|
|
||||||
#include "emulator.hpp"
|
#include "emulator.hpp"
|
||||||
#include "panda_qt/screen.hpp"
|
#include "panda_qt/screen.hpp"
|
||||||
|
@ -27,9 +28,11 @@ class MainWindow : public QMainWindow {
|
||||||
std::thread emuThread;
|
std::thread emuThread;
|
||||||
|
|
||||||
std::atomic<bool> appRunning = true; // Is the application itself running?
|
std::atomic<bool> appRunning = true; // Is the application itself running?
|
||||||
std::atomic<bool> needToLoadROM = false;
|
std::mutex messageQueueMutex; // Used for synchronizing messages between the emulator and UI
|
||||||
std::filesystem::path romToLoad = "";
|
std::filesystem::path romToLoad = "";
|
||||||
|
|
||||||
|
bool needToLoadROM = false;
|
||||||
|
|
||||||
ScreenWidget screen;
|
ScreenWidget screen;
|
||||||
QComboBox* themeSelect = nullptr;
|
QComboBox* themeSelect = nullptr;
|
||||||
QMenuBar* menuBar = nullptr;
|
QMenuBar* menuBar = nullptr;
|
||||||
|
|
|
@ -70,13 +70,17 @@ MainWindow::MainWindow(QApplication* app, QWidget* parent) : QMainWindow(parent)
|
||||||
|
|
||||||
void MainWindow::emuThreadMainLoop() {
|
void MainWindow::emuThreadMainLoop() {
|
||||||
while (appRunning) {
|
while (appRunning) {
|
||||||
if (needToLoadROM.load()) {
|
{
|
||||||
bool success = emu->loadROM(romToLoad);
|
std::unique_lock lock(messageQueueMutex);
|
||||||
if (!success) {
|
|
||||||
printf("Failed to load ROM");
|
|
||||||
}
|
|
||||||
|
|
||||||
needToLoadROM.store(false, std::memory_order::seq_cst);
|
if (needToLoadROM) {
|
||||||
|
needToLoadROM = false;
|
||||||
|
|
||||||
|
bool success = emu->loadROM(romToLoad);
|
||||||
|
if (!success) {
|
||||||
|
printf("Failed to load ROM");
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
emu->runFrame();
|
emu->runFrame();
|
||||||
|
@ -99,17 +103,22 @@ void MainWindow::swapEmuBuffer() {
|
||||||
|
|
||||||
void MainWindow::selectROM() {
|
void MainWindow::selectROM() {
|
||||||
// Are we already waiting for a ROM to be loaded? Then complain about it!
|
// Are we already waiting for a ROM to be loaded? Then complain about it!
|
||||||
if (needToLoadROM.load()) {
|
{
|
||||||
QMessageBox::warning(this, tr("Already loading ROM"), tr("Panda3DS is already busy loading a ROM, please wait"));
|
std::unique_lock lock(messageQueueMutex);
|
||||||
return;
|
if (needToLoadROM) {
|
||||||
|
QMessageBox::warning(this, tr("Already loading ROM"), tr("Panda3DS is already busy loading a ROM, please wait"));
|
||||||
|
return;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
auto path =
|
auto path =
|
||||||
QFileDialog::getOpenFileName(this, tr("Select 3DS ROM to load"), "", tr("Nintendo 3DS ROMs (*.3ds *.cci *.cxi *.app *.3dsx *.elf *.axf)"));
|
QFileDialog::getOpenFileName(this, tr("Select 3DS ROM to load"), "", tr("Nintendo 3DS ROMs (*.3ds *.cci *.cxi *.app *.3dsx *.elf *.axf)"));
|
||||||
|
|
||||||
if (!path.isEmpty()) {
|
if (!path.isEmpty()) {
|
||||||
|
std::unique_lock lock(messageQueueMutex);
|
||||||
|
|
||||||
romToLoad = path.toStdU16String();
|
romToLoad = path.toStdU16String();
|
||||||
needToLoadROM.store(true, std::memory_order_seq_cst);
|
needToLoadROM = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -184,7 +193,6 @@ void MainWindow::setTheme(Theme theme) {
|
||||||
}
|
}
|
||||||
|
|
||||||
void MainWindow::dumpRomFS() {
|
void MainWindow::dumpRomFS() {
|
||||||
// TODO: LOCK FILE MUTEX HERE
|
|
||||||
auto folder = QFileDialog::getExistingDirectory(
|
auto folder = QFileDialog::getExistingDirectory(
|
||||||
this, tr("Select folder to dump RomFS files to"), "", QFileDialog::ShowDirsOnly | QFileDialog::DontResolveSymlinks
|
this, tr("Select folder to dump RomFS files to"), "", QFileDialog::ShowDirsOnly | QFileDialog::DontResolveSymlinks
|
||||||
);
|
);
|
||||||
|
@ -192,7 +200,23 @@ void MainWindow::dumpRomFS() {
|
||||||
if (folder.isEmpty()) {
|
if (folder.isEmpty()) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::filesystem::path path(folder.toStdU16String());
|
std::filesystem::path path(folder.toStdU16String());
|
||||||
|
|
||||||
|
// TODO: This might break if the game accesses RomFS while we're dumping, we should move it to the emulator thread when we've got a message queue going
|
||||||
|
messageQueueMutex.lock();
|
||||||
RomFS::DumpingResult res = emu->dumpRomFS(path);
|
RomFS::DumpingResult res = emu->dumpRomFS(path);
|
||||||
|
messageQueueMutex.unlock();
|
||||||
|
|
||||||
|
switch (res) {
|
||||||
|
case RomFS::DumpingResult::Success: break; // Yay!
|
||||||
|
case RomFS::DumpingResult::InvalidFormat:
|
||||||
|
QMessageBox::warning(
|
||||||
|
this, tr("Invalid format for RomFS dumping"), tr("The currently loaded app is not in a format that supports RomFS!")
|
||||||
|
);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case RomFS::DumpingResult::NoRomFS:
|
||||||
|
QMessageBox::warning(this, tr("No RomFS found"), tr("No RomFS partition was found in the loaded app"));
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
Loading…
Add table
Add a link
Reference in a new issue