From bd76de1a8b70df4fd94e23a9bbaed100ca7bc633 Mon Sep 17 00:00:00 2001 From: "Jake.Stine" Date: Tue, 27 Apr 2010 15:18:25 +0000 Subject: [PATCH] Some bugfixes to suspend/resume and changing plugin options on the fly. git-svn-id: http://pcsx2.googlecode.com/svn/trunk@2915 96395faa-99c1-11dd-bbfe-3dabce05a288 --- pcsx2/gui/AppCorePlugins.cpp | 19 ++++- pcsx2/gui/AppCoreThread.cpp | 130 +++++++++++++++-------------------- pcsx2/gui/MainFrame.h | 1 + pcsx2/gui/MainMenuClicks.cpp | 2 +- pcsx2/gui/UpdateUI.cpp | 31 +++++---- 5 files changed, 94 insertions(+), 89 deletions(-) diff --git a/pcsx2/gui/AppCorePlugins.cpp b/pcsx2/gui/AppCorePlugins.cpp index a6d2be410a..5e2ae7bd3b 100644 --- a/pcsx2/gui/AppCorePlugins.cpp +++ b/pcsx2/gui/AppCorePlugins.cpp @@ -400,8 +400,9 @@ SaveSinglePluginHelper::SaveSinglePluginHelper( PluginsEnum_t pid ) SaveSinglePluginHelper::~SaveSinglePluginHelper() throw() { - try - { + bool allowResume = true; + + try { if( m_validstate ) { Console.WriteLn( Color_Green, L"Recovering single plugin: " + tbl_PluginInfo[m_pid].GetShortname() ); @@ -413,7 +414,19 @@ SaveSinglePluginHelper::~SaveSinglePluginHelper() throw() s_DisableGsWindow = false; } - DESTRUCTOR_CATCHALL; + catch( BaseException& ex ) + { + allowResume = false; + Console.Error( "Unhandled BaseException in %s (ignored!):", __pxFUNCTION__ ); + Console.Error( ex.FormatDiagnosticMessage() ); + } + catch( std::exception& ex ) + { + allowResume = false; + Console.Error( "Unhandled std::exception in %s (ignored!):", __pxFUNCTION__ ); + Console.Error( ex.what() ); + } s_DisableGsWindow = false; + if( allowResume ) m_scoped_pause.AllowResume(); } diff --git a/pcsx2/gui/AppCoreThread.cpp b/pcsx2/gui/AppCoreThread.cpp index 9205ad29a8..5a68f85e1d 100644 --- a/pcsx2/gui/AppCoreThread.cpp +++ b/pcsx2/gui/AppCoreThread.cpp @@ -275,14 +275,62 @@ enum }; // -------------------------------------------------------------------------------------- -// SysExecEvent_FullStop +// BaseSysExecEvent_ScopedCore // -------------------------------------------------------------------------------------- -class SysExecEvent_FullStop : public SysExecEvent +class BaseSysExecEvent_ScopedCore : public SysExecEvent { protected: SynchronousActionState* m_resume; Threading::Mutex* m_mtx_resume; +public: + virtual ~BaseSysExecEvent_ScopedCore() throw() {} + +protected: + BaseSysExecEvent_ScopedCore( SynchronousActionState* sync=NULL, SynchronousActionState* resume_sync=NULL, Threading::Mutex* mtx_resume=NULL ) + : SysExecEvent( sync ) + { + m_resume = resume_sync; + m_mtx_resume = mtx_resume; + } + + void _post_and_wait( IScopedCoreThread& core ) + { + PostResult(); + + if( m_resume ) + { + ScopedLock lock( m_mtx_resume ); + + // If the sender of the message requests a non-blocking resume, then we need + // to deallocate the m_sync object, since the sender will likely leave scope and + // invalidate it. + switch( m_resume->WaitForResult() ) + { + case FullStop_BlockingResume: + if( m_sync ) m_sync->ClearResult(); + core.AllowResume(); + break; + + case FullStop_NonblockingResume: + m_sync = NULL; + core.AllowResume(); + break; + + case FullStop_SkipResume: + m_sync = NULL; + break; + } + } + } + +}; + +// -------------------------------------------------------------------------------------- +// SysExecEvent_FullStop +// -------------------------------------------------------------------------------------- +class SysExecEvent_FullStop : public BaseSysExecEvent_ScopedCore +{ public: virtual ~SysExecEvent_FullStop() throw() {} SysExecEvent_FullStop* Clone() const @@ -291,46 +339,16 @@ public: } SysExecEvent_FullStop( SynchronousActionState* sync=NULL, SynchronousActionState* resume_sync=NULL, Threading::Mutex* mtx_resume=NULL ) - : SysExecEvent( sync ) - { - m_resume = resume_sync; - m_mtx_resume = mtx_resume; - } + : BaseSysExecEvent_ScopedCore( sync, resume_sync, mtx_resume ) { } SysExecEvent_FullStop( SynchronousActionState& sync, SynchronousActionState& resume_sync, Threading::Mutex& mtx_resume ) - : SysExecEvent( sync ) - { - m_resume = &resume_sync; - m_mtx_resume = &mtx_resume; - } + : BaseSysExecEvent_ScopedCore( &sync, &resume_sync, &mtx_resume ) { } protected: void _DoInvoke() { ScopedCoreThreadClose closed_core; - PostResult(); - - if( m_resume ) - { - ScopedLock lock( m_mtx_resume ); - - // If the sender of the message requests a non-blocking resume, then we need - // to deallocate the m_sync object, since the sender will likely leave scope and - // invalidate it. - switch( m_resume->WaitForResult() ) - { - case FullStop_SkipResume: return; - - case FullStop_BlockingResume: - if( m_sync ) m_sync->ClearResult(); - break; - - case FullStop_NonblockingResume: - m_sync = NULL; - break; - } - } - + _post_and_wait(closed_core); closed_core.AllowResume(); } }; @@ -338,12 +356,8 @@ protected: // -------------------------------------------------------------------------------------- // SysExecEvent_FullStop // -------------------------------------------------------------------------------------- -class SysExecEvent_Pause : public SysExecEvent +class SysExecEvent_Pause : public BaseSysExecEvent_ScopedCore { -protected: - SynchronousActionState* m_resume; - Threading::Mutex* m_mtx_resume; - public: virtual ~SysExecEvent_Pause() throw() {} SysExecEvent_Pause* Clone() const @@ -352,46 +366,16 @@ public: } SysExecEvent_Pause( SynchronousActionState* sync=NULL, SynchronousActionState* resume_sync=NULL, Threading::Mutex* mtx_resume=NULL ) - : SysExecEvent( sync ) - { - m_resume = resume_sync; - m_mtx_resume = mtx_resume; - } + : BaseSysExecEvent_ScopedCore( sync, resume_sync, mtx_resume ) { } SysExecEvent_Pause( SynchronousActionState& sync, SynchronousActionState& resume_sync, Threading::Mutex& mtx_resume ) - : SysExecEvent( sync ) - { - m_resume = &resume_sync; - m_mtx_resume = &mtx_resume; - } + : BaseSysExecEvent_ScopedCore( &sync, &resume_sync, &mtx_resume ) { } protected: void _DoInvoke() { ScopedCoreThreadPause paused_core; - PostResult(); - - if( m_resume ) - { - ScopedLock lock( m_mtx_resume ); - - // If the sender of the message requests a non-blocking resume, then we need - // to deallocate the m_sync object, since the sender will likely leave scope and - // invalidate it. - switch( m_resume->WaitForResult() ) - { - case FullStop_SkipResume: return; - - case FullStop_BlockingResume: - if( m_sync ) m_sync->ClearResult(); - break; - - case FullStop_NonblockingResume: - m_sync = NULL; - break; - } - } - + _post_and_wait(paused_core); paused_core.AllowResume(); } }; diff --git a/pcsx2/gui/MainFrame.h b/pcsx2/gui/MainFrame.h index 85b8a4c829..67ca3769ee 100644 --- a/pcsx2/gui/MainFrame.h +++ b/pcsx2/gui/MainFrame.h @@ -143,6 +143,7 @@ public: bool IsPaused() const { return GetMenuBar()->IsChecked( MenuId_Sys_SuspendResume ); } void UpdateIsoSrcSelection(); void RemoveCdvdMenu(); + void EnableMenuItem( int id, bool enable ); protected: void ApplySettings(); diff --git a/pcsx2/gui/MainMenuClicks.cpp b/pcsx2/gui/MainMenuClicks.cpp index 6990d30360..4b47b1cac0 100644 --- a/pcsx2/gui/MainMenuClicks.cpp +++ b/pcsx2/gui/MainMenuClicks.cpp @@ -448,7 +448,7 @@ void MainEmuFrame::Menu_SuspendResume_Click(wxCommandEvent &event) // has responded (it updates status after the plugins are loaded and emulation has // engaged successfully). - GetMenuBar()->Enable( MenuId_Sys_SuspendResume, false ); + EnableMenuItem( MenuId_Sys_SuspendResume, false ); GetSysExecutorThread().PostEvent( new SysExecEvent_ToggleSuspend() ); } diff --git a/pcsx2/gui/UpdateUI.cpp b/pcsx2/gui/UpdateUI.cpp index 5ba1d5dd86..2a60fd0356 100644 --- a/pcsx2/gui/UpdateUI.cpp +++ b/pcsx2/gui/UpdateUI.cpp @@ -17,11 +17,19 @@ #include "Mainframe.h" #include "GSFrame.h" +// This is necessary because this stupid wxWdigets thing has implicit debug errors +// in the FindItem call that asserts if the menu options are missing. This is bad +// mojo for configurable/dynamic menus. >_< +void MainEmuFrame::EnableMenuItem( int id, bool enable ) +{ + if( wxMenuItem* item = m_menubar.FindItem(id) ) + item->Enable( enable ); +} static void _SaveLoadStuff( bool enabled ) { - sMainFrame.GetMenuBar()->Enable( MenuId_Sys_LoadStates, enabled ); - sMainFrame.GetMenuBar()->Enable( MenuId_Sys_SaveStates, enabled ); + sMainFrame.EnableMenuItem( MenuId_Sys_LoadStates, enabled ); + sMainFrame.EnableMenuItem( MenuId_Sys_SaveStates, enabled ); } // Updates the enable/disable status of all System related controls: menus, toolbars, @@ -35,11 +43,10 @@ void UI_UpdateSysControls() _SaveLoadStuff( true ); } - void UI_DisableSysReset() { if( wxGetApp().PostMethodMyself( UI_DisableSysReset ) ) return; - sMainFrame.GetMenuBar()->Enable( MenuId_Sys_Restart, false ); + sMainFrame.EnableMenuItem( MenuId_Sys_Restart, false ); _SaveLoadStuff( false ); } @@ -48,16 +55,16 @@ void UI_DisableSysShutdown() { if( wxGetApp().PostMethodMyself( &UI_DisableSysShutdown ) ) return; - sMainFrame.GetMenuBar()->Enable( MenuId_Sys_Restart, false ); - sMainFrame.GetMenuBar()->Enable( MenuId_Sys_Shutdown, false ); + sMainFrame.EnableMenuItem( MenuId_Sys_Restart, false ); + sMainFrame.EnableMenuItem( MenuId_Sys_Shutdown, false ); } void UI_EnableSysShutdown() { if( wxGetApp().PostMethodMyself( &UI_EnableSysShutdown ) ) return; - sMainFrame.GetMenuBar()->Enable( MenuId_Sys_Restart, true ); - sMainFrame.GetMenuBar()->Enable( MenuId_Sys_Shutdown, true ); + sMainFrame.EnableMenuItem( MenuId_Sys_Restart, true ); + sMainFrame.EnableMenuItem( MenuId_Sys_Shutdown, true ); } @@ -65,16 +72,16 @@ void UI_DisableSysActions() { if( wxGetApp().PostMethodMyself( &UI_DisableSysShutdown ) ) return; - sMainFrame.GetMenuBar()->Enable( MenuId_Sys_Restart, false ); - sMainFrame.GetMenuBar()->Enable( MenuId_Sys_Shutdown, false ); + sMainFrame.EnableMenuItem( MenuId_Sys_Restart, false ); + sMainFrame.EnableMenuItem( MenuId_Sys_Shutdown, false ); } void UI_EnableSysActions() { if( wxGetApp().PostMethodMyself( &UI_EnableSysShutdown ) ) return; - sMainFrame.GetMenuBar()->Enable( MenuId_Sys_Restart, true ); - sMainFrame.GetMenuBar()->Enable( MenuId_Sys_Shutdown, true ); + sMainFrame.EnableMenuItem( MenuId_Sys_Restart, true ); + sMainFrame.EnableMenuItem( MenuId_Sys_Shutdown, true ); }