Qt: Fixed a bug in shutdown procedure, various cleanups.

merge-requests/60/head
bunnei 2015-04-30 19:46:50 +07:00
parent ad4445c529
commit bc41de2131
7 changed files with 26 additions and 35 deletions

@ -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();