From 3266394dfbb564f69e3cd6470ad608a4db314916 Mon Sep 17 00:00:00 2001 From: Jules Blok Date: Fri, 20 Jun 2014 02:43:57 +0200 Subject: Make the emulation stop asynchronous to prevent deadlocks. This may expose bugs which relied on the Main Thread to be suspended in the stopping state. --- Source/Core/DolphinWX/FrameTools.cpp | 105 ++++++++++++++++++----------------- 1 file changed, 55 insertions(+), 50 deletions(-) (limited to 'Source/Core/DolphinWX/FrameTools.cpp') diff --git a/Source/Core/DolphinWX/FrameTools.cpp b/Source/Core/DolphinWX/FrameTools.cpp index 6548deb5f0..7c72aad691 100644 --- a/Source/Core/DolphinWX/FrameTools.cpp +++ b/Source/Core/DolphinWX/FrameTools.cpp @@ -1120,72 +1120,77 @@ void CFrame::DoStop() wxBeginBusyCursor(); BootManager::Stop(); - wxEndBusyCursor(); - confirmStop = false; + } +} + +void CFrame::OnStopped() +{ + wxEndBusyCursor(); + + confirmStop = false; #if defined(HAVE_X11) && HAVE_X11 if (SConfig::GetInstance().m_LocalCoreStartupParameter.bDisableScreenSaver) X11Utils::InhibitScreensaver(X11Utils::XDisplayFromHandle(GetHandle()), X11Utils::XWindowFromHandle(GetHandle()), false); #endif - m_RenderFrame->SetTitle(StrToWxStr(scm_rev_str)); + m_RenderFrame->SetTitle(StrToWxStr(scm_rev_str)); - // Destroy the renderer frame when not rendering to main - m_RenderParent->Unbind(wxEVT_SIZE, &CFrame::OnRenderParentResize, this); - - // Keyboard - wxTheApp->Unbind(wxEVT_KEY_DOWN, &CFrame::OnKeyDown, this); - wxTheApp->Unbind(wxEVT_KEY_UP, &CFrame::OnKeyUp, this); - - // Mouse - wxTheApp->Unbind(wxEVT_RIGHT_DOWN, &CFrame::OnMouse, this); - wxTheApp->Unbind(wxEVT_RIGHT_UP, &CFrame::OnMouse, this); - wxTheApp->Unbind(wxEVT_MIDDLE_DOWN, &CFrame::OnMouse, this); - wxTheApp->Unbind(wxEVT_MIDDLE_UP, &CFrame::OnMouse, this); - wxTheApp->Unbind(wxEVT_MOTION, &CFrame::OnMouse, this); - if (SConfig::GetInstance().m_LocalCoreStartupParameter.bHideCursor) - m_RenderParent->SetCursor(wxNullCursor); - DoFullscreen(false); - if (!SConfig::GetInstance().m_LocalCoreStartupParameter.bRenderToMain) - { - m_RenderFrame->Destroy(); - } - else - { + // Destroy the renderer frame when not rendering to main + m_RenderParent->Unbind(wxEVT_SIZE, &CFrame::OnRenderParentResize, this); + + // Keyboard + wxTheApp->Unbind(wxEVT_KEY_DOWN, &CFrame::OnKeyDown, this); + wxTheApp->Unbind(wxEVT_KEY_UP, &CFrame::OnKeyUp, this); + + // Mouse + wxTheApp->Unbind(wxEVT_RIGHT_DOWN, &CFrame::OnMouse, this); + wxTheApp->Unbind(wxEVT_RIGHT_UP, &CFrame::OnMouse, this); + wxTheApp->Unbind(wxEVT_MIDDLE_DOWN, &CFrame::OnMouse, this); + wxTheApp->Unbind(wxEVT_MIDDLE_UP, &CFrame::OnMouse, this); + wxTheApp->Unbind(wxEVT_MOTION, &CFrame::OnMouse, this); + if (SConfig::GetInstance().m_LocalCoreStartupParameter.bHideCursor) + m_RenderParent->SetCursor(wxNullCursor); + DoFullscreen(false); + if (!SConfig::GetInstance().m_LocalCoreStartupParameter.bRenderToMain) + { + m_RenderFrame->Destroy(); + } + else + { #if defined(__APPLE__) - // Disable the full screen button when not in a game. - NSView *view = (NSView *) m_RenderFrame->GetHandle(); - NSWindow *window = [view window]; + // Disable the full screen button when not in a game. + NSView *view = (NSView *)m_RenderFrame->GetHandle(); + NSWindow *window = [view window]; - [window setCollectionBehavior:NSWindowCollectionBehaviorDefault]; + [window setCollectionBehavior : NSWindowCollectionBehaviorDefault]; #endif - // Make sure the window is not longer set to stay on top - m_RenderFrame->SetWindowStyle(m_RenderFrame->GetWindowStyle() & ~wxSTAY_ON_TOP); - } - m_RenderParent = nullptr; + // Make sure the window is not longer set to stay on top + m_RenderFrame->SetWindowStyle(m_RenderFrame->GetWindowStyle() & ~wxSTAY_ON_TOP); + } + m_RenderParent = nullptr; - // Clean framerate indications from the status bar. - GetStatusBar()->SetStatusText(" ", 0); + // Clean framerate indications from the status bar. + GetStatusBar()->SetStatusText(" ", 0); - // Clear wiimote connection status from the status bar. - GetStatusBar()->SetStatusText(" ", 1); + // Clear wiimote connection status from the status bar. + GetStatusBar()->SetStatusText(" ", 1); - // If batch mode was specified on the command-line, exit now. - if (m_bBatchMode) - Close(true); + // If batch mode was specified on the command-line, exit now. + if (m_bBatchMode) + Close(true); - // If using auto size with render to main, reset the application size. - if (SConfig::GetInstance().m_LocalCoreStartupParameter.bRenderToMain && - SConfig::GetInstance().m_LocalCoreStartupParameter.bRenderWindowAutoSize) - SetSize(SConfig::GetInstance().m_LocalCoreStartupParameter.iWidth, - SConfig::GetInstance().m_LocalCoreStartupParameter.iHeight); + // If using auto size with render to main, reset the application size. + if (SConfig::GetInstance().m_LocalCoreStartupParameter.bRenderToMain && + SConfig::GetInstance().m_LocalCoreStartupParameter.bRenderWindowAutoSize) + SetSize(SConfig::GetInstance().m_LocalCoreStartupParameter.iWidth, + SConfig::GetInstance().m_LocalCoreStartupParameter.iHeight); - m_GameListCtrl->Enable(); - m_GameListCtrl->Show(); - m_GameListCtrl->SetFocus(); - UpdateGUI(); - } + m_GameListCtrl->Enable(); + m_GameListCtrl->Show(); + m_GameListCtrl->SetFocus(); + UpdateGUI(); } void CFrame::DoRecordingSave() -- cgit v1.2.3 From b30d5dccbe46c4bf9977a1437a826d082abebee0 Mon Sep 17 00:00:00 2001 From: Jules Blok Date: Fri, 20 Jun 2014 03:03:00 +0200 Subject: Frame: OnClose now handles asynchronous behaviour of DoStop(). --- Source/Core/DolphinWX/FrameTools.cpp | 17 ++++++++++++----- 1 file changed, 12 insertions(+), 5 deletions(-) (limited to 'Source/Core/DolphinWX/FrameTools.cpp') diff --git a/Source/Core/DolphinWX/FrameTools.cpp b/Source/Core/DolphinWX/FrameTools.cpp index 7c72aad691..6fb0f0106a 100644 --- a/Source/Core/DolphinWX/FrameTools.cpp +++ b/Source/Core/DolphinWX/FrameTools.cpp @@ -832,9 +832,16 @@ void CFrame::OnPlay(wxCommandEvent& WXUNUSED (event)) void CFrame::OnRenderParentClose(wxCloseEvent& event) { - DoStop(); - if (Core::GetState() == Core::CORE_UNINITIALIZED) - event.Skip(); + // Before closing the window we need to shut down the emulation core. + // We'll try to close this window again once that is done. + if (Core::GetState() != Core::CORE_UNINITIALIZED) + { + DoStop(); + event.Veto(); + return; + } + + event.Skip(); } void CFrame::OnRenderParentMove(wxMoveEvent& event) @@ -1177,8 +1184,8 @@ void CFrame::OnStopped() // Clear wiimote connection status from the status bar. GetStatusBar()->SetStatusText(" ", 1); - // If batch mode was specified on the command-line, exit now. - if (m_bBatchMode) + // If batch mode was specified on the command-line or we were already closing, exit now. + if (m_bBatchMode || m_bClosing) Close(true); // If using auto size with render to main, reset the application size. -- cgit v1.2.3 From ad1b61af2e5d5b4c63c6d7ed052775e1c2858c39 Mon Sep 17 00:00:00 2001 From: Jules Blok Date: Sat, 28 Jun 2014 18:56:53 +0200 Subject: FrameTools: Update GUI and disable Play button when in stopping state. --- Source/Core/DolphinWX/FrameTools.cpp | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) (limited to 'Source/Core/DolphinWX/FrameTools.cpp') diff --git a/Source/Core/DolphinWX/FrameTools.cpp b/Source/Core/DolphinWX/FrameTools.cpp index 6fb0f0106a..66a5aa6858 100644 --- a/Source/Core/DolphinWX/FrameTools.cpp +++ b/Source/Core/DolphinWX/FrameTools.cpp @@ -1127,6 +1127,7 @@ void CFrame::DoStop() wxBeginBusyCursor(); BootManager::Stop(); + UpdateGUI(); } } @@ -1638,6 +1639,7 @@ void CFrame::UpdateGUI() bool Initialized = Core::IsRunning(); bool Running = Core::GetState() == Core::CORE_RUN; bool Paused = Core::GetState() == Core::CORE_PAUSE; + bool Stopping = Core::GetState() == Core::CORE_STOPPING; bool RunningWii = Initialized && SConfig::GetInstance().m_LocalCoreStartupParameter.bWii; bool RunningGamecube = Initialized && !SConfig::GetInstance().m_LocalCoreStartupParameter.bWii; @@ -1784,8 +1786,8 @@ void CFrame::UpdateGUI() { // Game has been loaded, enable the pause button if (m_ToolBar) - m_ToolBar->EnableTool(IDM_PLAY, true); - GetMenuBar()->FindItem(IDM_PLAY)->Enable(true); + m_ToolBar->EnableTool(IDM_PLAY, !Stopping); + GetMenuBar()->FindItem(IDM_PLAY)->Enable(!Stopping); // Reset game loading flag m_bGameLoading = false; -- cgit v1.2.3 From db7e746cb423de5ca47be7a3df7c4918a610ff5a Mon Sep 17 00:00:00 2001 From: Jules Blok Date: Tue, 8 Jul 2014 00:47:57 +0200 Subject: Check whether the core is running instead of checking if it is unitialized. This properly handles the stopping state and more accurately represents the intended check. --- Source/Core/DolphinWX/FrameTools.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'Source/Core/DolphinWX/FrameTools.cpp') diff --git a/Source/Core/DolphinWX/FrameTools.cpp b/Source/Core/DolphinWX/FrameTools.cpp index 66a5aa6858..7cd29d7ef5 100644 --- a/Source/Core/DolphinWX/FrameTools.cpp +++ b/Source/Core/DolphinWX/FrameTools.cpp @@ -802,7 +802,7 @@ void CFrame::OnRecordExport(wxCommandEvent& WXUNUSED (event)) void CFrame::OnPlay(wxCommandEvent& WXUNUSED (event)) { - if (Core::GetState() != Core::CORE_UNINITIALIZED) + if (Core::IsRunning()) { // Core is initialized and emulator is running if (UseDebugger) @@ -1581,7 +1581,7 @@ void CFrame::OnLoadLastState(wxCommandEvent& event) void CFrame::OnSaveFirstState(wxCommandEvent& WXUNUSED(event)) { - if (Core::GetState() != Core::CORE_UNINITIALIZED) + if (Core::IsRunningAndStarted()) State::SaveFirstSaved(); } -- cgit v1.2.3