Qt: Fixed a bug in shutdown procedure, various cleanups.
This commit is contained in:
parent
ad4445c529
commit
bc41de2131
|
@ -48,7 +48,7 @@ void EmuThread::run() {
|
||||||
Core::RunLoop();
|
Core::RunLoop();
|
||||||
|
|
||||||
was_active = running || exec_step;
|
was_active = running || exec_step;
|
||||||
if (!was_active)
|
if (!was_active && !stop_run)
|
||||||
emit DebugModeEntered();
|
emit DebugModeEntered();
|
||||||
} else if (exec_step) {
|
} else if (exec_step) {
|
||||||
if (!was_active)
|
if (!was_active)
|
||||||
|
@ -273,10 +273,10 @@ void GRenderWindow::OnMinimalClientAreaChangeRequest(const std::pair<unsigned,un
|
||||||
setMinimumSize(minimal_size.first, minimal_size.second);
|
setMinimumSize(minimal_size.first, minimal_size.second);
|
||||||
}
|
}
|
||||||
|
|
||||||
void GRenderWindow::OnEmulationStarted(EmuThread* emu_thread) {
|
void GRenderWindow::OnEmulationStarting(EmuThread* emu_thread) {
|
||||||
this->emu_thread = emu_thread;
|
this->emu_thread = emu_thread;
|
||||||
}
|
}
|
||||||
|
|
||||||
void GRenderWindow::OnEmulationStopped() {
|
void GRenderWindow::OnEmulationStopping() {
|
||||||
emu_thread = nullptr;
|
emu_thread = nullptr;
|
||||||
}
|
}
|
||||||
|
|
|
@ -51,9 +51,9 @@ public:
|
||||||
bool IsRunning() { return running; }
|
bool IsRunning() { return running; }
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Requests for the emulation thread to stop running and shutdown emulation
|
* Requests for the emulation thread to stop running
|
||||||
*/
|
*/
|
||||||
void RequestShutdown() {
|
void RequestStop() {
|
||||||
stop_run = true;
|
stop_run = true;
|
||||||
running = false;
|
running = false;
|
||||||
};
|
};
|
||||||
|
@ -115,8 +115,8 @@ public:
|
||||||
public slots:
|
public slots:
|
||||||
void moveContext(); // overridden
|
void moveContext(); // overridden
|
||||||
|
|
||||||
void OnEmulationStarted(EmuThread* emu_thread);
|
void OnEmulationStarting(EmuThread* emu_thread);
|
||||||
void OnEmulationStopped();
|
void OnEmulationStopping();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void OnMinimalClientAreaChangeRequest(const std::pair<unsigned,unsigned>& minimal_size) override;
|
void OnMinimalClientAreaChangeRequest(const std::pair<unsigned,unsigned>& minimal_size) override;
|
||||||
|
|
|
@ -241,7 +241,7 @@ int DisassemblerWidget::SelectedRow() {
|
||||||
return disasm_ui.treeView->selectionModel()->currentIndex().row();
|
return disasm_ui.treeView->selectionModel()->currentIndex().row();
|
||||||
}
|
}
|
||||||
|
|
||||||
void DisassemblerWidget::OnEmulationStarted(EmuThread* emu_thread) {
|
void DisassemblerWidget::OnEmulationStarting(EmuThread* emu_thread) {
|
||||||
this->emu_thread = emu_thread;
|
this->emu_thread = emu_thread;
|
||||||
|
|
||||||
model = new DisassemblerModel(this);
|
model = new DisassemblerModel(this);
|
||||||
|
@ -256,7 +256,7 @@ void DisassemblerWidget::OnEmulationStarted(EmuThread* emu_thread) {
|
||||||
setEnabled(true);
|
setEnabled(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
void DisassemblerWidget::OnEmulationStopped() {
|
void DisassemblerWidget::OnEmulationStopping() {
|
||||||
disasm_ui.treeView->setModel(nullptr);
|
disasm_ui.treeView->setModel(nullptr);
|
||||||
delete model;
|
delete model;
|
||||||
emu_thread = nullptr;
|
emu_thread = nullptr;
|
||||||
|
|
|
@ -65,8 +65,8 @@ public slots:
|
||||||
void OnDebugModeEntered();
|
void OnDebugModeEntered();
|
||||||
void OnDebugModeLeft();
|
void OnDebugModeLeft();
|
||||||
|
|
||||||
void OnEmulationStarted(EmuThread* emu_thread);
|
void OnEmulationStarting(EmuThread* emu_thread);
|
||||||
void OnEmulationStopped();
|
void OnEmulationStopping();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
// returns -1 if no row is selected
|
// returns -1 if no row is selected
|
||||||
|
|
|
@ -71,11 +71,11 @@ void RegistersWidget::OnDebugModeEntered() {
|
||||||
void RegistersWidget::OnDebugModeLeft() {
|
void RegistersWidget::OnDebugModeLeft() {
|
||||||
}
|
}
|
||||||
|
|
||||||
void RegistersWidget::OnEmulationStarted(EmuThread* emu_thread) {
|
void RegistersWidget::OnEmulationStarting(EmuThread* emu_thread) {
|
||||||
setEnabled(true);
|
setEnabled(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
void RegistersWidget::OnEmulationStopped() {
|
void RegistersWidget::OnEmulationStopping() {
|
||||||
// Reset widget text
|
// Reset widget text
|
||||||
for (int i = 0; i < 16; ++i)
|
for (int i = 0; i < 16; ++i)
|
||||||
registers->child(i)->setText(1, QString(""));
|
registers->child(i)->setText(1, QString(""));
|
||||||
|
|
|
@ -21,8 +21,8 @@ public slots:
|
||||||
void OnDebugModeEntered();
|
void OnDebugModeEntered();
|
||||||
void OnDebugModeLeft();
|
void OnDebugModeLeft();
|
||||||
|
|
||||||
void OnEmulationStarted(EmuThread* emu_thread);
|
void OnEmulationStarting(EmuThread* emu_thread);
|
||||||
void OnEmulationStopped();
|
void OnEmulationStopping();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
Ui::ARMRegisters cpu_regs_ui;
|
Ui::ARMRegisters cpu_regs_ui;
|
||||||
|
|
|
@ -139,12 +139,12 @@ GMainWindow::GMainWindow() : emu_thread(nullptr)
|
||||||
connect(ui.action_Single_Window_Mode, SIGNAL(triggered(bool)), this, SLOT(ToggleWindowMode()));
|
connect(ui.action_Single_Window_Mode, SIGNAL(triggered(bool)), this, SLOT(ToggleWindowMode()));
|
||||||
connect(ui.action_Hotkeys, SIGNAL(triggered()), this, SLOT(OnOpenHotkeysDialog()));
|
connect(ui.action_Hotkeys, SIGNAL(triggered()), this, SLOT(OnOpenHotkeysDialog()));
|
||||||
|
|
||||||
connect(this, SIGNAL(EmulationStarted(EmuThread*)), disasmWidget, SLOT(OnEmulationStarted(EmuThread*)));
|
connect(this, SIGNAL(EmulationStarting(EmuThread*)), disasmWidget, SLOT(OnEmulationStarting(EmuThread*)));
|
||||||
connect(this, SIGNAL(EmulationStopped()), disasmWidget, SLOT(OnEmulationStopped()));
|
connect(this, SIGNAL(EmulationStopping()), disasmWidget, SLOT(OnEmulationStopping()));
|
||||||
connect(this, SIGNAL(EmulationStarted(EmuThread*)), registersWidget, SLOT(OnEmulationStarted(EmuThread*)));
|
connect(this, SIGNAL(EmulationStarting(EmuThread*)), registersWidget, SLOT(OnEmulationStarting(EmuThread*)));
|
||||||
connect(this, SIGNAL(EmulationStopped()), registersWidget, SLOT(OnEmulationStopped()));
|
connect(this, SIGNAL(EmulationStopping()), registersWidget, SLOT(OnEmulationStopping()));
|
||||||
connect(this, SIGNAL(EmulationStarted(EmuThread*)), render_window, SLOT(OnEmulationStarted(EmuThread*)));
|
connect(this, SIGNAL(EmulationStarting(EmuThread*)), render_window, SLOT(OnEmulationStarting(EmuThread*)));
|
||||||
connect(this, SIGNAL(EmulationStopped()), render_window, SLOT(OnEmulationStopped()));
|
connect(this, SIGNAL(EmulationStopping()), render_window, SLOT(OnEmulationStopping()));
|
||||||
|
|
||||||
// Setup hotkeys
|
// Setup hotkeys
|
||||||
RegisterHotkey("Main Window", "Load File", QKeySequence::Open);
|
RegisterHotkey("Main Window", "Load File", QKeySequence::Open);
|
||||||
|
@ -210,7 +210,7 @@ void GMainWindow::BootGame(std::string filename) {
|
||||||
|
|
||||||
// Create and start the emulation thread
|
// Create and start the emulation thread
|
||||||
emu_thread = Common::make_unique<EmuThread>(render_window);
|
emu_thread = Common::make_unique<EmuThread>(render_window);
|
||||||
emit EmulationStarted(emu_thread.get());
|
emit EmulationStarting(emu_thread.get());
|
||||||
emu_thread->start();
|
emu_thread->start();
|
||||||
|
|
||||||
// BlockingQueuedConnection is important here, it makes sure we've finished refreshing our views before the CPU continues
|
// BlockingQueuedConnection is important here, it makes sure we've finished refreshing our views before the CPU continues
|
||||||
|
@ -230,25 +230,16 @@ void GMainWindow::BootGame(std::string filename) {
|
||||||
}
|
}
|
||||||
|
|
||||||
void GMainWindow::ShutdownGame() {
|
void GMainWindow::ShutdownGame() {
|
||||||
// Shutdown the emulation thread
|
emu_thread->RequestStop();
|
||||||
emu_thread->RequestShutdown();
|
|
||||||
|
|
||||||
// Disconnect signals that are attached to the current emulation thread
|
|
||||||
disconnect(emu_thread.get(), SIGNAL(DebugModeEntered()), disasmWidget, SLOT(OnDebugModeEntered()));
|
|
||||||
disconnect(emu_thread.get(), SIGNAL(DebugModeEntered()), registersWidget, SLOT(OnDebugModeEntered()));
|
|
||||||
disconnect(emu_thread.get(), SIGNAL(DebugModeEntered()), callstackWidget, SLOT(OnDebugModeEntered()));
|
|
||||||
disconnect(emu_thread.get(), SIGNAL(DebugModeLeft()), disasmWidget, SLOT(OnDebugModeLeft()));
|
|
||||||
disconnect(emu_thread.get(), SIGNAL(DebugModeLeft()), registersWidget, SLOT(OnDebugModeLeft()));
|
|
||||||
disconnect(emu_thread.get(), SIGNAL(DebugModeLeft()), callstackWidget, SLOT(OnDebugModeLeft()));
|
|
||||||
|
|
||||||
// Release emu threads from any breakpoints
|
// Release emu threads from any breakpoints
|
||||||
// This belongs after RequestShutdown() and before wait() because if emulation stops on a GPU
|
// This belongs after RequestStop() and before wait() because if emulation stops on a GPU
|
||||||
// breakpoint after (or before) RequestShutdown() is called, the emulation would never be able
|
// breakpoint after (or before) RequestStop() is called, the emulation would never be able
|
||||||
// to continue out to the main loop and terminate. Thus wait() would hang forever.
|
// to continue out to the main loop and terminate. Thus wait() would hang forever.
|
||||||
// TODO(bunnei): This function is not thread safe, but it's being used as if it were
|
// TODO(bunnei): This function is not thread safe, but it's being used as if it were
|
||||||
Pica::g_debug_context->ClearBreakpoints();
|
Pica::g_debug_context->ClearBreakpoints();
|
||||||
|
|
||||||
emit EmulationStopped();
|
emit EmulationStopping();
|
||||||
|
|
||||||
// Wait for emulation thread to complete and delete it
|
// Wait for emulation thread to complete and delete it
|
||||||
emu_thread->wait();
|
emu_thread->wait();
|
||||||
|
|
Reference in New Issue