Add some new checks for blocking VM reset/shutdown while savestates are saving (avoids accidental corruption). Renamed a lot of the new event listener code so that it's consistent... ish.

git-svn-id: http://pcsx2.googlecode.com/svn/trunk@2497 96395faa-99c1-11dd-bbfe-3dabce05a288
This commit is contained in:
Jake.Stine 2010-01-23 17:13:03 +00:00
parent bb3eda1524
commit fa04244375
26 changed files with 412 additions and 246 deletions

View File

@ -53,6 +53,13 @@ public:
bool IsReentrant() const { return Counter > 1; } bool IsReentrant() const { return Counter > 1; }
}; };
class IActionInvocation
{
public:
virtual ~IActionInvocation() throw() {}
virtual void InvokeAction()=0;
};
// -------------------------------------------------------------------------------------- // --------------------------------------------------------------------------------------
// IDeletableObject // IDeletableObject
// -------------------------------------------------------------------------------------- // --------------------------------------------------------------------------------------

View File

@ -54,7 +54,6 @@ public:
extern StartupParams g_Startup; extern StartupParams g_Startup;
extern void States_Save( const wxString& file );
extern bool States_isSlotUsed(int num); extern bool States_isSlotUsed(int num);
extern void States_FreezeCurrentSlot(); extern void States_FreezeCurrentSlot();

View File

@ -565,7 +565,7 @@ void memClearPageAddr(u32 vaddr)
/////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////
// PS2 Memory Init / Reset / Shutdown // PS2 Memory Init / Reset / Shutdown
class mmap_PageFaultHandler : public IEventListener_PageFault class mmap_PageFaultHandler : public EventListener_PageFault
{ {
protected: protected:
void OnPageFaultEvent( const PageFaultInfo& info, bool& handled ); void OnPageFaultEvent( const PageFaultInfo& info, bool& handled );

View File

@ -19,9 +19,14 @@
#include "App.h" #include "App.h"
#include "HostGui.h" #include "HostGui.h"
#include "AppSaveStates.h"
#include "Utilities/EventSource.inl"
class _BaseStateThread; class _BaseStateThread;
template EventSource<IEventListener_SaveStateThread>;
static EventSource<IEventListener_SaveStateThread> m_evtsrc_SaveState;
// Used to hold the current state backup (fullcopy of PS2 memory and plugin states). // Used to hold the current state backup (fullcopy of PS2 memory and plugin states).
static SafeArray<u8> state_buffer; static SafeArray<u8> state_buffer;
@ -30,6 +35,10 @@ _BaseStateThread* current_state_thread = NULL;
// Simple lock boolean for the state buffer being in use by a thread. // Simple lock boolean for the state buffer being in use by a thread.
static NonblockingMutex state_buffer_lock; static NonblockingMutex state_buffer_lock;
// This boolean tracks if a savestate is actively saving. When a state is saving we
// typically delay program termination to allow th state time to finish it's work.
static bool state_is_saving = false;
// This boolean is to keep the system from resuming emulation until the current state has completely // This boolean is to keep the system from resuming emulation until the current state has completely
// uploaded or downloaded itself. It is only modified from the main thread, and should only be read // uploaded or downloaded itself. It is only modified from the main thread, and should only be read
// from the main thread. // from the main thread.
@ -44,32 +53,8 @@ static bool StateCopy_ForceClear()
state_buffer.Dispose(); state_buffer.Dispose();
} }
class EventListener_AppExiting : public IEventListener_AppStatus
{
protected:
PersistentThread& m_thread;
public:
EventListener_AppExiting( PersistentThread& thr )
: m_thread( thr )
{
}
virtual ~EventListener_AppExiting() throw() {}
};
enum
{
StateThreadAction_None = 0,
StateThreadAction_Create,
StateThreadAction_Restore,
StateThreadAction_ZipToDisk,
StateThreadAction_UnzipFromDisk,
};
class _BaseStateThread : public PersistentThread, class _BaseStateThread : public PersistentThread,
public virtual IEventListener_AppStatus, public virtual EventListener_AppStatus,
public virtual IDeletableObject public virtual IDeletableObject
{ {
typedef PersistentThread _parent; typedef PersistentThread _parent;
@ -93,6 +78,8 @@ public:
current_state_thread = NULL; current_state_thread = NULL;
state_buffer_lock.Release(); // just in case; state_buffer_lock.Release(); // just in case;
} }
virtual bool IsFreezing() const=0;
protected: protected:
_BaseStateThread( const char* name, FnType_OnThreadComplete* onFinished ) _BaseStateThread( const char* name, FnType_OnThreadComplete* onFinished )
@ -121,10 +108,7 @@ protected:
void AppStatusEvent_OnExit() void AppStatusEvent_OnExit()
{ {
Cancel(); Cancel();
wxGetApp().DeleteObject( this );
Pcsx2App& myapp( wxGetApp() );
myapp.RemoveListener( *this );
myapp.DeleteObject( *this );
} }
}; };
@ -142,6 +126,8 @@ public:
throw Exception::RuntimeError( L"Cannot complete state freeze request; the virtual machine state is reset.", _("You'll need to start a new virtual machine before you can save its state.") ); throw Exception::RuntimeError( L"Cannot complete state freeze request; the virtual machine state is reset.", _("You'll need to start a new virtual machine before you can save its state.") );
} }
bool IsFreezing() const { return true; }
protected: protected:
void OnStart() void OnStart()
{ {
@ -157,7 +143,7 @@ protected:
void OnCleanupInThread() void OnCleanupInThread()
{ {
SendFinishEvent( StateThreadAction_Create ); SendFinishEvent( SaveStateAction_CreateFinished );
_parent::OnCleanupInThread(); _parent::OnCleanupInThread();
} }
}; };
@ -186,6 +172,8 @@ public:
{ {
if( m_gzfp != NULL ) gzclose( m_gzfp ); if( m_gzfp != NULL ) gzclose( m_gzfp );
} }
bool IsFreezing() const { return true; }
protected: protected:
void OnStart() void OnStart()
@ -208,13 +196,15 @@ protected:
if( gzwrite( m_gzfp, state_buffer.GetPtr(curidx), thisBlockSize ) < thisBlockSize ) if( gzwrite( m_gzfp, state_buffer.GetPtr(curidx), thisBlockSize ) < thisBlockSize )
throw Exception::BadStream( m_filename ); throw Exception::BadStream( m_filename );
curidx += thisBlockSize; curidx += thisBlockSize;
Yield( 1 ); Yield( 10 );
} while( curidx < state_buffer.GetSizeInBytes() ); } while( curidx < state_buffer.GetSizeInBytes() );
Console.WriteLn( "State saved to disk without error." );
} }
void OnCleanupInThread() void OnCleanupInThread()
{ {
SendFinishEvent( StateThreadAction_ZipToDisk ); SendFinishEvent( SaveStateAction_ZipToDiskFinished );
_parent::OnCleanupInThread(); _parent::OnCleanupInThread();
} }
}; };
@ -250,6 +240,8 @@ public:
if( m_gzfp != NULL ) gzclose( m_gzfp ); if( m_gzfp != NULL ) gzclose( m_gzfp );
} }
bool IsFreezing() const { return false; }
protected: protected:
void OnStart() void OnStart()
{ {
@ -281,11 +273,12 @@ protected:
void OnCleanupInThread() void OnCleanupInThread()
{ {
SendFinishEvent( StateThreadAction_UnzipFromDisk ); SendFinishEvent( SaveStateAction_UnzipFromDiskFinished );
_parent::OnCleanupInThread(); _parent::OnCleanupInThread();
} }
}; };
void Pcsx2App::OnFreezeThreadFinished( wxCommandEvent& evt ) void Pcsx2App::OnFreezeThreadFinished( wxCommandEvent& evt )
{ {
// clear the OnFreezeFinished to NULL now, in case of error. // clear the OnFreezeFinished to NULL now, in case of error.
@ -296,8 +289,13 @@ void Pcsx2App::OnFreezeThreadFinished( wxCommandEvent& evt )
{ {
ScopedPtr<PersistentThread> thr( (PersistentThread*)evt.GetClientData() ); ScopedPtr<PersistentThread> thr( (PersistentThread*)evt.GetClientData() );
if( !pxAssertDev( thr != NULL, "NULL thread handle on freeze finished?" ) ) return; if( !pxAssertDev( thr != NULL, "NULL thread handle on freeze finished?" ) ) return;
current_state_thread = NULL;
state_buffer_lock.Release(); state_buffer_lock.Release();
--sys_resume_lock; --sys_resume_lock;
m_evtsrc_SaveState.Dispatch( (SaveStateActionType)evt.GetInt() );
thr->RethrowException(); thr->RethrowException();
} }
@ -314,7 +312,7 @@ static wxString zip_dest_filename;
static void OnFinished_ZipToDisk( const wxCommandEvent& evt ) static void OnFinished_ZipToDisk( const wxCommandEvent& evt )
{ {
if( !pxAssertDev( evt.GetInt() == StateThreadAction_Create, "Unexpected StateThreadAction value, aborting save." ) ) return; if( !pxAssertDev( evt.GetInt() == SaveStateAction_CreateFinished, "Unexpected StateThreadAction value, aborting save." ) ) return;
if( zip_dest_filename.IsEmpty() ) if( zip_dest_filename.IsEmpty() )
{ {
@ -328,11 +326,80 @@ static void OnFinished_ZipToDisk( const wxCommandEvent& evt )
CoreThread.Resume(); CoreThread.Resume();
} }
class InvokeAction_WhenSaveComplete :
public IEventListener_SaveStateThread,
public IDeletableObject
{
protected:
IActionInvocation* m_action;
public:
InvokeAction_WhenSaveComplete( IActionInvocation* action )
{
m_action = action;
}
virtual ~InvokeAction_WhenSaveComplete() throw() {}
void SaveStateAction_OnZipToDiskFinished()
{
if( m_action )
{
m_action->InvokeAction();
safe_delete( m_action );
}
wxGetApp().DeleteObject( this );
}
};
class InvokeAction_WhenStateCopyComplete : public InvokeAction_WhenSaveComplete
{
public:
InvokeAction_WhenStateCopyComplete( IActionInvocation* action )
: InvokeAction_WhenSaveComplete( action )
{
}
virtual ~InvokeAction_WhenStateCopyComplete() throw() {}
void SaveStateAction_OnCreateFinished()
{
SaveStateAction_OnZipToDiskFinished();
}
};
// ===================================================================================================== // =====================================================================================================
// StateCopy Public Interface // StateCopy Public Interface
// ===================================================================================================== // =====================================================================================================
bool StateCopy_InvokeOnSaveComplete( IActionInvocation* sst )
{
AffinityAssert_AllowFromMain();
if( current_state_thread == NULL || !current_state_thread->IsFreezing() )
{
delete sst;
return false;
}
m_evtsrc_SaveState.Add( new InvokeAction_WhenSaveComplete( sst ) );
return true;
}
bool StateCopy_InvokeOnCopyComplete( IActionInvocation* sst )
{
AffinityAssert_AllowFromMain();
if( current_state_thread == NULL || !current_state_thread->IsFreezing() )
{
delete sst;
return false;
}
m_evtsrc_SaveState.Add( new InvokeAction_WhenStateCopyComplete( sst ) );
return true;
}
void StateCopy_SaveToFile( const wxString& file ) void StateCopy_SaveToFile( const wxString& file )
{ {
if( state_buffer_lock.IsLocked() ) return; if( state_buffer_lock.IsLocked() ) return;

View File

@ -15,7 +15,6 @@
#pragma once #pragma once
// This shouldn't break Win compiles, but it does.
#include "PS2Edefs.h" #include "PS2Edefs.h"
#include "System.h" #include "System.h"
@ -253,17 +252,3 @@ public:
bool IsFinished() const { return m_idx >= m_memory.GetSizeInBytes(); } bool IsFinished() const { return m_idx >= m_memory.GetSizeInBytes(); }
}; };
extern bool StateCopy_IsValid();
extern void StateCopy_FreezeToMem();
extern void StateCopy_FreezeToMem_Blocking();
extern void StateCopy_ThawFromMem_Blocking();
extern void StateCopy_SaveToFile( const wxString& file );
extern void StateCopy_LoadFromFile( const wxString& file );
extern void StateCopy_SaveToSlot( uint num );
extern void StateCopy_LoadFromSlot( uint slot );
extern void StateCopy_Clear();
extern bool StateCopy_IsBusy();
extern const SafeArray<u8>* StateCopy_GetBuffer();

View File

@ -26,12 +26,12 @@ template class EventSource< IEventListener_PageFault >;
SrcType_PageFault Source_PageFault; SrcType_PageFault Source_PageFault;
IEventListener_PageFault::IEventListener_PageFault() EventListener_PageFault::EventListener_PageFault()
{ {
Source_PageFault.Add( *this ); Source_PageFault.Add( *this );
} }
IEventListener_PageFault::~IEventListener_PageFault() throw() EventListener_PageFault::~EventListener_PageFault() throw()
{ {
Source_PageFault.Remove( *this ); Source_PageFault.Remove( *this );
} }

View File

@ -42,8 +42,7 @@ public:
typedef PageFaultInfo EvtParams; typedef PageFaultInfo EvtParams;
public: public:
IEventListener_PageFault(); virtual ~IEventListener_PageFault() throw() {}
virtual ~IEventListener_PageFault() throw();
virtual void DispatchEvent( const PageFaultInfo& evtinfo, bool& handled ) virtual void DispatchEvent( const PageFaultInfo& evtinfo, bool& handled )
{ {
@ -59,6 +58,13 @@ protected:
virtual void OnPageFaultEvent( const PageFaultInfo& evtinfo, bool& handled ) {} virtual void OnPageFaultEvent( const PageFaultInfo& evtinfo, bool& handled ) {}
}; };
class EventListener_PageFault : public IEventListener_PageFault
{
public:
EventListener_PageFault();
virtual ~EventListener_PageFault() throw();
};
class SrcType_PageFault : public EventSource<IEventListener_PageFault> class SrcType_PageFault : public EventSource<IEventListener_PageFault>
{ {
protected: protected:

View File

@ -269,19 +269,6 @@ void SysCoreThread::CpuInitializeMess()
{ {
if( m_hasValidState ) return; if( m_hasValidState ) return;
if( StateCopy_IsValid() )
{
// Automatic recovery system if a state exists in memory. This is executed here
// in order to ensure the plugins are in the proper (loaded/opened) state.
SysClearExecutionCache();
StateCopy_ThawFromMem_Blocking();
m_hasValidState = true;
m_resetVirtualMachine = false;
return;
}
_reset_stuff_as_needed(); _reset_stuff_as_needed();
ScopedBool_ClearOnError sbcoe( m_hasValidState ); ScopedBool_ClearOnError sbcoe( m_hasValidState );

View File

@ -215,9 +215,9 @@ public:
virtual void ChangeCdvdSource( CDVD_SourceType type ); virtual void ChangeCdvdSource( CDVD_SourceType type );
protected: protected:
void CpuInitializeMess();
void _reset_stuff_as_needed(); void _reset_stuff_as_needed();
virtual void CpuInitializeMess();
virtual void Start(); virtual void Start();
virtual void OnSuspendInThread(); virtual void OnSuspendInThread();
virtual void OnPauseInThread() {} virtual void OnPauseInThread() {}

View File

@ -510,7 +510,7 @@ public:
void DetectCpuAndUserMode(); void DetectCpuAndUserMode();
void OpenConsoleLog(); void OpenConsoleLog();
void OpenMainFrame(); void OpenMainFrame();
bool PrepForExit( bool canCancel ); void PrepForExit();
void CleanupRestartable(); void CleanupRestartable();
void CleanupResources(); void CleanupResources();
void WipeUserModeSettings(); void WipeUserModeSettings();
@ -635,6 +635,8 @@ protected:
virtual void DoCpuReset(); virtual void DoCpuReset();
virtual void DoThreadDeadlocked(); virtual void DoThreadDeadlocked();
virtual void CpuInitializeMess();
}; };
DECLARE_APP(Pcsx2App) DECLARE_APP(Pcsx2App)

View File

@ -48,7 +48,6 @@ void AppCoreThread::Reset()
void AppCoreThread::DoThreadDeadlocked() void AppCoreThread::DoThreadDeadlocked()
{ {
//wxGetApp().PostCommand( );
wxGetApp().DoStuckThread( *this ); wxGetApp().DoStuckThread( *this );
} }
@ -94,7 +93,7 @@ void AppCoreThread::Resume()
// Resume failed for some reason, so update GUI statuses and post a message to // Resume failed for some reason, so update GUI statuses and post a message to
// try again on the resume. // try again on the resume.
wxGetApp().PostCommand( pxEvt_CoreThreadStatus, CoreStatus_Suspended ); wxGetApp().PostCommand( pxEvt_CoreThreadStatus, CoreThread_Suspended );
if( (m_ExecMode != ExecMode_Closing) || (m_ExecMode != ExecMode_Pausing) ) if( (m_ExecMode != ExecMode_Closing) || (m_ExecMode != ExecMode_Pausing) )
{ {
@ -121,7 +120,7 @@ void AppCoreThread::ChangeCdvdSource( CDVD_SourceType type )
void AppCoreThread::DoCpuReset() void AppCoreThread::DoCpuReset()
{ {
wxGetApp().PostCommand( pxEvt_CoreThreadStatus, CoreStatus_Reset ); wxGetApp().PostCommand( pxEvt_CoreThreadStatus, CoreThread_Reset );
_parent::DoCpuReset(); _parent::DoCpuReset();
} }
@ -143,13 +142,13 @@ void AppCoreThread::OnResumeReady()
void AppCoreThread::OnResumeInThread( bool isSuspended ) void AppCoreThread::OnResumeInThread( bool isSuspended )
{ {
_parent::OnResumeInThread( isSuspended ); _parent::OnResumeInThread( isSuspended );
wxGetApp().PostCommand( pxEvt_CoreThreadStatus, CoreStatus_Resumed ); wxGetApp().PostCommand( pxEvt_CoreThreadStatus, CoreThread_Resumed );
} }
void AppCoreThread::OnSuspendInThread() void AppCoreThread::OnSuspendInThread()
{ {
_parent::OnSuspendInThread(); _parent::OnSuspendInThread();
wxGetApp().PostCommand( pxEvt_CoreThreadStatus, CoreStatus_Suspended ); wxGetApp().PostCommand( pxEvt_CoreThreadStatus, CoreThread_Suspended );
} }
// Called whenever the thread has terminated, for either regular or irregular reasons. // Called whenever the thread has terminated, for either regular or irregular reasons.
@ -158,7 +157,7 @@ void AppCoreThread::OnSuspendInThread()
// the new (lack of) thread status, so this posts a message to the App to do so. // the new (lack of) thread status, so this posts a message to the App to do so.
void AppCoreThread::OnCleanupInThread() void AppCoreThread::OnCleanupInThread()
{ {
wxGetApp().PostCommand( pxEvt_CoreThreadStatus, CoreStatus_Stopped ); wxGetApp().PostCommand( pxEvt_CoreThreadStatus, CoreThread_Stopped );
_parent::OnCleanupInThread(); _parent::OnCleanupInThread();
} }
@ -194,9 +193,30 @@ void AppCoreThread::ApplySettings( const Pcsx2Config& src )
_parent::ApplySettings( fixup ); _parent::ApplySettings( fixup );
} }
void AppCoreThread::CpuInitializeMess()
{
if( m_hasValidState ) return;
if( StateCopy_IsValid() )
{
// Automatic recovery system if a state exists in memory. This is executed here
// in order to ensure the plugins are in the proper (loaded/opened) state.
SysClearExecutionCache();
StateCopy_ThawFromMem_Blocking();
m_hasValidState = true;
m_resetVirtualMachine = false;
return;
}
_parent::CpuInitializeMess();
}
void AppCoreThread::ExecuteTaskInThread() void AppCoreThread::ExecuteTaskInThread()
{ {
wxGetApp().PostCommand( pxEvt_CoreThreadStatus, CoreStatus_Started ); wxGetApp().PostCommand( pxEvt_CoreThreadStatus, CoreThread_Started );
_parent::ExecuteTaskInThread(); _parent::ExecuteTaskInThread();
// ---------------------------------------------------------------------------- // ----------------------------------------------------------------------------

View File

@ -19,12 +19,12 @@
enum CoreThreadStatus enum CoreThreadStatus
{ {
CoreStatus_Indeterminate, CoreThread_Indeterminate,
CoreStatus_Started, CoreThread_Started,
CoreStatus_Resumed, CoreThread_Resumed,
CoreStatus_Suspended, CoreThread_Suspended,
CoreStatus_Reset, CoreThread_Reset,
CoreStatus_Stopped, CoreThread_Stopped,
}; };
enum AppEventType enum AppEventType
@ -37,14 +37,14 @@ enum AppEventType
enum PluginEventType enum PluginEventType
{ {
PluginsEvt_Loaded, CorePlugins_Loaded,
PluginsEvt_Init, CorePlugins_Init,
PluginsEvt_Opening, // dispatched prior to plugins being opened CorePlugins_Opening, // dispatched prior to plugins being opened
PluginsEvt_Opened, // dispatched after plugins are opened CorePlugins_Opened, // dispatched after plugins are opened
PluginsEvt_Closing, // dispatched prior to plugins being closed CorePlugins_Closing, // dispatched prior to plugins being closed
PluginsEvt_Closed, // dispatched after plugins are closed CorePlugins_Closed, // dispatched after plugins are closed
PluginsEvt_Shutdown, CorePlugins_Shutdown,
PluginsEvt_Unloaded, CorePlugins_Unloaded,
}; };
struct AppEventInfo struct AppEventInfo
@ -78,29 +78,23 @@ public:
typedef CoreThreadStatus EvtParams; typedef CoreThreadStatus EvtParams;
public: public:
IEventListener_CoreThread(); virtual ~IEventListener_CoreThread() throw() {}
virtual ~IEventListener_CoreThread() throw();
virtual void DispatchEvent( const CoreThreadStatus& status ) virtual void DispatchEvent( const CoreThreadStatus& status );
{
switch( status )
{
case CoreStatus_Indeterminate: OnCoreStatus_Indeterminate(); break;
case CoreStatus_Started: OnCoreStatus_Started(); break;
case CoreStatus_Resumed: OnCoreStatus_Resumed(); break;
case CoreStatus_Suspended: OnCoreStatus_Suspended(); break;
case CoreStatus_Reset: OnCoreStatus_Reset(); break;
case CoreStatus_Stopped: OnCoreStatus_Stopped(); break;
}
}
protected: protected:
virtual void OnCoreStatus_Indeterminate() {} virtual void CoreThread_OnStarted() {}
virtual void OnCoreStatus_Started() {} virtual void CoreThread_OnResumed() {}
virtual void OnCoreStatus_Resumed() {} virtual void CoreThread_OnSuspended() {}
virtual void OnCoreStatus_Suspended() {} virtual void CoreThread_OnReset() {}
virtual void OnCoreStatus_Reset() {} virtual void CoreThread_OnStopped() {}
virtual void OnCoreStatus_Stopped() {} };
class EventListener_CoreThread : public IEventListener_CoreThread
{
public:
EventListener_CoreThread();
virtual ~EventListener_CoreThread() throw();
}; };
// -------------------------------------------------------------------------------------- // --------------------------------------------------------------------------------------
@ -112,34 +106,26 @@ public:
typedef PluginEventType EvtParams; typedef PluginEventType EvtParams;
public: public:
IEventListener_Plugins(); virtual ~IEventListener_Plugins() throw() {}
virtual ~IEventListener_Plugins() throw();
virtual void DispatchEvent( const PluginEventType& pevt ) virtual void DispatchEvent( const PluginEventType& pevt );
{
switch( pevt )
{
case PluginsEvt_Loaded: OnPluginsEvt_Loaded(); break;
case PluginsEvt_Init: OnPluginsEvt_Init(); break;
case PluginsEvt_Opening: OnPluginsEvt_Opening(); break;
case PluginsEvt_Opened: OnPluginsEvt_Opened(); break;
case PluginsEvt_Closing: OnPluginsEvt_Closing(); break;
case PluginsEvt_Closed: OnPluginsEvt_Closed(); break;
case PluginsEvt_Shutdown: OnPluginsEvt_Shutdown(); break;
case PluginsEvt_Unloaded: OnPluginsEvt_Unloaded(); break;
}
}
protected: protected:
virtual void OnPluginsEvt_Loaded() {} virtual void CorePlugins_OnLoaded() {}
virtual void OnPluginsEvt_Init() {} virtual void CorePlugins_OnInit() {}
virtual void OnPluginsEvt_Opening() {} // dispatched prior to plugins being opened virtual void CorePlugins_OnOpening() {} // dispatched prior to plugins being opened
virtual void OnPluginsEvt_Opened() {} // dispatched after plugins are opened virtual void CorePlugins_OnOpened() {} // dispatched after plugins are opened
virtual void OnPluginsEvt_Closing() {} // dispatched prior to plugins being closed virtual void CorePlugins_OnClosing() {} // dispatched prior to plugins being closed
virtual void OnPluginsEvt_Closed() {} // dispatched after plugins are closed virtual void CorePlugins_OnClosed() {} // dispatched after plugins are closed
virtual void OnPluginsEvt_Shutdown() {} virtual void CorePlugins_OnShutdown() {}
virtual void OnPluginsEvt_Unloaded() {} virtual void CorePlugins_OnUnloaded() {}
};
class EventListener_Plugins : public IEventListener_Plugins
{
public:
EventListener_Plugins();
virtual ~EventListener_Plugins() throw();
}; };
// -------------------------------------------------------------------------------------- // --------------------------------------------------------------------------------------
@ -151,8 +137,7 @@ public:
typedef AppEventInfo EvtParams; typedef AppEventInfo EvtParams;
public: public:
IEventListener_AppStatus(); virtual ~IEventListener_AppStatus() throw() {}
virtual ~IEventListener_AppStatus() throw();
virtual void DispatchEvent( const AppEventInfo& evtinfo ); virtual void DispatchEvent( const AppEventInfo& evtinfo );
@ -162,6 +147,13 @@ protected:
virtual void AppStatusEvent_OnExit() {} virtual void AppStatusEvent_OnExit() {}
}; };
class EventListener_AppStatus : public IEventListener_AppStatus
{
public:
EventListener_AppStatus();
virtual ~EventListener_AppStatus() throw();
};
// -------------------------------------------------------------------------------------- // --------------------------------------------------------------------------------------
// EventListenerHelpers (CoreThread / Plugins / AppStatus) // EventListenerHelpers (CoreThread / Plugins / AppStatus)
// -------------------------------------------------------------------------------------- // --------------------------------------------------------------------------------------
@ -172,7 +164,7 @@ protected:
// //
template< typename TypeToDispatchTo > template< typename TypeToDispatchTo >
class EventListenerHelper_CoreThread : public IEventListener_CoreThread class EventListenerHelper_CoreThread : public EventListener_CoreThread
{ {
public: public:
TypeToDispatchTo& Owner; TypeToDispatchTo& Owner;
@ -190,16 +182,16 @@ public:
virtual ~EventListenerHelper_CoreThread() throw() {} virtual ~EventListenerHelper_CoreThread() throw() {}
protected: protected:
void OnCoreStatus_Indeterminate() { Owner.OnCoreStatus_Indeterminate(); } void OnCoreThread_Indeterminate() { Owner.OnCoreThread_Indeterminate(); }
void OnCoreStatus_Started() { Owner.OnCoreStatus_Started(); } void CoreThread_OnStarted() { Owner.OnCoreThread_Started(); }
void OnCoreStatus_Resumed() { Owner.OnCoreStatus_Resumed(); } void CoreThread_OnResumed() { Owner.OnCoreThread_Resumed(); }
void OnCoreStatus_Suspended() { Owner.OnCoreStatus_Suspended(); } void CoreThread_OnSuspended() { Owner.OnCoreThread_Suspended(); }
void OnCoreStatus_Reset() { Owner.OnCoreStatus_Reset(); } void CoreThread_OnReset() { Owner.OnCoreThread_Reset(); }
void OnCoreStatus_Stopped() { Owner.OnCoreStatus_Stopped(); } void CoreThread_OnStopped() { Owner.OnCoreThread_Stopped(); }
}; };
template< typename TypeToDispatchTo > template< typename TypeToDispatchTo >
class EventListenerHelper_Plugins : public IEventListener_Plugins class EventListenerHelper_Plugins : public EventListener_Plugins
{ {
public: public:
TypeToDispatchTo& Owner; TypeToDispatchTo& Owner;
@ -217,18 +209,18 @@ public:
virtual ~EventListenerHelper_Plugins() throw() {} virtual ~EventListenerHelper_Plugins() throw() {}
protected: protected:
void OnPluginsEvt_Loaded() { Owner.OnPluginsEvt_Loaded(); } void CorePlugins_OnLoaded() { Owner.OnCorePlugins_Loaded(); }
void OnPluginsEvt_Init() { Owner.OnPluginsEvt_Init(); } void CorePlugins_OnInit() { Owner.OnCorePlugins_Init(); }
void OnPluginsEvt_Opening() { Owner.OnPluginsEvt_Opening(); } void CorePlugins_OnOpening() { Owner.OnCorePlugins_Opening(); }
void OnPluginsEvt_Opened() { Owner.OnPluginsEvt_Opened(); } void CorePlugins_OnOpened() { Owner.OnCorePlugins_Opened(); }
void OnPluginsEvt_Closing() { Owner.OnPluginsEvt_Closing(); } void CorePlugins_OnClosing() { Owner.OnCorePlugins_Closing(); }
void OnPluginsEvt_Closed() { Owner.OnPluginsEvt_Closed(); } void CorePlugins_OnClosed() { Owner.OnCorePlugins_Closed(); }
void OnPluginsEvt_Shutdown() { Owner.OnPluginsEvt_Shutdown(); } void CorePlugins_OnShutdown() { Owner.OnCorePlugins_Shutdown(); }
void OnPluginsEvt_Unloaded() { Owner.OnPluginsEvt_Unloaded(); } void CorePlugins_OnUnloaded() { Owner.OnCorePlugins_Unloaded(); }
}; };
template< typename TypeToDispatchTo > template< typename TypeToDispatchTo >
class EventListenerHelper_AppStatus : public IEventListener_AppStatus class EventListenerHelper_AppStatus : public EventListener_AppStatus
{ {
public: public:
TypeToDispatchTo& Owner; TypeToDispatchTo& Owner;

View File

@ -28,32 +28,63 @@ AppSettingsEventInfo::AppSettingsEventInfo( IniInterface& ini )
{ {
} }
IEventListener_CoreThread::IEventListener_CoreThread() EventListener_CoreThread::EventListener_CoreThread()
{ {
wxGetApp().AddListener( this ); wxGetApp().AddListener( this );
} }
IEventListener_CoreThread::~IEventListener_CoreThread() throw() EventListener_CoreThread::~EventListener_CoreThread() throw()
{ {
wxGetApp().RemoveListener( this ); wxGetApp().RemoveListener( this );
} }
IEventListener_Plugins::IEventListener_Plugins() void IEventListener_CoreThread::DispatchEvent( const CoreThreadStatus& status )
{
switch( status )
{
case CoreThread_Started: CoreThread_OnStarted(); break;
case CoreThread_Resumed: CoreThread_OnResumed(); break;
case CoreThread_Suspended: CoreThread_OnSuspended(); break;
case CoreThread_Reset: CoreThread_OnReset(); break;
case CoreThread_Stopped: CoreThread_OnStopped(); break;
jNO_DEFAULT;
}
}
EventListener_Plugins::EventListener_Plugins()
{ {
wxGetApp().AddListener( this ); wxGetApp().AddListener( this );
} }
IEventListener_Plugins::~IEventListener_Plugins() throw() EventListener_Plugins::~EventListener_Plugins() throw()
{ {
wxGetApp().RemoveListener( this ); wxGetApp().RemoveListener( this );
} }
IEventListener_AppStatus::IEventListener_AppStatus() void IEventListener_Plugins::DispatchEvent( const PluginEventType& pevt )
{
switch( pevt )
{
case CorePlugins_Loaded: CorePlugins_OnLoaded(); break;
case CorePlugins_Init: CorePlugins_OnInit(); break;
case CorePlugins_Opening: CorePlugins_OnOpening(); break;
case CorePlugins_Opened: CorePlugins_OnOpened(); break;
case CorePlugins_Closing: CorePlugins_OnClosing(); break;
case CorePlugins_Closed: CorePlugins_OnClosed(); break;
case CorePlugins_Shutdown: CorePlugins_OnShutdown(); break;
case CorePlugins_Unloaded: CorePlugins_OnUnloaded(); break;
jNO_DEFAULT;
}
}
EventListener_AppStatus::EventListener_AppStatus()
{ {
wxGetApp().AddListener( this ); wxGetApp().AddListener( this );
} }
IEventListener_AppStatus::~IEventListener_AppStatus() throw() EventListener_AppStatus::~EventListener_AppStatus() throw()
{ {
wxGetApp().RemoveListener( this ); wxGetApp().RemoveListener( this );
} }
@ -68,6 +99,6 @@ void IEventListener_AppStatus::DispatchEvent( const AppEventInfo& evtinfo )
break; break;
case AppStatus_SettingsApplied: AppStatusEvent_OnSettingsApplied(); break; case AppStatus_SettingsApplied: AppStatusEvent_OnSettingsApplied(); break;
case AppStatus_Exiting: AppStatusEvent_OnExit(); break; case AppStatus_Exiting: AppStatusEvent_OnExit(); break;
} }
} }

View File

@ -17,7 +17,7 @@
#include "IniInterface.h" #include "IniInterface.h"
#include "MainFrame.h" #include "MainFrame.h"
#include "Plugins.h" #include "Plugins.h"
#include "SaveState.h" #include "AppSaveStates.h"
#include "ps2/BiosTools.h" #include "ps2/BiosTools.h"
#include "Dialogs/ModalPopups.h" #include "Dialogs/ModalPopups.h"
@ -41,7 +41,6 @@ DEFINE_EVENT_TYPE( pxEvt_InvokeMethod );
DEFINE_EVENT_TYPE( pxEvt_LogicalVsync ); DEFINE_EVENT_TYPE( pxEvt_LogicalVsync );
DEFINE_EVENT_TYPE( pxEvt_OpenModalDialog ); DEFINE_EVENT_TYPE( pxEvt_OpenModalDialog );
//DEFINE_EVENT_TYPE( pxEvt_OpenDialog_StuckThread );
bool UseAdminMode = false; bool UseAdminMode = false;
wxDirName SettingsFolder; wxDirName SettingsFolder;
@ -276,14 +275,14 @@ void Pcsx2App::OnCoreThreadStatus( wxCommandEvent& evt )
switch( status ) switch( status )
{ {
case CoreStatus_Started: case CoreThread_Started:
case CoreStatus_Reset: case CoreThread_Reset:
case CoreStatus_Stopped: case CoreThread_Stopped:
FpsManager.Reset(); FpsManager.Reset();
break; break;
case CoreStatus_Resumed: case CoreThread_Resumed:
case CoreStatus_Suspended: case CoreThread_Suspended:
FpsManager.Resume(); FpsManager.Resume();
break; break;
} }
@ -538,64 +537,22 @@ void Pcsx2App::HandleEvent(wxEvtHandler* handler, wxEventFunction func, wxEvent&
} }
} }
class CancelCoreThreadWhenSaveStateDone : public IEventListener_CoreThread,
public IDeletableObject
{
public:
virtual ~CancelCoreThreadWhenSaveStateDone() throw() {}
void OnCoreStatus_Resumed()
{
Pcsx2App& myapp( wxGetApp() );
myapp.DeleteObject( this );
myapp.PostMenuAction( MenuId_Exit );
}
};
// Common exit handler which can be called from any event (though really it should // Common exit handler which can be called from any event (though really it should
// be called only from CloseWindow handlers since that's the more appropriate way // be called only from CloseWindow handlers since that's the more appropriate way
// to handle cancelable window closures) // to handle cancelable window closures)
// //
// returns true if the app can close, or false if the close event was canceled by // returns true if the app can close, or false if the close event was canceled by
// the glorious user, whomever (s)he-it might be. // the glorious user, whomever (s)he-it might be.
bool Pcsx2App::PrepForExit( bool canCancel ) void Pcsx2App::PrepForExit()
{ {
// If a savestate is saving, we should wait until it finishes. Otherwise the user
// might lose data.
if( StateCopy_IsBusy() )
{
new CancelCoreThreadWhenSaveStateDone();
throw Exception::CancelEvent( "Savestate in progress, close event delayed until action is complete." );
}
CancelLoadingPlugins(); CancelLoadingPlugins();
/*
if( canCancel )
{
// TODO: Confirm with the user?
// Problem: Suspend is often slow because it needs to wait until the current EE frame
// has finished processing (if the GS or logging has incurred severe overhead this makes
// closing PCSX2 difficult). A non-blocking suspend with modal dialog might suffice
// however. --air
bool resume = CoreThread.Suspend();
if( false )
{
if(resume) CoreThread.Resume();
return false;
}
}*/
DispatchEvent( AppStatus_Exiting ); DispatchEvent( AppStatus_Exiting );
// This should be called by OnExit(), but sometimes wxWidgets fails to call OnExit(), so // This should be called by OnExit(), but sometimes wxWidgets fails to call OnExit(), so
// do it here just in case (no harm anyway -- OnExit is the next logical step after // do it here just in case (no harm anyway -- OnExit is the next logical step after
// CloseWindow returns true from the TopLevel window). // CloseWindow returns true from the TopLevel window).
CleanupRestartable(); CleanupRestartable();
return true;
} }
// This method generates debug assertions if the MainFrame handle is NULL (typically // This method generates debug assertions if the MainFrame handle is NULL (typically
@ -968,8 +925,8 @@ void Pcsx2App::OnSysExecute( wxCommandEvent& evt )
void Pcsx2App::SysReset() void Pcsx2App::SysReset()
{ {
StateCopy_Clear(); StateCopy_Clear();
CoreThread.Reset(); CoreThread.Reset();
CoreThread.Cancel();
CoreThread.ReleaseResumeLock(); CoreThread.ReleaseResumeLock();
m_CorePlugins = NULL; m_CorePlugins = NULL;
} }

77
pcsx2/gui/AppSaveStates.h Normal file
View File

@ -0,0 +1,77 @@
/* PCSX2 - PS2 Emulator for PCs
* Copyright (C) 2002-2009 PCSX2 Dev Team
*
* PCSX2 is free software: you can redistribute it and/or modify it under the terms
* of the GNU Lesser General Public License as published by the Free Software Found-
* ation, either version 3 of the License, or (at your option) any later version.
*
* PCSX2 is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
* PURPOSE. See the GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along with PCSX2.
* If not, see <http://www.gnu.org/licenses/>.
*/
#pragma once
#include "SaveState.h"
enum SaveStateActionType
{
SaveStateAction_CreateFinished,
SaveStateAction_RestoreFinished,
SaveStateAction_ZipToDiskFinished,
SaveStateAction_UnzipFromDiskFinished,
};
// --------------------------------------------------------------------------------------
// IEventListener_SaveStateThread
// --------------------------------------------------------------------------------------
class IEventListener_SaveStateThread : public IEventDispatcher<SaveStateActionType>
{
public:
typedef SaveStateActionType EvtParams;
public:
IEventListener_SaveStateThread() {}
virtual ~IEventListener_SaveStateThread() throw() {}
virtual void DispatchEvent( const SaveStateActionType& status )
{
switch( status )
{
case SaveStateAction_CreateFinished: SaveStateAction_OnCreateFinished(); break;
case SaveStateAction_RestoreFinished: SaveStateAction_OnRestoreFinished(); break;
case SaveStateAction_ZipToDiskFinished: SaveStateAction_OnZipToDiskFinished(); break;
case SaveStateAction_UnzipFromDiskFinished: SaveStateAction_OnUnzipFromDiskFinished(); break;
jNO_DEFAULT;
}
}
protected:
virtual void SaveStateAction_OnCreateFinished() {}
virtual void SaveStateAction_OnRestoreFinished() {}
virtual void SaveStateAction_OnZipToDiskFinished() {}
virtual void SaveStateAction_OnUnzipFromDiskFinished() {}
};
extern bool StateCopy_InvokeOnSaveComplete( IActionInvocation* sst );
extern bool StateCopy_InvokeOnCopyComplete( IActionInvocation* sst );
extern bool StateCopy_IsValid();
extern void StateCopy_FreezeToMem();
extern void StateCopy_FreezeToMem_Blocking();
extern void StateCopy_ThawFromMem_Blocking();
extern void StateCopy_SaveToFile( const wxString& file );
extern void StateCopy_LoadFromFile( const wxString& file );
extern void StateCopy_SaveToSlot( uint num );
extern void StateCopy_LoadFromSlot( uint slot );
extern void StateCopy_Clear();
extern bool StateCopy_IsBusy();
extern const SafeArray<u8>* StateCopy_GetBuffer();

View File

@ -90,8 +90,8 @@ public:
// pxLogTextCtrl // pxLogTextCtrl
// -------------------------------------------------------------------------------------- // --------------------------------------------------------------------------------------
class pxLogTextCtrl : public wxTextCtrl, class pxLogTextCtrl : public wxTextCtrl,
public IEventListener_CoreThread, public EventListener_CoreThread,
public IEventListener_Plugins public EventListener_Plugins
{ {
protected: protected:
//EventListenerHelper_CoreThread<pxLogTextCtrl> m_listener_CoreThread; //EventListenerHelper_CoreThread<pxLogTextCtrl> m_listener_CoreThread;

View File

@ -16,7 +16,7 @@
#include "PrecompiledHeader.h" #include "PrecompiledHeader.h"
#include "MainFrame.h" #include "MainFrame.h"
#include "HostGui.h" #include "HostGui.h"
#include "SaveState.h" #include "AppSaveStates.h"
#include "GS.h" #include "GS.h"
#include "Dump.h" #include "Dump.h"

View File

@ -15,6 +15,7 @@
#include "PrecompiledHeader.h" #include "PrecompiledHeader.h"
#include "MainFrame.h" #include "MainFrame.h"
#include "AppSaveStates.h"
#include "ConsoleLogger.h" #include "ConsoleLogger.h"
#include "MSWstuff.h" #include "MSWstuff.h"
@ -70,6 +71,8 @@ void MainEmuFrame::UpdateIsoSrcSelection()
// //
void MainEmuFrame::OnCloseWindow(wxCloseEvent& evt) void MainEmuFrame::OnCloseWindow(wxCloseEvent& evt)
{ {
CoreThread.Suspend();
bool isClosing = false; bool isClosing = false;
if( !evt.CanVeto() ) if( !evt.CanVeto() )
@ -79,10 +82,20 @@ void MainEmuFrame::OnCloseWindow(wxCloseEvent& evt)
} }
else else
{ {
isClosing = wxGetApp().PrepForExit( evt.CanVeto() ); // TODO : Add confirmation prior to exit here!
if( !isClosing ) evt.Veto( true ); // Problem: Suspend is often slow because it needs to wait until the current EE frame
// has finished processing (if the GS or logging has incurred severe overhead this makes
// closing PCSX2 difficult). A non-blocking suspend with modal dialog might suffice
// however. --air
if( StateCopy_InvokeOnSaveComplete( new InvokeAction_MenuCommand( MenuId_Exit ) ) ) return;
} }
if( isClosing )
wxGetApp().PrepForExit();
else
evt.Veto( true );
sApp.OnMainFrameClosed(); sApp.OnMainFrameClosed();
evt.Skip(); evt.Skip();

View File

@ -20,6 +20,7 @@
#include <wx/docview.h> #include <wx/docview.h>
#include "App.h" #include "App.h"
#include "AppSaveStates.h"
enum LimiterModeType enum LimiterModeType
{ {
@ -33,7 +34,7 @@ extern LimiterModeType g_LimiterMode;
// -------------------------------------------------------------------------------------- // --------------------------------------------------------------------------------------
// GSPanel // GSPanel
// -------------------------------------------------------------------------------------- // --------------------------------------------------------------------------------------
class GSPanel : public wxWindow, public IEventListener_AppStatus class GSPanel : public wxWindow, public EventListener_AppStatus
{ {
typedef wxWindow _parent; typedef wxWindow _parent;
@ -71,7 +72,7 @@ protected:
// -------------------------------------------------------------------------------------- // --------------------------------------------------------------------------------------
// GSFrame // GSFrame
// -------------------------------------------------------------------------------------- // --------------------------------------------------------------------------------------
class GSFrame : public wxFrame, public IEventListener_AppStatus class GSFrame : public wxFrame, public EventListener_AppStatus
{ {
typedef wxFrame _parent; typedef wxFrame _parent;
@ -153,13 +154,30 @@ public:
operator const wxMenu*() const { return &MyMenu; } operator const wxMenu*() const { return &MyMenu; }
}; };
class InvokeAction_MenuCommand : public IActionInvocation
{
protected:
MenuIdentifiers m_menu_cmd;
public:
InvokeAction_MenuCommand( MenuIdentifiers menu_command )
{
m_menu_cmd = menu_command;
}
virtual void InvokeAction()
{
wxGetApp().PostMenuAction( m_menu_cmd );
}
};
// -------------------------------------------------------------------------------------- // --------------------------------------------------------------------------------------
// MainEmuFrame // MainEmuFrame
// -------------------------------------------------------------------------------------- // --------------------------------------------------------------------------------------
class MainEmuFrame : public wxFrame, class MainEmuFrame : public wxFrame,
public IEventListener_Plugins, public EventListener_Plugins,
public IEventListener_CoreThread, public EventListener_CoreThread,
public IEventListener_AppStatus public EventListener_AppStatus
{ {
protected: protected:
// EventListenerHelper_Plugins<MainEmuFrame> m_listener_plugins; // EventListenerHelper_Plugins<MainEmuFrame> m_listener_plugins;

View File

@ -68,9 +68,11 @@ static void WipeSettings()
// manually from explorer does work. Can't think of a good work-around at the moment. --air // manually from explorer does work. Can't think of a good work-around at the moment. --air
//wxRmdir( GetSettingsFolder().ToString() ); //wxRmdir( GetSettingsFolder().ToString() );
g_Conf = new AppConfig();
} }
class RestartEverything_WhenCoreThreadStops : public IEventListener_CoreThread, class RestartEverything_WhenCoreThreadStops : public EventListener_CoreThread,
public virtual IDeletableObject public virtual IDeletableObject
{ {
public: public:
@ -78,20 +80,21 @@ public:
virtual ~RestartEverything_WhenCoreThreadStops() throw() {} virtual ~RestartEverything_WhenCoreThreadStops() throw() {}
protected: protected:
virtual void OnCoreStatus_Stopped() virtual void CoreThread_OnStopped()
{ {
wxGetApp().DeleteObject( this ); wxGetApp().DeleteObject( this );
WipeSettings(); WipeSettings();
} }
}; };
class CancelCoreThread_WhenSaveStateDone : public IEventListener_CoreThread, class CancelCoreThread_WhenSaveStateDone :
public EventListener_CoreThread,
public IDeletableObject public IDeletableObject
{ {
public: public:
virtual ~CancelCoreThread_WhenSaveStateDone() throw() {} virtual ~CancelCoreThread_WhenSaveStateDone() throw() {}
void OnCoreStatus_Resumed() void CoreThread_OnResumed()
{ {
wxGetApp().DeleteObject( this ); wxGetApp().DeleteObject( this );
CoreThread.Cancel(); CoreThread.Cancel();
@ -336,7 +339,8 @@ void MainEmuFrame::Menu_SuspendResume_Click(wxCommandEvent &event)
void MainEmuFrame::Menu_SysReset_Click(wxCommandEvent &event) void MainEmuFrame::Menu_SysReset_Click(wxCommandEvent &event)
{ {
//if( !SysHasValidState() ) return; if( StateCopy_InvokeOnCopyComplete( new InvokeAction_MenuCommand(MenuId_Sys_Reset) ) ) return;
sApp.SysReset(); sApp.SysReset();
sApp.SysExecute(); sApp.SysExecute();
//GetMenuBar()->Enable( MenuId_Sys_Reset, true ); //GetMenuBar()->Enable( MenuId_Sys_Reset, true );
@ -344,7 +348,9 @@ void MainEmuFrame::Menu_SysReset_Click(wxCommandEvent &event)
void MainEmuFrame::Menu_SysShutdown_Click(wxCommandEvent &event) void MainEmuFrame::Menu_SysShutdown_Click(wxCommandEvent &event)
{ {
if( !SysHasValidState() ) return; if( !SysHasValidState() && g_plugins == NULL ) return;
if( StateCopy_InvokeOnCopyComplete( new InvokeAction_MenuCommand(MenuId_Sys_Shutdown) ) ) return;
sApp.SysReset(); sApp.SysReset();
GetMenuBar()->Enable( MenuId_Sys_Shutdown, false ); GetMenuBar()->Enable( MenuId_Sys_Shutdown, false );
} }

View File

@ -403,7 +403,7 @@ namespace Panels
// PluginSelectorPanel // PluginSelectorPanel
// -------------------------------------------------------------------------------------- // --------------------------------------------------------------------------------------
class PluginSelectorPanel: public BaseSelectorPanel, class PluginSelectorPanel: public BaseSelectorPanel,
public IEventListener_Plugins public EventListener_Plugins
{ {
protected: protected:
// ---------------------------------------------------------------------------- // ----------------------------------------------------------------------------

View File

@ -15,8 +15,8 @@
#include "PrecompiledHeader.h" #include "PrecompiledHeader.h"
#include "App.h" #include "App.h"
#include "AppSaveStates.h"
#include "Plugins.h" #include "Plugins.h"
#include "SaveState.h"
#include "Utilities/ScopedPtr.h" #include "Utilities/ScopedPtr.h"
#include "ConfigurationPanels.h" #include "ConfigurationPanels.h"
#include "Dialogs/ModalPopups.h" #include "Dialogs/ModalPopups.h"
@ -232,7 +232,7 @@ void Panels::PluginSelectorPanel::ComboBoxPanel::Reset()
// ===================================================================================================== // =====================================================================================================
void Panels::PluginSelectorPanel::DispatchEvent( const PluginEventType& evt ) void Panels::PluginSelectorPanel::DispatchEvent( const PluginEventType& evt )
{ {
if( (evt != PluginsEvt_Loaded) && (evt != PluginsEvt_Unloaded) ) return; // everything else we don't care about if( (evt != CorePlugins_Loaded) && (evt != CorePlugins_Unloaded) ) return; // everything else we don't care about
if( IsBeingDeleted() ) return; if( IsBeingDeleted() ) return;

View File

@ -54,29 +54,29 @@ public:
virtual ~AppPluginManager() throw() virtual ~AppPluginManager() throw()
{ {
sApp.PostPluginStatus( PluginsEvt_Unloaded ); sApp.PostPluginStatus( CorePlugins_Unloaded );
} }
void Init() void Init()
{ {
SetSettingsFolder( GetSettingsFolder().ToString() ); SetSettingsFolder( GetSettingsFolder().ToString() );
_parent::Init(); _parent::Init();
sApp.PostPluginStatus( PluginsEvt_Init ); sApp.PostPluginStatus( CorePlugins_Init );
} }
void Shutdown() void Shutdown()
{ {
_parent::Shutdown(); _parent::Shutdown();
sApp.PostPluginStatus( PluginsEvt_Shutdown ); sApp.PostPluginStatus( CorePlugins_Shutdown );
} }
void Close() void Close()
{ {
if( !NeedsClose() ) return; if( !NeedsClose() ) return;
sApp.PostPluginStatus( PluginsEvt_Closing ); sApp.PostPluginStatus( CorePlugins_Closing );
_parent::Close(); _parent::Close();
sApp.PostPluginStatus( PluginsEvt_Closed ); sApp.PostPluginStatus( CorePlugins_Closed );
} }
void Open() void Open()
@ -85,9 +85,9 @@ public:
if( !NeedsOpen() ) return; if( !NeedsOpen() ) return;
sApp.PostPluginStatus( PluginsEvt_Opening ); sApp.PostPluginStatus( CorePlugins_Opening );
_parent::Open(); _parent::Open();
sApp.PostPluginStatus( PluginsEvt_Opened ); sApp.PostPluginStatus( CorePlugins_Opened );
} }
// Yay, this plugin is guaranteed to always be opened first and closed last. // Yay, this plugin is guaranteed to always be opened first and closed last.
@ -319,7 +319,7 @@ void Pcsx2App::OnLoadPluginsComplete( wxCommandEvent& evt )
if( fn_tmp != NULL ) fn_tmp( evt ); if( fn_tmp != NULL ) fn_tmp( evt );
PostPluginStatus( PluginsEvt_Loaded ); PostPluginStatus( CorePlugins_Loaded );
} }
void Pcsx2App::CancelLoadingPlugins() void Pcsx2App::CancelLoadingPlugins()

View File

@ -19,7 +19,7 @@
// RecentIsoManager // RecentIsoManager
// -------------------------------------------------------------------------------------- // --------------------------------------------------------------------------------------
class RecentIsoManager : public wxEvtHandler, class RecentIsoManager : public wxEvtHandler,
public IEventListener_AppStatus public EventListener_AppStatus
{ {
protected: protected:
struct RecentItem struct RecentItem

View File

@ -15,6 +15,7 @@
#include "PrecompiledHeader.h" #include "PrecompiledHeader.h"
#include "App.h" #include "App.h"
#include "AppSaveStates.h"
#include "Common.h" #include "Common.h"
#include "HostGui.h" #include "HostGui.h"
@ -24,12 +25,6 @@
StartupParams g_Startup; StartupParams g_Startup;
// Save state save-to-file (or slot) helpers.
void States_Save( const wxString& file )
{
StateCopy_SaveToFile( file );
}
// -------------------------------------------------------------------------------------- // --------------------------------------------------------------------------------------
// Saveslot Section // Saveslot Section
// -------------------------------------------------------------------------------------- // --------------------------------------------------------------------------------------

View File

@ -2559,6 +2559,10 @@
RelativePath="..\..\gui\ApplyState.h" RelativePath="..\..\gui\ApplyState.h"
> >
</File> </File>
<File
RelativePath="..\..\gui\AppSaveStates.h"
>
</File>
<File <File
RelativePath="..\..\gui\ConsoleLogger.h" RelativePath="..\..\gui\ConsoleLogger.h"
> >