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
This commit is contained in:
Jake.Stine 2010-04-27 15:18:25 +00:00
parent df60f016c8
commit bd76de1a8b
5 changed files with 94 additions and 89 deletions

View File

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

View File

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

View File

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

View File

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

View File

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