mirror of https://github.com/PCSX2/pcsx2.git
Some missing svn:eol-style=native props. It's like they vanish into thin air these things.
git-svn-id: http://pcsx2.googlecode.com/svn/trunk@2981 96395faa-99c1-11dd-bbfe-3dabce05a288
This commit is contained in:
parent
02038a7dc1
commit
338cc07ce9
|
@ -1,52 +1,52 @@
|
|||
/* PCSX2 - PS2 Emulator for PCs
|
||||
* Copyright (C) 2002-2010 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 "AppCommon.h"
|
||||
|
||||
// --------------------------------------------------------------------------------------
|
||||
// AppPluginManager
|
||||
// --------------------------------------------------------------------------------------
|
||||
// This extension of PluginManager provides event listener sources for plugins -- loading,
|
||||
// unloading, open, close, shutdown, etc.
|
||||
//
|
||||
// FIXME : Should this be made part of the PCSX2 core emulation? (integrated into PluginManager)
|
||||
// I'm undecided on if it makes sense more in that context or in this one (interface).
|
||||
//
|
||||
class AppPluginManager : public PluginManager
|
||||
{
|
||||
typedef PluginManager _parent;
|
||||
|
||||
public:
|
||||
AppPluginManager();
|
||||
virtual ~AppPluginManager() throw();
|
||||
|
||||
void Load( const wxString (&folders)[PluginId_Count] );
|
||||
void Load( PluginsEnum_t pid, const wxString& srcfile );
|
||||
void Unload( PluginsEnum_t pid );
|
||||
void Unload();
|
||||
|
||||
void Init();
|
||||
void Init( PluginsEnum_t pid );
|
||||
void Shutdown( PluginsEnum_t pid );
|
||||
void Shutdown();
|
||||
void Close();
|
||||
void Open();
|
||||
|
||||
protected:
|
||||
bool OpenPlugin_GS();
|
||||
void ClosePlugin_GS();
|
||||
};
|
||||
/* PCSX2 - PS2 Emulator for PCs
|
||||
* Copyright (C) 2002-2010 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 "AppCommon.h"
|
||||
|
||||
// --------------------------------------------------------------------------------------
|
||||
// AppPluginManager
|
||||
// --------------------------------------------------------------------------------------
|
||||
// This extension of PluginManager provides event listener sources for plugins -- loading,
|
||||
// unloading, open, close, shutdown, etc.
|
||||
//
|
||||
// FIXME : Should this be made part of the PCSX2 core emulation? (integrated into PluginManager)
|
||||
// I'm undecided on if it makes sense more in that context or in this one (interface).
|
||||
//
|
||||
class AppPluginManager : public PluginManager
|
||||
{
|
||||
typedef PluginManager _parent;
|
||||
|
||||
public:
|
||||
AppPluginManager();
|
||||
virtual ~AppPluginManager() throw();
|
||||
|
||||
void Load( const wxString (&folders)[PluginId_Count] );
|
||||
void Load( PluginsEnum_t pid, const wxString& srcfile );
|
||||
void Unload( PluginsEnum_t pid );
|
||||
void Unload();
|
||||
|
||||
void Init();
|
||||
void Init( PluginsEnum_t pid );
|
||||
void Shutdown( PluginsEnum_t pid );
|
||||
void Shutdown();
|
||||
void Close();
|
||||
void Open();
|
||||
|
||||
protected:
|
||||
bool OpenPlugin_GS();
|
||||
void ClosePlugin_GS();
|
||||
};
|
||||
|
|
|
@ -1,236 +1,236 @@
|
|||
/* PCSX2 - PS2 Emulator for PCs
|
||||
* Copyright (C) 2002-2010 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 "System/SysThreads.h"
|
||||
#include "AppCommon.h"
|
||||
#include "AppCorePlugins.h"
|
||||
#include "SaveState.h"
|
||||
|
||||
#define AffinityAssert_AllowFrom_CoreThread() \
|
||||
pxAssertMsg( GetCoreThread().IsSelf(), "Thread affinity violation: Call allowed from SysCoreThread only." )
|
||||
|
||||
#define AffinityAssert_DisallowFrom_CoreThread() \
|
||||
pxAssertMsg( !GetCoreThread().IsSelf(), "Thread affinity violation: Call is *not* allowed from SysCoreThread." )
|
||||
|
||||
class IScopedCoreThread;
|
||||
class BaseScopedCoreThread;
|
||||
|
||||
enum ScopedCoreResumeType
|
||||
{
|
||||
ScopedCore_BlockingResume
|
||||
, ScopedCore_NonblockingResume
|
||||
, ScopedCore_SkipResume
|
||||
};
|
||||
|
||||
|
||||
// --------------------------------------------------------------------------------------
|
||||
// BaseSysExecEvent_ScopedCore
|
||||
// --------------------------------------------------------------------------------------
|
||||
class BaseSysExecEvent_ScopedCore : public SysExecEvent
|
||||
{
|
||||
protected:
|
||||
SynchronousActionState* m_resume;
|
||||
Threading::Mutex* m_mtx_resume;
|
||||
|
||||
public:
|
||||
virtual ~BaseSysExecEvent_ScopedCore() throw() {}
|
||||
|
||||
BaseSysExecEvent_ScopedCore& SetResumeStates( SynchronousActionState* sync, Threading::Mutex* mutex )
|
||||
{
|
||||
m_resume = sync;
|
||||
m_mtx_resume = mutex;
|
||||
return *this;
|
||||
}
|
||||
|
||||
BaseSysExecEvent_ScopedCore& SetResumeStates( SynchronousActionState& sync, Threading::Mutex& mutex )
|
||||
{
|
||||
m_resume = &sync;
|
||||
m_mtx_resume = &mutex;
|
||||
return *this;
|
||||
}
|
||||
|
||||
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 );
|
||||
|
||||
virtual void DoScopedTask() {}
|
||||
};
|
||||
|
||||
|
||||
// --------------------------------------------------------------------------------------
|
||||
// SysExecEvent_CoreThreadClose
|
||||
// --------------------------------------------------------------------------------------
|
||||
class SysExecEvent_CoreThreadClose : public BaseSysExecEvent_ScopedCore
|
||||
{
|
||||
public:
|
||||
wxString GetEventName() const { return L"CloseCoreThread"; }
|
||||
|
||||
virtual ~SysExecEvent_CoreThreadClose() throw() {}
|
||||
SysExecEvent_CoreThreadClose* Clone() const { return new SysExecEvent_CoreThreadClose( *this ); }
|
||||
|
||||
SysExecEvent_CoreThreadClose( SynchronousActionState* sync=NULL, SynchronousActionState* resume_sync=NULL, Threading::Mutex* mtx_resume=NULL )
|
||||
: BaseSysExecEvent_ScopedCore( sync, resume_sync, mtx_resume ) { }
|
||||
|
||||
protected:
|
||||
void InvokeEvent();
|
||||
};
|
||||
|
||||
// --------------------------------------------------------------------------------------
|
||||
// SysExecEvent_CoreThreadPause
|
||||
// --------------------------------------------------------------------------------------
|
||||
class SysExecEvent_CoreThreadPause : public BaseSysExecEvent_ScopedCore
|
||||
{
|
||||
public:
|
||||
wxString GetEventName() const { return L"PauseCoreThread"; }
|
||||
|
||||
virtual ~SysExecEvent_CoreThreadPause() throw() {}
|
||||
SysExecEvent_CoreThreadPause* Clone() const { return new SysExecEvent_CoreThreadPause( *this ); }
|
||||
|
||||
SysExecEvent_CoreThreadPause( SynchronousActionState* sync=NULL, SynchronousActionState* resume_sync=NULL, Threading::Mutex* mtx_resume=NULL )
|
||||
: BaseSysExecEvent_ScopedCore( sync, resume_sync, mtx_resume ) { }
|
||||
|
||||
protected:
|
||||
void InvokeEvent();
|
||||
};
|
||||
|
||||
// --------------------------------------------------------------------------------------
|
||||
// AppCoreThread class
|
||||
// --------------------------------------------------------------------------------------
|
||||
class AppCoreThread : public SysCoreThread
|
||||
{
|
||||
typedef SysCoreThread _parent;
|
||||
|
||||
public:
|
||||
AppCoreThread();
|
||||
virtual ~AppCoreThread() throw();
|
||||
|
||||
virtual void Suspend( bool isBlocking=false );
|
||||
virtual void Resume();
|
||||
virtual void Shutdown();
|
||||
virtual void Cancel( bool isBlocking=true );
|
||||
virtual void StateCheckInThread();
|
||||
virtual void ChangeCdvdSource();
|
||||
|
||||
virtual void ApplySettings( const Pcsx2Config& src );
|
||||
virtual void UploadStateCopy( const VmStateBuffer& copy );
|
||||
|
||||
protected:
|
||||
virtual void OnResumeReady();
|
||||
virtual void OnResumeInThread( bool IsSuspended );
|
||||
virtual void OnSuspendInThread();
|
||||
virtual void OnCleanupInThread();
|
||||
virtual void PostVsyncToUI();
|
||||
virtual void ExecuteTaskInThread();
|
||||
virtual void DoCpuReset();
|
||||
};
|
||||
|
||||
// --------------------------------------------------------------------------------------
|
||||
// IScopedCoreThread / BaseScopedCoreThread
|
||||
// --------------------------------------------------------------------------------------
|
||||
class IScopedCoreThread
|
||||
{
|
||||
protected:
|
||||
IScopedCoreThread() {}
|
||||
|
||||
public:
|
||||
virtual ~IScopedCoreThread() throw() {};
|
||||
virtual void AllowResume()=0;
|
||||
virtual void DisallowResume()=0;
|
||||
};
|
||||
|
||||
class BaseScopedCoreThread : public IScopedCoreThread
|
||||
{
|
||||
DeclareNoncopyableObject( BaseScopedCoreThread );
|
||||
|
||||
protected:
|
||||
bool m_allowResume;
|
||||
bool m_alreadyStopped;
|
||||
bool m_alreadyScoped;
|
||||
SynchronousActionState m_sync;
|
||||
SynchronousActionState m_sync_resume;
|
||||
Threading::Mutex m_mtx_resume;
|
||||
|
||||
BaseScopedCoreThread();
|
||||
|
||||
public:
|
||||
virtual ~BaseScopedCoreThread() throw()=0;
|
||||
virtual void AllowResume();
|
||||
virtual void DisallowResume();
|
||||
|
||||
virtual bool PostToSysExec( BaseSysExecEvent_ScopedCore* msg );
|
||||
|
||||
protected:
|
||||
// Called from destructors -- do not make virtual!!
|
||||
void DoResume();
|
||||
};
|
||||
|
||||
// --------------------------------------------------------------------------------------
|
||||
// ScopedCoreThreadClose / ScopedCoreThreadPause / ScopedCoreThreadPopup
|
||||
// --------------------------------------------------------------------------------------
|
||||
// This class behaves a bit differently from other scoped classes due to the "standard"
|
||||
// assumption that we actually do *not* want to resume CoreThread operations when an
|
||||
// exception occurs. Because of this, the destructor of this class does *not* unroll the
|
||||
// suspend operation. Instead you must manually instruct the class to resume using a call
|
||||
// to the provisioned AllowResume() method.
|
||||
//
|
||||
// If the class leaves scope without having been resumed, a log is written to the console.
|
||||
// This can be useful for troubleshooting, and also allows the log a second line of info
|
||||
// indicating the status of CoreThread execution at the time of the exception.
|
||||
//
|
||||
// ScopedCoreThreadPopup is intended for use where message boxes are popped up to the user.
|
||||
// The old style GUI (without GSopen2) must use a full close of the CoreThread, in order to
|
||||
// ensure that the GS window isn't blocking the popup, and to avoid crashes if the GS window
|
||||
// is maximized or fullscreen.
|
||||
//
|
||||
class ScopedCoreThreadClose : public BaseScopedCoreThread
|
||||
{
|
||||
typedef BaseScopedCoreThread _parent;
|
||||
|
||||
public:
|
||||
ScopedCoreThreadClose();
|
||||
virtual ~ScopedCoreThreadClose() throw();
|
||||
|
||||
void LoadPlugins();
|
||||
};
|
||||
|
||||
struct ScopedCoreThreadPause : public BaseScopedCoreThread
|
||||
{
|
||||
typedef BaseScopedCoreThread _parent;
|
||||
|
||||
public:
|
||||
ScopedCoreThreadPause( BaseSysExecEvent_ScopedCore* abuse_me=NULL );
|
||||
virtual ~ScopedCoreThreadPause() throw();
|
||||
};
|
||||
|
||||
struct ScopedCoreThreadPopup : public IScopedCoreThread
|
||||
{
|
||||
protected:
|
||||
ScopedPtr<BaseScopedCoreThread> m_scoped_core;
|
||||
|
||||
public:
|
||||
ScopedCoreThreadPopup();
|
||||
virtual ~ScopedCoreThreadPopup() throw() {}
|
||||
|
||||
virtual void AllowResume();
|
||||
virtual void DisallowResume();
|
||||
};
|
||||
/* PCSX2 - PS2 Emulator for PCs
|
||||
* Copyright (C) 2002-2010 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 "System/SysThreads.h"
|
||||
#include "AppCommon.h"
|
||||
#include "AppCorePlugins.h"
|
||||
#include "SaveState.h"
|
||||
|
||||
#define AffinityAssert_AllowFrom_CoreThread() \
|
||||
pxAssertMsg( GetCoreThread().IsSelf(), "Thread affinity violation: Call allowed from SysCoreThread only." )
|
||||
|
||||
#define AffinityAssert_DisallowFrom_CoreThread() \
|
||||
pxAssertMsg( !GetCoreThread().IsSelf(), "Thread affinity violation: Call is *not* allowed from SysCoreThread." )
|
||||
|
||||
class IScopedCoreThread;
|
||||
class BaseScopedCoreThread;
|
||||
|
||||
enum ScopedCoreResumeType
|
||||
{
|
||||
ScopedCore_BlockingResume
|
||||
, ScopedCore_NonblockingResume
|
||||
, ScopedCore_SkipResume
|
||||
};
|
||||
|
||||
|
||||
// --------------------------------------------------------------------------------------
|
||||
// BaseSysExecEvent_ScopedCore
|
||||
// --------------------------------------------------------------------------------------
|
||||
class BaseSysExecEvent_ScopedCore : public SysExecEvent
|
||||
{
|
||||
protected:
|
||||
SynchronousActionState* m_resume;
|
||||
Threading::Mutex* m_mtx_resume;
|
||||
|
||||
public:
|
||||
virtual ~BaseSysExecEvent_ScopedCore() throw() {}
|
||||
|
||||
BaseSysExecEvent_ScopedCore& SetResumeStates( SynchronousActionState* sync, Threading::Mutex* mutex )
|
||||
{
|
||||
m_resume = sync;
|
||||
m_mtx_resume = mutex;
|
||||
return *this;
|
||||
}
|
||||
|
||||
BaseSysExecEvent_ScopedCore& SetResumeStates( SynchronousActionState& sync, Threading::Mutex& mutex )
|
||||
{
|
||||
m_resume = &sync;
|
||||
m_mtx_resume = &mutex;
|
||||
return *this;
|
||||
}
|
||||
|
||||
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 );
|
||||
|
||||
virtual void DoScopedTask() {}
|
||||
};
|
||||
|
||||
|
||||
// --------------------------------------------------------------------------------------
|
||||
// SysExecEvent_CoreThreadClose
|
||||
// --------------------------------------------------------------------------------------
|
||||
class SysExecEvent_CoreThreadClose : public BaseSysExecEvent_ScopedCore
|
||||
{
|
||||
public:
|
||||
wxString GetEventName() const { return L"CloseCoreThread"; }
|
||||
|
||||
virtual ~SysExecEvent_CoreThreadClose() throw() {}
|
||||
SysExecEvent_CoreThreadClose* Clone() const { return new SysExecEvent_CoreThreadClose( *this ); }
|
||||
|
||||
SysExecEvent_CoreThreadClose( SynchronousActionState* sync=NULL, SynchronousActionState* resume_sync=NULL, Threading::Mutex* mtx_resume=NULL )
|
||||
: BaseSysExecEvent_ScopedCore( sync, resume_sync, mtx_resume ) { }
|
||||
|
||||
protected:
|
||||
void InvokeEvent();
|
||||
};
|
||||
|
||||
// --------------------------------------------------------------------------------------
|
||||
// SysExecEvent_CoreThreadPause
|
||||
// --------------------------------------------------------------------------------------
|
||||
class SysExecEvent_CoreThreadPause : public BaseSysExecEvent_ScopedCore
|
||||
{
|
||||
public:
|
||||
wxString GetEventName() const { return L"PauseCoreThread"; }
|
||||
|
||||
virtual ~SysExecEvent_CoreThreadPause() throw() {}
|
||||
SysExecEvent_CoreThreadPause* Clone() const { return new SysExecEvent_CoreThreadPause( *this ); }
|
||||
|
||||
SysExecEvent_CoreThreadPause( SynchronousActionState* sync=NULL, SynchronousActionState* resume_sync=NULL, Threading::Mutex* mtx_resume=NULL )
|
||||
: BaseSysExecEvent_ScopedCore( sync, resume_sync, mtx_resume ) { }
|
||||
|
||||
protected:
|
||||
void InvokeEvent();
|
||||
};
|
||||
|
||||
// --------------------------------------------------------------------------------------
|
||||
// AppCoreThread class
|
||||
// --------------------------------------------------------------------------------------
|
||||
class AppCoreThread : public SysCoreThread
|
||||
{
|
||||
typedef SysCoreThread _parent;
|
||||
|
||||
public:
|
||||
AppCoreThread();
|
||||
virtual ~AppCoreThread() throw();
|
||||
|
||||
virtual void Suspend( bool isBlocking=false );
|
||||
virtual void Resume();
|
||||
virtual void Shutdown();
|
||||
virtual void Cancel( bool isBlocking=true );
|
||||
virtual void StateCheckInThread();
|
||||
virtual void ChangeCdvdSource();
|
||||
|
||||
virtual void ApplySettings( const Pcsx2Config& src );
|
||||
virtual void UploadStateCopy( const VmStateBuffer& copy );
|
||||
|
||||
protected:
|
||||
virtual void OnResumeReady();
|
||||
virtual void OnResumeInThread( bool IsSuspended );
|
||||
virtual void OnSuspendInThread();
|
||||
virtual void OnCleanupInThread();
|
||||
virtual void PostVsyncToUI();
|
||||
virtual void ExecuteTaskInThread();
|
||||
virtual void DoCpuReset();
|
||||
};
|
||||
|
||||
// --------------------------------------------------------------------------------------
|
||||
// IScopedCoreThread / BaseScopedCoreThread
|
||||
// --------------------------------------------------------------------------------------
|
||||
class IScopedCoreThread
|
||||
{
|
||||
protected:
|
||||
IScopedCoreThread() {}
|
||||
|
||||
public:
|
||||
virtual ~IScopedCoreThread() throw() {};
|
||||
virtual void AllowResume()=0;
|
||||
virtual void DisallowResume()=0;
|
||||
};
|
||||
|
||||
class BaseScopedCoreThread : public IScopedCoreThread
|
||||
{
|
||||
DeclareNoncopyableObject( BaseScopedCoreThread );
|
||||
|
||||
protected:
|
||||
bool m_allowResume;
|
||||
bool m_alreadyStopped;
|
||||
bool m_alreadyScoped;
|
||||
SynchronousActionState m_sync;
|
||||
SynchronousActionState m_sync_resume;
|
||||
Threading::Mutex m_mtx_resume;
|
||||
|
||||
BaseScopedCoreThread();
|
||||
|
||||
public:
|
||||
virtual ~BaseScopedCoreThread() throw()=0;
|
||||
virtual void AllowResume();
|
||||
virtual void DisallowResume();
|
||||
|
||||
virtual bool PostToSysExec( BaseSysExecEvent_ScopedCore* msg );
|
||||
|
||||
protected:
|
||||
// Called from destructors -- do not make virtual!!
|
||||
void DoResume();
|
||||
};
|
||||
|
||||
// --------------------------------------------------------------------------------------
|
||||
// ScopedCoreThreadClose / ScopedCoreThreadPause / ScopedCoreThreadPopup
|
||||
// --------------------------------------------------------------------------------------
|
||||
// This class behaves a bit differently from other scoped classes due to the "standard"
|
||||
// assumption that we actually do *not* want to resume CoreThread operations when an
|
||||
// exception occurs. Because of this, the destructor of this class does *not* unroll the
|
||||
// suspend operation. Instead you must manually instruct the class to resume using a call
|
||||
// to the provisioned AllowResume() method.
|
||||
//
|
||||
// If the class leaves scope without having been resumed, a log is written to the console.
|
||||
// This can be useful for troubleshooting, and also allows the log a second line of info
|
||||
// indicating the status of CoreThread execution at the time of the exception.
|
||||
//
|
||||
// ScopedCoreThreadPopup is intended for use where message boxes are popped up to the user.
|
||||
// The old style GUI (without GSopen2) must use a full close of the CoreThread, in order to
|
||||
// ensure that the GS window isn't blocking the popup, and to avoid crashes if the GS window
|
||||
// is maximized or fullscreen.
|
||||
//
|
||||
class ScopedCoreThreadClose : public BaseScopedCoreThread
|
||||
{
|
||||
typedef BaseScopedCoreThread _parent;
|
||||
|
||||
public:
|
||||
ScopedCoreThreadClose();
|
||||
virtual ~ScopedCoreThreadClose() throw();
|
||||
|
||||
void LoadPlugins();
|
||||
};
|
||||
|
||||
struct ScopedCoreThreadPause : public BaseScopedCoreThread
|
||||
{
|
||||
typedef BaseScopedCoreThread _parent;
|
||||
|
||||
public:
|
||||
ScopedCoreThreadPause( BaseSysExecEvent_ScopedCore* abuse_me=NULL );
|
||||
virtual ~ScopedCoreThreadPause() throw();
|
||||
};
|
||||
|
||||
struct ScopedCoreThreadPopup : public IScopedCoreThread
|
||||
{
|
||||
protected:
|
||||
ScopedPtr<BaseScopedCoreThread> m_scoped_core;
|
||||
|
||||
public:
|
||||
ScopedCoreThreadPopup();
|
||||
virtual ~ScopedCoreThreadPopup() throw() {}
|
||||
|
||||
virtual void AllowResume();
|
||||
virtual void DisallowResume();
|
||||
};
|
||||
|
|
|
@ -1,28 +1,28 @@
|
|||
/* PCSX2 - PS2 Emulator for PCs
|
||||
* Copyright (C) 2002-2010 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 <wx/listbook.h>
|
||||
|
||||
template< typename T >
|
||||
void Dialogs::BaseConfigurationDialog::AddPage( const char* label, int iconid )
|
||||
{
|
||||
const wxString labelstr( fromUTF8( label ) );
|
||||
const int curidx = m_labels.Add( labelstr );
|
||||
m_ApplyState.SetCurrentPage( curidx );
|
||||
m_listbook.AddPage( new T( &m_listbook ), wxGetTranslation( labelstr ),
|
||||
( labelstr == GetConfSettingsTabName() ), iconid );
|
||||
}
|
||||
/* PCSX2 - PS2 Emulator for PCs
|
||||
* Copyright (C) 2002-2010 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 <wx/listbook.h>
|
||||
|
||||
template< typename T >
|
||||
void Dialogs::BaseConfigurationDialog::AddPage( const char* label, int iconid )
|
||||
{
|
||||
const wxString labelstr( fromUTF8( label ) );
|
||||
const int curidx = m_labels.Add( labelstr );
|
||||
m_ApplyState.SetCurrentPage( curidx );
|
||||
m_listbook.AddPage( new T( &m_listbook ), wxGetTranslation( labelstr ),
|
||||
( labelstr == GetConfSettingsTabName() ), iconid );
|
||||
}
|
||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -1,120 +1,120 @@
|
|||
|
||||
/* PCSX2 - PS2 Emulator for PCs
|
||||
* Copyright (C) 2002-2010 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 "App.h"
|
||||
#include "CpuUsageProvider.h"
|
||||
|
||||
|
||||
enum LimiterModeType
|
||||
{
|
||||
Limit_Nominal,
|
||||
Limit_Turbo,
|
||||
Limit_Slomo,
|
||||
};
|
||||
|
||||
extern LimiterModeType g_LimiterMode;
|
||||
|
||||
// --------------------------------------------------------------------------------------
|
||||
// GSPanel
|
||||
// --------------------------------------------------------------------------------------
|
||||
class GSPanel : public wxWindow, public EventListener_AppStatus
|
||||
{
|
||||
typedef wxWindow _parent;
|
||||
|
||||
protected:
|
||||
AcceleratorDictionary m_Accels;
|
||||
wxTimer m_HideMouseTimer;
|
||||
bool m_CursorShown;
|
||||
bool m_HasFocus;
|
||||
|
||||
public:
|
||||
GSPanel( wxWindow* parent );
|
||||
virtual ~GSPanel() throw();
|
||||
|
||||
void DoResize();
|
||||
void DoShowMouse();
|
||||
|
||||
protected:
|
||||
void AppStatusEvent_OnSettingsApplied();
|
||||
|
||||
#ifdef __WXMSW__
|
||||
virtual WXLRESULT MSWWindowProc(WXUINT message, WXWPARAM wParam, WXLPARAM lParam);
|
||||
#endif
|
||||
|
||||
void InitDefaultAccelerators();
|
||||
|
||||
void OnCloseWindow( wxCloseEvent& evt );
|
||||
void OnResize(wxSizeEvent& event);
|
||||
void OnShowMouse( wxMouseEvent& evt );
|
||||
void OnHideMouseTimeout( wxTimerEvent& evt );
|
||||
void OnKeyDown( wxKeyEvent& evt );
|
||||
void OnFocus( wxFocusEvent& evt );
|
||||
void OnFocusLost( wxFocusEvent& evt );
|
||||
};
|
||||
|
||||
|
||||
// --------------------------------------------------------------------------------------
|
||||
// GSFrame
|
||||
// --------------------------------------------------------------------------------------
|
||||
class GSFrame : public wxFrame,
|
||||
public EventListener_AppStatus,
|
||||
public EventListener_CoreThread
|
||||
{
|
||||
typedef wxFrame _parent;
|
||||
|
||||
protected:
|
||||
wxTimer m_timer_UpdateTitle;
|
||||
wxWindowID m_id_gspanel;
|
||||
wxWindowID m_id_OutputDisabled;
|
||||
wxStaticText* m_label_Disabled;
|
||||
wxStatusBar* m_statusbar;
|
||||
|
||||
CpuUsageProvider m_CpuUsage;
|
||||
|
||||
public:
|
||||
GSFrame(wxWindow* parent, const wxString& title);
|
||||
virtual ~GSFrame() throw();
|
||||
|
||||
GSPanel* GetViewport();
|
||||
void SetFocus();
|
||||
bool Show( bool shown=true );
|
||||
wxStaticText* GetLabel_OutputDisabled() const;
|
||||
|
||||
protected:
|
||||
void OnCloseWindow( wxCloseEvent& evt );
|
||||
void OnMove( wxMoveEvent& evt );
|
||||
void OnResize( wxSizeEvent& evt );
|
||||
void OnActivate( wxActivateEvent& evt );
|
||||
void OnUpdateTitle( wxTimerEvent& evt );
|
||||
|
||||
void AppStatusEvent_OnSettingsApplied();
|
||||
void CoreThread_OnResumed();
|
||||
void CoreThread_OnSuspended();
|
||||
};
|
||||
|
||||
// --------------------------------------------------------------------------------------
|
||||
// s* macros! ['s' stands for 'shortcut']
|
||||
// --------------------------------------------------------------------------------------
|
||||
// Use these for "silent fail" invocation of PCSX2 Application-related constructs. If the
|
||||
// construct (albeit wxApp, MainFrame, CoreThread, etc) is null, the requested method will
|
||||
// not be invoked, and an optional "else" clause can be affixed for handling the end case.
|
||||
//
|
||||
// See App.h (sApp) for more details.
|
||||
//
|
||||
#define sGSFrame \
|
||||
if( GSFrame* __gsframe_ = wxGetApp().GetGsFramePtr() ) (*__gsframe_)
|
||||
|
||||
/* PCSX2 - PS2 Emulator for PCs
|
||||
* Copyright (C) 2002-2010 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 "App.h"
|
||||
#include "CpuUsageProvider.h"
|
||||
|
||||
|
||||
enum LimiterModeType
|
||||
{
|
||||
Limit_Nominal,
|
||||
Limit_Turbo,
|
||||
Limit_Slomo,
|
||||
};
|
||||
|
||||
extern LimiterModeType g_LimiterMode;
|
||||
|
||||
// --------------------------------------------------------------------------------------
|
||||
// GSPanel
|
||||
// --------------------------------------------------------------------------------------
|
||||
class GSPanel : public wxWindow, public EventListener_AppStatus
|
||||
{
|
||||
typedef wxWindow _parent;
|
||||
|
||||
protected:
|
||||
AcceleratorDictionary m_Accels;
|
||||
wxTimer m_HideMouseTimer;
|
||||
bool m_CursorShown;
|
||||
bool m_HasFocus;
|
||||
|
||||
public:
|
||||
GSPanel( wxWindow* parent );
|
||||
virtual ~GSPanel() throw();
|
||||
|
||||
void DoResize();
|
||||
void DoShowMouse();
|
||||
|
||||
protected:
|
||||
void AppStatusEvent_OnSettingsApplied();
|
||||
|
||||
#ifdef __WXMSW__
|
||||
virtual WXLRESULT MSWWindowProc(WXUINT message, WXWPARAM wParam, WXLPARAM lParam);
|
||||
#endif
|
||||
|
||||
void InitDefaultAccelerators();
|
||||
|
||||
void OnCloseWindow( wxCloseEvent& evt );
|
||||
void OnResize(wxSizeEvent& event);
|
||||
void OnShowMouse( wxMouseEvent& evt );
|
||||
void OnHideMouseTimeout( wxTimerEvent& evt );
|
||||
void OnKeyDown( wxKeyEvent& evt );
|
||||
void OnFocus( wxFocusEvent& evt );
|
||||
void OnFocusLost( wxFocusEvent& evt );
|
||||
};
|
||||
|
||||
|
||||
// --------------------------------------------------------------------------------------
|
||||
// GSFrame
|
||||
// --------------------------------------------------------------------------------------
|
||||
class GSFrame : public wxFrame,
|
||||
public EventListener_AppStatus,
|
||||
public EventListener_CoreThread
|
||||
{
|
||||
typedef wxFrame _parent;
|
||||
|
||||
protected:
|
||||
wxTimer m_timer_UpdateTitle;
|
||||
wxWindowID m_id_gspanel;
|
||||
wxWindowID m_id_OutputDisabled;
|
||||
wxStaticText* m_label_Disabled;
|
||||
wxStatusBar* m_statusbar;
|
||||
|
||||
CpuUsageProvider m_CpuUsage;
|
||||
|
||||
public:
|
||||
GSFrame(wxWindow* parent, const wxString& title);
|
||||
virtual ~GSFrame() throw();
|
||||
|
||||
GSPanel* GetViewport();
|
||||
void SetFocus();
|
||||
bool Show( bool shown=true );
|
||||
wxStaticText* GetLabel_OutputDisabled() const;
|
||||
|
||||
protected:
|
||||
void OnCloseWindow( wxCloseEvent& evt );
|
||||
void OnMove( wxMoveEvent& evt );
|
||||
void OnResize( wxSizeEvent& evt );
|
||||
void OnActivate( wxActivateEvent& evt );
|
||||
void OnUpdateTitle( wxTimerEvent& evt );
|
||||
|
||||
void AppStatusEvent_OnSettingsApplied();
|
||||
void CoreThread_OnResumed();
|
||||
void CoreThread_OnSuspended();
|
||||
};
|
||||
|
||||
// --------------------------------------------------------------------------------------
|
||||
// s* macros! ['s' stands for 'shortcut']
|
||||
// --------------------------------------------------------------------------------------
|
||||
// Use these for "silent fail" invocation of PCSX2 Application-related constructs. If the
|
||||
// construct (albeit wxApp, MainFrame, CoreThread, etc) is null, the requested method will
|
||||
// not be invoked, and an optional "else" clause can be affixed for handling the end case.
|
||||
//
|
||||
// See App.h (sApp) for more details.
|
||||
//
|
||||
#define sGSFrame \
|
||||
if( GSFrame* __gsframe_ = wxGetApp().GetGsFramePtr() ) (*__gsframe_)
|
||||
|
|
|
@ -1,353 +1,353 @@
|
|||
/* PCSX2 - PS2 Emulator for PCs
|
||||
* Copyright (C) 2002-2010 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 te 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/>.
|
||||
*/
|
||||
|
||||
#include "PrecompiledHeader.h"
|
||||
#include "App.h"
|
||||
|
||||
#include "System/SysThreads.h"
|
||||
#include "SaveState.h"
|
||||
|
||||
#include "ZipTools/ThreadedZipTools.h"
|
||||
|
||||
// Used to hold the current state backup (fullcopy of PS2 memory and plugin states).
|
||||
//static VmStateBuffer state_buffer( L"Public Savestate Buffer" );
|
||||
|
||||
static const char SavestateIdentString[] = "PCSX2 Savestate";
|
||||
static const uint SavestateIdentLen = sizeof(SavestateIdentString);
|
||||
|
||||
static void SaveStateFile_WriteHeader( IStreamWriter& thr )
|
||||
{
|
||||
thr.Write( SavestateIdentString );
|
||||
thr.Write( g_SaveVersion );
|
||||
}
|
||||
|
||||
static void SaveStateFile_ReadHeader( IStreamReader& thr )
|
||||
{
|
||||
char ident[SavestateIdentLen] = {0};
|
||||
|
||||
thr.Read( ident );
|
||||
|
||||
if( strcmp(SavestateIdentString, ident) )
|
||||
throw Exception::SaveStateLoadError( thr.GetStreamName(),
|
||||
wxsFormat( L"Unrecognized file signature while loading savestate: %s", ident ),
|
||||
_("File is not a valid PCSX2 savestate, or is from an older unsupported version of PCSX2.")
|
||||
);
|
||||
|
||||
u32 savever;
|
||||
thr.Read( savever );
|
||||
|
||||
if( (savever >> 16) != (g_SaveVersion >> 16) )
|
||||
throw Exception::SaveStateLoadError( thr.GetStreamName(),
|
||||
wxsFormat( L"Unrecognized file signature while loading savestate: %s", ident ),
|
||||
_("File is not a valid PCSX2 savestate, or is from an older unsupported version of PCSX2.")
|
||||
);
|
||||
|
||||
if( savever > g_SaveVersion )
|
||||
throw Exception::SaveStateLoadError( thr.GetStreamName(),
|
||||
wxsFormat( L"Unrecognized file signature while loading savestate: %s", ident ),
|
||||
_("File is not a valid PCSX2 savestate, or is from an older unsupported version of PCSX2.")
|
||||
);
|
||||
};
|
||||
|
||||
// --------------------------------------------------------------------------------------
|
||||
// gzipReader
|
||||
// --------------------------------------------------------------------------------------
|
||||
// Interface for reading data from a gzip stream.
|
||||
//
|
||||
class gzipReader : public IStreamReader
|
||||
{
|
||||
DeclareNoncopyableObject(gzipReader);
|
||||
|
||||
protected:
|
||||
wxString m_filename;
|
||||
gzFile m_gzfp;
|
||||
|
||||
public:
|
||||
gzipReader( const wxString& filename )
|
||||
: m_filename( filename )
|
||||
{
|
||||
if( NULL == (m_gzfp = gzopen( m_filename.ToUTF8(), "rb" )) )
|
||||
throw Exception::CannotCreateStream( m_filename, "Cannot open file for reading." );
|
||||
|
||||
gzbuffer(m_gzfp, 0x100000); // 1mb buffer for zlib internal operations
|
||||
}
|
||||
|
||||
virtual ~gzipReader() throw ()
|
||||
{
|
||||
if( m_gzfp ) gzclose( m_gzfp );
|
||||
}
|
||||
|
||||
wxString GetStreamName() const { return m_filename; }
|
||||
|
||||
void Read( void* dest, size_t size )
|
||||
{
|
||||
int result = gzread( m_gzfp, dest, size );
|
||||
if( result == -1)
|
||||
throw Exception::BadStream( m_filename, "Data read failed: Invalid or corrupted gzip archive." );
|
||||
|
||||
if( (size_t)result < size )
|
||||
throw Exception::EndOfStream( m_filename );
|
||||
}
|
||||
};
|
||||
|
||||
static bool IsSavingOrLoading = false;
|
||||
|
||||
|
||||
// --------------------------------------------------------------------------------------
|
||||
// SysExecEvent_DownloadState
|
||||
// --------------------------------------------------------------------------------------
|
||||
// Pauses core emulation and downloads the savestate into the state_buffer.
|
||||
//
|
||||
class SysExecEvent_DownloadState : public SysExecEvent
|
||||
{
|
||||
protected:
|
||||
VmStateBuffer* m_dest_buffer;
|
||||
|
||||
public:
|
||||
wxString GetEventName() const { return L"VM_Download"; }
|
||||
|
||||
virtual ~SysExecEvent_DownloadState() throw() {}
|
||||
SysExecEvent_DownloadState* Clone() const { return new SysExecEvent_DownloadState( *this ); }
|
||||
SysExecEvent_DownloadState( VmStateBuffer* dest=NULL )
|
||||
{
|
||||
m_dest_buffer = dest;
|
||||
}
|
||||
|
||||
bool IsCriticalEvent() const { return true; }
|
||||
bool AllowCancelOnExit() const { return false; }
|
||||
|
||||
protected:
|
||||
void InvokeEvent()
|
||||
{
|
||||
ScopedCoreThreadPause paused_core;
|
||||
|
||||
if( !SysHasValidState() )
|
||||
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.") );
|
||||
|
||||
memSavingState(m_dest_buffer).FreezeAll();
|
||||
|
||||
UI_EnableStateActions();
|
||||
paused_core.AllowResume();
|
||||
}
|
||||
};
|
||||
|
||||
// It's bad mojo to have savestates trying to read and write from the same file at the
|
||||
// same time. To prevent that we use this mutex lock, which is used by both the
|
||||
// CompressThread and the UnzipFromDisk events. (note that CompressThread locks the
|
||||
// mutex during OnStartInThread, which ensures that the ZipToDisk event blocks; preventing
|
||||
// the SysExecutor's Idle Event from re-enabing savestates and slots.)
|
||||
//
|
||||
static Mutex mtx_CompressToDisk;
|
||||
|
||||
// --------------------------------------------------------------------------------------
|
||||
// CompressThread_VmState
|
||||
// --------------------------------------------------------------------------------------
|
||||
class VmStateZipThread : public CompressThread_gzip
|
||||
{
|
||||
typedef CompressThread_gzip _parent;
|
||||
|
||||
protected:
|
||||
ScopedLock m_lock_Compress;
|
||||
|
||||
public:
|
||||
VmStateZipThread( const wxString& file, VmStateBuffer* srcdata )
|
||||
: _parent( file, srcdata, SaveStateFile_WriteHeader )
|
||||
{
|
||||
m_lock_Compress.Assign(mtx_CompressToDisk);
|
||||
}
|
||||
|
||||
VmStateZipThread( const wxString& file, ScopedPtr<VmStateBuffer>& srcdata )
|
||||
: _parent( file, srcdata, SaveStateFile_WriteHeader )
|
||||
{
|
||||
m_lock_Compress.Assign(mtx_CompressToDisk);
|
||||
}
|
||||
|
||||
virtual ~VmStateZipThread() throw()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
protected:
|
||||
void OnStartInThread()
|
||||
{
|
||||
_parent::OnStartInThread();
|
||||
m_lock_Compress.Acquire();
|
||||
}
|
||||
|
||||
void OnCleanupInThread()
|
||||
{
|
||||
m_lock_Compress.Release();
|
||||
_parent::OnCleanupInThread();
|
||||
}
|
||||
};
|
||||
|
||||
// --------------------------------------------------------------------------------------
|
||||
// SysExecEvent_ZipToDisk
|
||||
// --------------------------------------------------------------------------------------
|
||||
class SysExecEvent_ZipToDisk : public SysExecEvent
|
||||
{
|
||||
protected:
|
||||
VmStateBuffer* m_src_buffer;
|
||||
wxString m_filename;
|
||||
|
||||
public:
|
||||
wxString GetEventName() const { return L"VM_ZipToDisk"; }
|
||||
|
||||
virtual ~SysExecEvent_ZipToDisk() throw()
|
||||
{
|
||||
delete m_src_buffer;
|
||||
}
|
||||
|
||||
SysExecEvent_ZipToDisk* Clone() const { return new SysExecEvent_ZipToDisk( *this ); }
|
||||
|
||||
SysExecEvent_ZipToDisk( ScopedPtr<VmStateBuffer>& src, const wxString& filename )
|
||||
: m_filename( filename )
|
||||
{
|
||||
m_src_buffer = src.DetachPtr();
|
||||
}
|
||||
|
||||
SysExecEvent_ZipToDisk( VmStateBuffer* src, const wxString& filename )
|
||||
: m_filename( filename )
|
||||
{
|
||||
m_src_buffer = src;
|
||||
}
|
||||
|
||||
bool IsCriticalEvent() const { return true; }
|
||||
bool AllowCancelOnExit() const { return false; }
|
||||
|
||||
protected:
|
||||
void InvokeEvent()
|
||||
{
|
||||
(new VmStateZipThread( m_filename, m_src_buffer ))->Start();
|
||||
m_src_buffer = NULL;
|
||||
}
|
||||
};
|
||||
|
||||
// --------------------------------------------------------------------------------------
|
||||
// SysExecEvent_UnzipFromDisk
|
||||
// --------------------------------------------------------------------------------------
|
||||
// Note: Unzipping always goes directly into the SysCoreThread's static VM state, and is
|
||||
// always a blocking action on the SysExecutor thread (the system cannot execute other
|
||||
// commands while states are unzipping or uploading into the system).
|
||||
//
|
||||
class SysExecEvent_UnzipFromDisk : public SysExecEvent
|
||||
{
|
||||
protected:
|
||||
wxString m_filename;
|
||||
|
||||
public:
|
||||
wxString GetEventName() const { return L"VM_UnzipFromDisk"; }
|
||||
|
||||
virtual ~SysExecEvent_UnzipFromDisk() throw() {}
|
||||
SysExecEvent_UnzipFromDisk* Clone() const { return new SysExecEvent_UnzipFromDisk( *this ); }
|
||||
SysExecEvent_UnzipFromDisk( const wxString& filename )
|
||||
: m_filename( filename )
|
||||
{
|
||||
}
|
||||
|
||||
wxString GetStreamName() const { return m_filename; }
|
||||
|
||||
protected:
|
||||
void InvokeEvent()
|
||||
{
|
||||
ScopedLock lock( mtx_CompressToDisk );
|
||||
gzipReader m_gzreader(m_filename );
|
||||
SaveStateFile_ReadHeader( m_gzreader );
|
||||
|
||||
// We use direct Suspend/Resume control here, since it's desirable that emulation
|
||||
// *ALWAYS* start execution after the new savestate is loaded.
|
||||
|
||||
GetCoreThread().Pause();
|
||||
|
||||
// fixme: should start initially with the file size, and then grow from there.
|
||||
|
||||
static const int BlockSize = 0x100000;
|
||||
|
||||
VmStateBuffer buffer( 0x800000, L"StateBuffer_UnzipFromDisk" ); // start with an 8 meg buffer to avoid frequent reallocation.
|
||||
int curidx = 0;
|
||||
|
||||
try {
|
||||
while(true) {
|
||||
buffer.MakeRoomFor( curidx+BlockSize );
|
||||
m_gzreader.Read( buffer.GetPtr(curidx), BlockSize );
|
||||
curidx += BlockSize;
|
||||
Threading::pxTestCancel();
|
||||
}
|
||||
}
|
||||
catch( Exception::EndOfStream& )
|
||||
{
|
||||
// This exception actually means success! Any others we let get sent
|
||||
// to the main event handler/thread for handling.
|
||||
}
|
||||
|
||||
// Optional shutdown of plugins when loading states? I'm not implementing it yet because some
|
||||
// things, like the SPU2-recovery trick, rely on not resetting the plugins prior to loading
|
||||
// the new savestate data.
|
||||
//if( ShutdownOnStateLoad ) GetCoreThread().Cancel();
|
||||
|
||||
|
||||
GetCoreThread().UploadStateCopy( buffer );
|
||||
GetCoreThread().Resume(); // force resume regardless of emulation state earlier.
|
||||
}
|
||||
};
|
||||
|
||||
// =====================================================================================================
|
||||
// StateCopy Public Interface
|
||||
// =====================================================================================================
|
||||
|
||||
void StateCopy_SaveToFile( const wxString& file )
|
||||
{
|
||||
UI_DisableStateActions();
|
||||
|
||||
ScopedPtr<VmStateBuffer> zipbuf(new VmStateBuffer( L"Zippable Savestate" ));
|
||||
GetSysExecutorThread().PostEvent(new SysExecEvent_DownloadState( zipbuf ));
|
||||
GetSysExecutorThread().PostEvent(new SysExecEvent_ZipToDisk( zipbuf, file ));
|
||||
}
|
||||
|
||||
void StateCopy_LoadFromFile( const wxString& file )
|
||||
{
|
||||
UI_DisableSysActions();
|
||||
GetSysExecutorThread().PostEvent(new SysExecEvent_UnzipFromDisk( file ));
|
||||
}
|
||||
|
||||
// Saves recovery state info to the given saveslot, or saves the active emulation state
|
||||
// (if one exists) and no recovery data was found. This is needed because when a recovery
|
||||
// state is made, the emulation state is usually reset so the only persisting state is
|
||||
// the one in the memory save. :)
|
||||
void StateCopy_SaveToSlot( uint num )
|
||||
{
|
||||
const wxString file( SaveStateBase::GetFilename( num ) );
|
||||
|
||||
Console.WriteLn( Color_StrongGreen, "Saving savestate to slot %d...", num );
|
||||
Console.Indent().WriteLn( Color_StrongGreen, L"filename: %s", file.c_str() );
|
||||
|
||||
StateCopy_SaveToFile( file );
|
||||
}
|
||||
|
||||
void StateCopy_LoadFromSlot( uint slot )
|
||||
{
|
||||
wxString file( SaveStateBase::GetFilename( slot ) );
|
||||
|
||||
if( !wxFileExists( file ) )
|
||||
{
|
||||
Console.Warning( "Savestate slot %d is empty.", slot );
|
||||
return;
|
||||
}
|
||||
|
||||
Console.WriteLn( Color_StrongGreen, "Loading savestate from slot %d...", slot );
|
||||
Console.Indent().WriteLn( Color_StrongGreen, L"filename: %s", file.c_str() );
|
||||
|
||||
StateCopy_LoadFromFile( file );
|
||||
}
|
||||
/* PCSX2 - PS2 Emulator for PCs
|
||||
* Copyright (C) 2002-2010 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 te 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/>.
|
||||
*/
|
||||
|
||||
#include "PrecompiledHeader.h"
|
||||
#include "App.h"
|
||||
|
||||
#include "System/SysThreads.h"
|
||||
#include "SaveState.h"
|
||||
|
||||
#include "ZipTools/ThreadedZipTools.h"
|
||||
|
||||
// Used to hold the current state backup (fullcopy of PS2 memory and plugin states).
|
||||
//static VmStateBuffer state_buffer( L"Public Savestate Buffer" );
|
||||
|
||||
static const char SavestateIdentString[] = "PCSX2 Savestate";
|
||||
static const uint SavestateIdentLen = sizeof(SavestateIdentString);
|
||||
|
||||
static void SaveStateFile_WriteHeader( IStreamWriter& thr )
|
||||
{
|
||||
thr.Write( SavestateIdentString );
|
||||
thr.Write( g_SaveVersion );
|
||||
}
|
||||
|
||||
static void SaveStateFile_ReadHeader( IStreamReader& thr )
|
||||
{
|
||||
char ident[SavestateIdentLen] = {0};
|
||||
|
||||
thr.Read( ident );
|
||||
|
||||
if( strcmp(SavestateIdentString, ident) )
|
||||
throw Exception::SaveStateLoadError( thr.GetStreamName(),
|
||||
wxsFormat( L"Unrecognized file signature while loading savestate: %s", ident ),
|
||||
_("File is not a valid PCSX2 savestate, or is from an older unsupported version of PCSX2.")
|
||||
);
|
||||
|
||||
u32 savever;
|
||||
thr.Read( savever );
|
||||
|
||||
if( (savever >> 16) != (g_SaveVersion >> 16) )
|
||||
throw Exception::SaveStateLoadError( thr.GetStreamName(),
|
||||
wxsFormat( L"Unrecognized file signature while loading savestate: %s", ident ),
|
||||
_("File is not a valid PCSX2 savestate, or is from an older unsupported version of PCSX2.")
|
||||
);
|
||||
|
||||
if( savever > g_SaveVersion )
|
||||
throw Exception::SaveStateLoadError( thr.GetStreamName(),
|
||||
wxsFormat( L"Unrecognized file signature while loading savestate: %s", ident ),
|
||||
_("File is not a valid PCSX2 savestate, or is from an older unsupported version of PCSX2.")
|
||||
);
|
||||
};
|
||||
|
||||
// --------------------------------------------------------------------------------------
|
||||
// gzipReader
|
||||
// --------------------------------------------------------------------------------------
|
||||
// Interface for reading data from a gzip stream.
|
||||
//
|
||||
class gzipReader : public IStreamReader
|
||||
{
|
||||
DeclareNoncopyableObject(gzipReader);
|
||||
|
||||
protected:
|
||||
wxString m_filename;
|
||||
gzFile m_gzfp;
|
||||
|
||||
public:
|
||||
gzipReader( const wxString& filename )
|
||||
: m_filename( filename )
|
||||
{
|
||||
if( NULL == (m_gzfp = gzopen( m_filename.ToUTF8(), "rb" )) )
|
||||
throw Exception::CannotCreateStream( m_filename, "Cannot open file for reading." );
|
||||
|
||||
gzbuffer(m_gzfp, 0x100000); // 1mb buffer for zlib internal operations
|
||||
}
|
||||
|
||||
virtual ~gzipReader() throw ()
|
||||
{
|
||||
if( m_gzfp ) gzclose( m_gzfp );
|
||||
}
|
||||
|
||||
wxString GetStreamName() const { return m_filename; }
|
||||
|
||||
void Read( void* dest, size_t size )
|
||||
{
|
||||
int result = gzread( m_gzfp, dest, size );
|
||||
if( result == -1)
|
||||
throw Exception::BadStream( m_filename, "Data read failed: Invalid or corrupted gzip archive." );
|
||||
|
||||
if( (size_t)result < size )
|
||||
throw Exception::EndOfStream( m_filename );
|
||||
}
|
||||
};
|
||||
|
||||
static bool IsSavingOrLoading = false;
|
||||
|
||||
|
||||
// --------------------------------------------------------------------------------------
|
||||
// SysExecEvent_DownloadState
|
||||
// --------------------------------------------------------------------------------------
|
||||
// Pauses core emulation and downloads the savestate into the state_buffer.
|
||||
//
|
||||
class SysExecEvent_DownloadState : public SysExecEvent
|
||||
{
|
||||
protected:
|
||||
VmStateBuffer* m_dest_buffer;
|
||||
|
||||
public:
|
||||
wxString GetEventName() const { return L"VM_Download"; }
|
||||
|
||||
virtual ~SysExecEvent_DownloadState() throw() {}
|
||||
SysExecEvent_DownloadState* Clone() const { return new SysExecEvent_DownloadState( *this ); }
|
||||
SysExecEvent_DownloadState( VmStateBuffer* dest=NULL )
|
||||
{
|
||||
m_dest_buffer = dest;
|
||||
}
|
||||
|
||||
bool IsCriticalEvent() const { return true; }
|
||||
bool AllowCancelOnExit() const { return false; }
|
||||
|
||||
protected:
|
||||
void InvokeEvent()
|
||||
{
|
||||
ScopedCoreThreadPause paused_core;
|
||||
|
||||
if( !SysHasValidState() )
|
||||
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.") );
|
||||
|
||||
memSavingState(m_dest_buffer).FreezeAll();
|
||||
|
||||
UI_EnableStateActions();
|
||||
paused_core.AllowResume();
|
||||
}
|
||||
};
|
||||
|
||||
// It's bad mojo to have savestates trying to read and write from the same file at the
|
||||
// same time. To prevent that we use this mutex lock, which is used by both the
|
||||
// CompressThread and the UnzipFromDisk events. (note that CompressThread locks the
|
||||
// mutex during OnStartInThread, which ensures that the ZipToDisk event blocks; preventing
|
||||
// the SysExecutor's Idle Event from re-enabing savestates and slots.)
|
||||
//
|
||||
static Mutex mtx_CompressToDisk;
|
||||
|
||||
// --------------------------------------------------------------------------------------
|
||||
// CompressThread_VmState
|
||||
// --------------------------------------------------------------------------------------
|
||||
class VmStateZipThread : public CompressThread_gzip
|
||||
{
|
||||
typedef CompressThread_gzip _parent;
|
||||
|
||||
protected:
|
||||
ScopedLock m_lock_Compress;
|
||||
|
||||
public:
|
||||
VmStateZipThread( const wxString& file, VmStateBuffer* srcdata )
|
||||
: _parent( file, srcdata, SaveStateFile_WriteHeader )
|
||||
{
|
||||
m_lock_Compress.Assign(mtx_CompressToDisk);
|
||||
}
|
||||
|
||||
VmStateZipThread( const wxString& file, ScopedPtr<VmStateBuffer>& srcdata )
|
||||
: _parent( file, srcdata, SaveStateFile_WriteHeader )
|
||||
{
|
||||
m_lock_Compress.Assign(mtx_CompressToDisk);
|
||||
}
|
||||
|
||||
virtual ~VmStateZipThread() throw()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
protected:
|
||||
void OnStartInThread()
|
||||
{
|
||||
_parent::OnStartInThread();
|
||||
m_lock_Compress.Acquire();
|
||||
}
|
||||
|
||||
void OnCleanupInThread()
|
||||
{
|
||||
m_lock_Compress.Release();
|
||||
_parent::OnCleanupInThread();
|
||||
}
|
||||
};
|
||||
|
||||
// --------------------------------------------------------------------------------------
|
||||
// SysExecEvent_ZipToDisk
|
||||
// --------------------------------------------------------------------------------------
|
||||
class SysExecEvent_ZipToDisk : public SysExecEvent
|
||||
{
|
||||
protected:
|
||||
VmStateBuffer* m_src_buffer;
|
||||
wxString m_filename;
|
||||
|
||||
public:
|
||||
wxString GetEventName() const { return L"VM_ZipToDisk"; }
|
||||
|
||||
virtual ~SysExecEvent_ZipToDisk() throw()
|
||||
{
|
||||
delete m_src_buffer;
|
||||
}
|
||||
|
||||
SysExecEvent_ZipToDisk* Clone() const { return new SysExecEvent_ZipToDisk( *this ); }
|
||||
|
||||
SysExecEvent_ZipToDisk( ScopedPtr<VmStateBuffer>& src, const wxString& filename )
|
||||
: m_filename( filename )
|
||||
{
|
||||
m_src_buffer = src.DetachPtr();
|
||||
}
|
||||
|
||||
SysExecEvent_ZipToDisk( VmStateBuffer* src, const wxString& filename )
|
||||
: m_filename( filename )
|
||||
{
|
||||
m_src_buffer = src;
|
||||
}
|
||||
|
||||
bool IsCriticalEvent() const { return true; }
|
||||
bool AllowCancelOnExit() const { return false; }
|
||||
|
||||
protected:
|
||||
void InvokeEvent()
|
||||
{
|
||||
(new VmStateZipThread( m_filename, m_src_buffer ))->Start();
|
||||
m_src_buffer = NULL;
|
||||
}
|
||||
};
|
||||
|
||||
// --------------------------------------------------------------------------------------
|
||||
// SysExecEvent_UnzipFromDisk
|
||||
// --------------------------------------------------------------------------------------
|
||||
// Note: Unzipping always goes directly into the SysCoreThread's static VM state, and is
|
||||
// always a blocking action on the SysExecutor thread (the system cannot execute other
|
||||
// commands while states are unzipping or uploading into the system).
|
||||
//
|
||||
class SysExecEvent_UnzipFromDisk : public SysExecEvent
|
||||
{
|
||||
protected:
|
||||
wxString m_filename;
|
||||
|
||||
public:
|
||||
wxString GetEventName() const { return L"VM_UnzipFromDisk"; }
|
||||
|
||||
virtual ~SysExecEvent_UnzipFromDisk() throw() {}
|
||||
SysExecEvent_UnzipFromDisk* Clone() const { return new SysExecEvent_UnzipFromDisk( *this ); }
|
||||
SysExecEvent_UnzipFromDisk( const wxString& filename )
|
||||
: m_filename( filename )
|
||||
{
|
||||
}
|
||||
|
||||
wxString GetStreamName() const { return m_filename; }
|
||||
|
||||
protected:
|
||||
void InvokeEvent()
|
||||
{
|
||||
ScopedLock lock( mtx_CompressToDisk );
|
||||
gzipReader m_gzreader(m_filename );
|
||||
SaveStateFile_ReadHeader( m_gzreader );
|
||||
|
||||
// We use direct Suspend/Resume control here, since it's desirable that emulation
|
||||
// *ALWAYS* start execution after the new savestate is loaded.
|
||||
|
||||
GetCoreThread().Pause();
|
||||
|
||||
// fixme: should start initially with the file size, and then grow from there.
|
||||
|
||||
static const int BlockSize = 0x100000;
|
||||
|
||||
VmStateBuffer buffer( 0x800000, L"StateBuffer_UnzipFromDisk" ); // start with an 8 meg buffer to avoid frequent reallocation.
|
||||
int curidx = 0;
|
||||
|
||||
try {
|
||||
while(true) {
|
||||
buffer.MakeRoomFor( curidx+BlockSize );
|
||||
m_gzreader.Read( buffer.GetPtr(curidx), BlockSize );
|
||||
curidx += BlockSize;
|
||||
Threading::pxTestCancel();
|
||||
}
|
||||
}
|
||||
catch( Exception::EndOfStream& )
|
||||
{
|
||||
// This exception actually means success! Any others we let get sent
|
||||
// to the main event handler/thread for handling.
|
||||
}
|
||||
|
||||
// Optional shutdown of plugins when loading states? I'm not implementing it yet because some
|
||||
// things, like the SPU2-recovery trick, rely on not resetting the plugins prior to loading
|
||||
// the new savestate data.
|
||||
//if( ShutdownOnStateLoad ) GetCoreThread().Cancel();
|
||||
|
||||
|
||||
GetCoreThread().UploadStateCopy( buffer );
|
||||
GetCoreThread().Resume(); // force resume regardless of emulation state earlier.
|
||||
}
|
||||
};
|
||||
|
||||
// =====================================================================================================
|
||||
// StateCopy Public Interface
|
||||
// =====================================================================================================
|
||||
|
||||
void StateCopy_SaveToFile( const wxString& file )
|
||||
{
|
||||
UI_DisableStateActions();
|
||||
|
||||
ScopedPtr<VmStateBuffer> zipbuf(new VmStateBuffer( L"Zippable Savestate" ));
|
||||
GetSysExecutorThread().PostEvent(new SysExecEvent_DownloadState( zipbuf ));
|
||||
GetSysExecutorThread().PostEvent(new SysExecEvent_ZipToDisk( zipbuf, file ));
|
||||
}
|
||||
|
||||
void StateCopy_LoadFromFile( const wxString& file )
|
||||
{
|
||||
UI_DisableSysActions();
|
||||
GetSysExecutorThread().PostEvent(new SysExecEvent_UnzipFromDisk( file ));
|
||||
}
|
||||
|
||||
// Saves recovery state info to the given saveslot, or saves the active emulation state
|
||||
// (if one exists) and no recovery data was found. This is needed because when a recovery
|
||||
// state is made, the emulation state is usually reset so the only persisting state is
|
||||
// the one in the memory save. :)
|
||||
void StateCopy_SaveToSlot( uint num )
|
||||
{
|
||||
const wxString file( SaveStateBase::GetFilename( num ) );
|
||||
|
||||
Console.WriteLn( Color_StrongGreen, "Saving savestate to slot %d...", num );
|
||||
Console.Indent().WriteLn( Color_StrongGreen, L"filename: %s", file.c_str() );
|
||||
|
||||
StateCopy_SaveToFile( file );
|
||||
}
|
||||
|
||||
void StateCopy_LoadFromSlot( uint slot )
|
||||
{
|
||||
wxString file( SaveStateBase::GetFilename( slot ) );
|
||||
|
||||
if( !wxFileExists( file ) )
|
||||
{
|
||||
Console.Warning( "Savestate slot %d is empty.", slot );
|
||||
return;
|
||||
}
|
||||
|
||||
Console.WriteLn( Color_StrongGreen, "Loading savestate from slot %d...", slot );
|
||||
Console.Indent().WriteLn( Color_StrongGreen, L"filename: %s", file.c_str() );
|
||||
|
||||
StateCopy_LoadFromFile( file );
|
||||
}
|
||||
|
|
|
@ -1,109 +1,109 @@
|
|||
/* PCSX2 - PS2 Emulator for PCs
|
||||
* Copyright (C) 2002-2010 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/>.
|
||||
*/
|
||||
|
||||
#include "PrecompiledHeader.h"
|
||||
#include "MainFrame.h"
|
||||
#include "GSFrame.h"
|
||||
|
||||
// General Notes:
|
||||
// * It's very important that we re-discover menu items by ID every time we change them,
|
||||
// because the modern era of configurable GUIs means that we can't be assured the IDs
|
||||
// exist anymore.
|
||||
|
||||
|
||||
// This is necessary because this stupid wxWidgets 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.EnableMenuItem( MenuId_Sys_LoadStates, enabled );
|
||||
sMainFrame.EnableMenuItem( MenuId_Sys_SaveStates, enabled );
|
||||
}
|
||||
|
||||
// Updates the enable/disable status of all System related controls: menus, toolbars,
|
||||
// etc. Typically called by SysEvtHandler whenever the message pump becomes idle.
|
||||
void UI_UpdateSysControls()
|
||||
{
|
||||
if( wxGetApp().PostMethodMyself( &UI_UpdateSysControls ) ) return;
|
||||
|
||||
sApp.PostAction( CoreThreadStatusEvent( CoreThread_Indeterminate ) );
|
||||
|
||||
_SaveLoadStuff( true );
|
||||
}
|
||||
|
||||
void UI_DisableSysReset()
|
||||
{
|
||||
if( wxGetApp().PostMethodMyself( UI_DisableSysReset ) ) return;
|
||||
sMainFrame.EnableMenuItem( MenuId_Sys_Restart, false );
|
||||
|
||||
_SaveLoadStuff( false );
|
||||
}
|
||||
|
||||
void UI_DisableSysShutdown()
|
||||
{
|
||||
if( wxGetApp().PostMethodMyself( &UI_DisableSysShutdown ) ) return;
|
||||
|
||||
sMainFrame.EnableMenuItem( MenuId_Sys_Restart, false );
|
||||
sMainFrame.EnableMenuItem( MenuId_Sys_Shutdown, false );
|
||||
}
|
||||
|
||||
void UI_EnableSysShutdown()
|
||||
{
|
||||
if( wxGetApp().PostMethodMyself( &UI_EnableSysShutdown ) ) return;
|
||||
|
||||
sMainFrame.EnableMenuItem( MenuId_Sys_Restart, true );
|
||||
sMainFrame.EnableMenuItem( MenuId_Sys_Shutdown, true );
|
||||
}
|
||||
|
||||
|
||||
void UI_DisableSysActions()
|
||||
{
|
||||
if( wxGetApp().PostMethodMyself( &UI_DisableSysActions ) ) return;
|
||||
|
||||
sMainFrame.EnableMenuItem( MenuId_Sys_Restart, false );
|
||||
sMainFrame.EnableMenuItem( MenuId_Sys_Shutdown, false );
|
||||
|
||||
_SaveLoadStuff( false );
|
||||
}
|
||||
|
||||
void UI_EnableSysActions()
|
||||
{
|
||||
if( wxGetApp().PostMethodMyself( &UI_EnableSysActions ) ) return;
|
||||
|
||||
sMainFrame.EnableMenuItem( MenuId_Sys_Restart, true );
|
||||
sMainFrame.EnableMenuItem( MenuId_Sys_Shutdown, true );
|
||||
|
||||
_SaveLoadStuff( true );
|
||||
}
|
||||
|
||||
void UI_DisableStateActions()
|
||||
{
|
||||
if( wxGetApp().PostMethodMyself( &UI_DisableStateActions ) ) return;
|
||||
_SaveLoadStuff( false );
|
||||
}
|
||||
|
||||
void UI_EnableStateActions()
|
||||
{
|
||||
if( wxGetApp().PostMethodMyself( &UI_EnableStateActions ) ) return;
|
||||
_SaveLoadStuff( true );
|
||||
}
|
||||
|
||||
|
||||
/* PCSX2 - PS2 Emulator for PCs
|
||||
* Copyright (C) 2002-2010 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/>.
|
||||
*/
|
||||
|
||||
#include "PrecompiledHeader.h"
|
||||
#include "MainFrame.h"
|
||||
#include "GSFrame.h"
|
||||
|
||||
// General Notes:
|
||||
// * It's very important that we re-discover menu items by ID every time we change them,
|
||||
// because the modern era of configurable GUIs means that we can't be assured the IDs
|
||||
// exist anymore.
|
||||
|
||||
|
||||
// This is necessary because this stupid wxWidgets 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.EnableMenuItem( MenuId_Sys_LoadStates, enabled );
|
||||
sMainFrame.EnableMenuItem( MenuId_Sys_SaveStates, enabled );
|
||||
}
|
||||
|
||||
// Updates the enable/disable status of all System related controls: menus, toolbars,
|
||||
// etc. Typically called by SysEvtHandler whenever the message pump becomes idle.
|
||||
void UI_UpdateSysControls()
|
||||
{
|
||||
if( wxGetApp().PostMethodMyself( &UI_UpdateSysControls ) ) return;
|
||||
|
||||
sApp.PostAction( CoreThreadStatusEvent( CoreThread_Indeterminate ) );
|
||||
|
||||
_SaveLoadStuff( true );
|
||||
}
|
||||
|
||||
void UI_DisableSysReset()
|
||||
{
|
||||
if( wxGetApp().PostMethodMyself( UI_DisableSysReset ) ) return;
|
||||
sMainFrame.EnableMenuItem( MenuId_Sys_Restart, false );
|
||||
|
||||
_SaveLoadStuff( false );
|
||||
}
|
||||
|
||||
void UI_DisableSysShutdown()
|
||||
{
|
||||
if( wxGetApp().PostMethodMyself( &UI_DisableSysShutdown ) ) return;
|
||||
|
||||
sMainFrame.EnableMenuItem( MenuId_Sys_Restart, false );
|
||||
sMainFrame.EnableMenuItem( MenuId_Sys_Shutdown, false );
|
||||
}
|
||||
|
||||
void UI_EnableSysShutdown()
|
||||
{
|
||||
if( wxGetApp().PostMethodMyself( &UI_EnableSysShutdown ) ) return;
|
||||
|
||||
sMainFrame.EnableMenuItem( MenuId_Sys_Restart, true );
|
||||
sMainFrame.EnableMenuItem( MenuId_Sys_Shutdown, true );
|
||||
}
|
||||
|
||||
|
||||
void UI_DisableSysActions()
|
||||
{
|
||||
if( wxGetApp().PostMethodMyself( &UI_DisableSysActions ) ) return;
|
||||
|
||||
sMainFrame.EnableMenuItem( MenuId_Sys_Restart, false );
|
||||
sMainFrame.EnableMenuItem( MenuId_Sys_Shutdown, false );
|
||||
|
||||
_SaveLoadStuff( false );
|
||||
}
|
||||
|
||||
void UI_EnableSysActions()
|
||||
{
|
||||
if( wxGetApp().PostMethodMyself( &UI_EnableSysActions ) ) return;
|
||||
|
||||
sMainFrame.EnableMenuItem( MenuId_Sys_Restart, true );
|
||||
sMainFrame.EnableMenuItem( MenuId_Sys_Shutdown, true );
|
||||
|
||||
_SaveLoadStuff( true );
|
||||
}
|
||||
|
||||
void UI_DisableStateActions()
|
||||
{
|
||||
if( wxGetApp().PostMethodMyself( &UI_DisableStateActions ) ) return;
|
||||
_SaveLoadStuff( false );
|
||||
}
|
||||
|
||||
void UI_EnableStateActions()
|
||||
{
|
||||
if( wxGetApp().PostMethodMyself( &UI_EnableStateActions ) ) return;
|
||||
_SaveLoadStuff( true );
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -1,237 +1,237 @@
|
|||
/* PCSX2 - PS2 Emulator for PCs
|
||||
* Copyright (C) 2002-2010 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 "Utilities/PersistentThread.h"
|
||||
#include "Utilities/pxEvents.h"
|
||||
|
||||
// TODO!! Make this system a bit more generic, and then move it to the Utilities library.
|
||||
|
||||
// --------------------------------------------------------------------------------------
|
||||
// SysExecEvent
|
||||
// --------------------------------------------------------------------------------------
|
||||
// Base class for all pxEvtHandler processable events.
|
||||
//
|
||||
// Rules for deriving:
|
||||
// * Override InvokeEvent(), *NOT* _DoInvokeEvent(). _DoInvokeEvent() performs setup and
|
||||
// wraps exceptions for transport to the invoking context/thread, and then itself calls
|
||||
// InvokeEvent() to perform the derived class implementation.
|
||||
//
|
||||
// * Derived classes must implement their own versions of an empty constructor and
|
||||
// Clone(), or else the class will fail to be copied to the event handler's thread
|
||||
// context correctly.
|
||||
//
|
||||
// * This class is not abstract, and gives no error if the invocation method is not
|
||||
// overridden: It can be used as a simple ping device against the event queue, Re-
|
||||
// awaking the invoking thread as soon as the queue has caught up to and processed
|
||||
// the event.
|
||||
//
|
||||
// * Avoid using virtual class inheritence. It's unreliable at best.
|
||||
//
|
||||
class SysExecEvent : public ICloneable
|
||||
{
|
||||
protected:
|
||||
SynchronousActionState* m_sync;
|
||||
|
||||
public:
|
||||
virtual ~SysExecEvent() throw() {}
|
||||
SysExecEvent* Clone() const { return new SysExecEvent( *this ); }
|
||||
|
||||
SysExecEvent( SynchronousActionState* sync=NULL )
|
||||
{
|
||||
m_sync = sync;
|
||||
}
|
||||
|
||||
SysExecEvent( SynchronousActionState& sync )
|
||||
{
|
||||
m_sync = &sync;
|
||||
}
|
||||
|
||||
const SynchronousActionState* GetSyncState() const { return m_sync; }
|
||||
SynchronousActionState* GetSyncState() { return m_sync; }
|
||||
|
||||
SysExecEvent& SetSyncState( SynchronousActionState* obj ) { m_sync = obj; return *this; }
|
||||
SysExecEvent& SetSyncState( SynchronousActionState& obj ) { m_sync = &obj; return *this; }
|
||||
|
||||
// Tells the Event Handler whether or not this event can be skipped when the system
|
||||
// is being quit or reset. Typically set this to true for events which shut down the
|
||||
// system, since program crashes can occur if the program tries to exit while threads
|
||||
// are running.
|
||||
virtual bool IsCriticalEvent() const { return false; }
|
||||
|
||||
// Tells the Event Handler whether or not this event can be canceled. Typically events
|
||||
// should not prohibit cancellation, since it expedites program termination and helps
|
||||
// avoid permanent deadlock. Some actions like saving states and shutdown procedures
|
||||
// should not allow cancellation since they could result in program crashes or corrupted
|
||||
// data.
|
||||
virtual bool AllowCancelOnExit() const { return true; }
|
||||
|
||||
virtual void _DoInvokeEvent();
|
||||
virtual void PostResult() const;
|
||||
|
||||
virtual wxString GetEventName() const;
|
||||
virtual wxString GetEventMessage() const;
|
||||
|
||||
virtual int GetResult()
|
||||
{
|
||||
if( !pxAssertDev( m_sync != NULL, "SysEvent: Expecting return value, but no sync object provided." ) ) return 0;
|
||||
return m_sync->return_value;
|
||||
}
|
||||
|
||||
virtual void SetException( BaseException* ex );
|
||||
|
||||
void SetException( const BaseException& ex );
|
||||
|
||||
protected:
|
||||
virtual void InvokeEvent();
|
||||
virtual void CleanupEvent();
|
||||
};
|
||||
|
||||
// --------------------------------------------------------------------------------------
|
||||
// SysExecEvent_MethodVoid
|
||||
// --------------------------------------------------------------------------------------
|
||||
class SysExecEvent_MethodVoid : public SysExecEvent
|
||||
{
|
||||
protected:
|
||||
FnType_Void* m_method;
|
||||
|
||||
public:
|
||||
wxString GetEventName() const { return L"MethodVoid"; }
|
||||
|
||||
virtual ~SysExecEvent_MethodVoid() throw() {}
|
||||
SysExecEvent_MethodVoid* Clone() const { return new SysExecEvent_MethodVoid( *this ); }
|
||||
|
||||
explicit SysExecEvent_MethodVoid( FnType_Void* method = NULL )
|
||||
{
|
||||
m_method = method;
|
||||
}
|
||||
|
||||
protected:
|
||||
void InvokeEvent()
|
||||
{
|
||||
if( m_method ) m_method();
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
typedef std::list<SysExecEvent*> pxEvtList;
|
||||
|
||||
// --------------------------------------------------------------------------------------
|
||||
// pxEvtHandler
|
||||
// --------------------------------------------------------------------------------------
|
||||
// Purpose: To provide a safe environment for queuing tasks that must be executed in
|
||||
// sequential order (in blocking fashion). Unlike the wxWidgets event handlers, instances
|
||||
// of this handler can be stalled for extended periods of time without affecting the
|
||||
// responsiveness of the GUI or frame updates of the DirectX output windows. This class
|
||||
// is mostly intended to be used from the context of an ExecutorThread.
|
||||
//
|
||||
// Rationales:
|
||||
// * Using the main event handler of wxWidgets is dangerous because it must call itself
|
||||
// recursively when waiting on threaded events such as semaphore and mutexes. Thus,
|
||||
// tasks such as suspending the VM would invoke the event queue while waiting,
|
||||
// running events that expect the suspend to be complete while the suspend was still
|
||||
// pending.
|
||||
//
|
||||
// * wxWidgets Event Queue (wxEvtHandler) isn't thread-safe and isn't even
|
||||
// intended for use for anything other than wxWindow events (it uses static vars
|
||||
// and checks/modifies wxApp globals while processing), so it's useless to us.
|
||||
// Have to roll our own. -_-
|
||||
//
|
||||
class pxEvtHandler
|
||||
{
|
||||
protected:
|
||||
pxEvtList m_pendingEvents;
|
||||
pxEvtList m_idleEvents;
|
||||
|
||||
Threading::MutexRecursive m_mtx_pending;
|
||||
Threading::Semaphore m_wakeup;
|
||||
wxThreadIdType m_OwnerThreadId;
|
||||
volatile u32 m_Quitting;
|
||||
|
||||
// Used for performance measuring the execution of individual events,
|
||||
// and also for detecting deadlocks during message processing.
|
||||
volatile u64 m_qpc_Start;
|
||||
|
||||
public:
|
||||
pxEvtHandler();
|
||||
virtual ~pxEvtHandler() throw() {}
|
||||
|
||||
virtual wxString GetEventHandlerName() const { return L"pxEvtHandler"; }
|
||||
|
||||
virtual void ShutdownQueue();
|
||||
bool IsShuttingDown() const { return !!m_Quitting; }
|
||||
|
||||
void ProcessEvents( pxEvtList& list );
|
||||
void ProcessPendingEvents();
|
||||
void ProcessIdleEvents();
|
||||
void Idle();
|
||||
|
||||
void AddPendingEvent( SysExecEvent& evt );
|
||||
void PostEvent( SysExecEvent* evt );
|
||||
void PostEvent( const SysExecEvent& evt );
|
||||
void PostIdleEvent( SysExecEvent* evt );
|
||||
void PostIdleEvent( const SysExecEvent& evt );
|
||||
|
||||
void ProcessEvent( SysExecEvent* evt );
|
||||
void ProcessEvent( SysExecEvent& evt );
|
||||
|
||||
bool ProcessMethodSelf( FnType_Void* method );
|
||||
void SetActiveThread();
|
||||
|
||||
protected:
|
||||
virtual void _DoIdle() {}
|
||||
};
|
||||
|
||||
// --------------------------------------------------------------------------------------
|
||||
// ExecutorThread
|
||||
// --------------------------------------------------------------------------------------
|
||||
// Threaded wrapper class for implementing pxEvtHandler. Simply create the desired
|
||||
// EvtHandler, start the thread, and enjoy queued event execution in fully blocking fashion.
|
||||
//
|
||||
class ExecutorThread : public Threading::PersistentThread
|
||||
{
|
||||
typedef Threading::PersistentThread _parent;
|
||||
|
||||
protected:
|
||||
ScopedPtr<wxTimer> m_ExecutorTimer;
|
||||
ScopedPtr<pxEvtHandler> m_EvtHandler;
|
||||
|
||||
public:
|
||||
ExecutorThread( pxEvtHandler* evtandler = NULL );
|
||||
virtual ~ExecutorThread() throw() { }
|
||||
|
||||
virtual void ShutdownQueue();
|
||||
|
||||
void PostEvent( SysExecEvent* evt );
|
||||
void PostEvent( const SysExecEvent& evt );
|
||||
|
||||
void PostIdleEvent( SysExecEvent* evt );
|
||||
void PostIdleEvent( const SysExecEvent& evt );
|
||||
|
||||
void ProcessEvent( SysExecEvent* evt );
|
||||
void ProcessEvent( SysExecEvent& evt );
|
||||
|
||||
bool ProcessMethodSelf( void (*evt)() )
|
||||
{
|
||||
return m_EvtHandler ? m_EvtHandler->ProcessMethodSelf( evt ) : false;
|
||||
}
|
||||
|
||||
protected:
|
||||
void OnStart();
|
||||
void ExecuteTaskInThread();
|
||||
void OnCleanupInThread();
|
||||
};
|
||||
|
||||
/* PCSX2 - PS2 Emulator for PCs
|
||||
* Copyright (C) 2002-2010 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 "Utilities/PersistentThread.h"
|
||||
#include "Utilities/pxEvents.h"
|
||||
|
||||
// TODO!! Make this system a bit more generic, and then move it to the Utilities library.
|
||||
|
||||
// --------------------------------------------------------------------------------------
|
||||
// SysExecEvent
|
||||
// --------------------------------------------------------------------------------------
|
||||
// Base class for all pxEvtHandler processable events.
|
||||
//
|
||||
// Rules for deriving:
|
||||
// * Override InvokeEvent(), *NOT* _DoInvokeEvent(). _DoInvokeEvent() performs setup and
|
||||
// wraps exceptions for transport to the invoking context/thread, and then itself calls
|
||||
// InvokeEvent() to perform the derived class implementation.
|
||||
//
|
||||
// * Derived classes must implement their own versions of an empty constructor and
|
||||
// Clone(), or else the class will fail to be copied to the event handler's thread
|
||||
// context correctly.
|
||||
//
|
||||
// * This class is not abstract, and gives no error if the invocation method is not
|
||||
// overridden: It can be used as a simple ping device against the event queue, Re-
|
||||
// awaking the invoking thread as soon as the queue has caught up to and processed
|
||||
// the event.
|
||||
//
|
||||
// * Avoid using virtual class inheritence. It's unreliable at best.
|
||||
//
|
||||
class SysExecEvent : public ICloneable
|
||||
{
|
||||
protected:
|
||||
SynchronousActionState* m_sync;
|
||||
|
||||
public:
|
||||
virtual ~SysExecEvent() throw() {}
|
||||
SysExecEvent* Clone() const { return new SysExecEvent( *this ); }
|
||||
|
||||
SysExecEvent( SynchronousActionState* sync=NULL )
|
||||
{
|
||||
m_sync = sync;
|
||||
}
|
||||
|
||||
SysExecEvent( SynchronousActionState& sync )
|
||||
{
|
||||
m_sync = &sync;
|
||||
}
|
||||
|
||||
const SynchronousActionState* GetSyncState() const { return m_sync; }
|
||||
SynchronousActionState* GetSyncState() { return m_sync; }
|
||||
|
||||
SysExecEvent& SetSyncState( SynchronousActionState* obj ) { m_sync = obj; return *this; }
|
||||
SysExecEvent& SetSyncState( SynchronousActionState& obj ) { m_sync = &obj; return *this; }
|
||||
|
||||
// Tells the Event Handler whether or not this event can be skipped when the system
|
||||
// is being quit or reset. Typically set this to true for events which shut down the
|
||||
// system, since program crashes can occur if the program tries to exit while threads
|
||||
// are running.
|
||||
virtual bool IsCriticalEvent() const { return false; }
|
||||
|
||||
// Tells the Event Handler whether or not this event can be canceled. Typically events
|
||||
// should not prohibit cancellation, since it expedites program termination and helps
|
||||
// avoid permanent deadlock. Some actions like saving states and shutdown procedures
|
||||
// should not allow cancellation since they could result in program crashes or corrupted
|
||||
// data.
|
||||
virtual bool AllowCancelOnExit() const { return true; }
|
||||
|
||||
virtual void _DoInvokeEvent();
|
||||
virtual void PostResult() const;
|
||||
|
||||
virtual wxString GetEventName() const;
|
||||
virtual wxString GetEventMessage() const;
|
||||
|
||||
virtual int GetResult()
|
||||
{
|
||||
if( !pxAssertDev( m_sync != NULL, "SysEvent: Expecting return value, but no sync object provided." ) ) return 0;
|
||||
return m_sync->return_value;
|
||||
}
|
||||
|
||||
virtual void SetException( BaseException* ex );
|
||||
|
||||
void SetException( const BaseException& ex );
|
||||
|
||||
protected:
|
||||
virtual void InvokeEvent();
|
||||
virtual void CleanupEvent();
|
||||
};
|
||||
|
||||
// --------------------------------------------------------------------------------------
|
||||
// SysExecEvent_MethodVoid
|
||||
// --------------------------------------------------------------------------------------
|
||||
class SysExecEvent_MethodVoid : public SysExecEvent
|
||||
{
|
||||
protected:
|
||||
FnType_Void* m_method;
|
||||
|
||||
public:
|
||||
wxString GetEventName() const { return L"MethodVoid"; }
|
||||
|
||||
virtual ~SysExecEvent_MethodVoid() throw() {}
|
||||
SysExecEvent_MethodVoid* Clone() const { return new SysExecEvent_MethodVoid( *this ); }
|
||||
|
||||
explicit SysExecEvent_MethodVoid( FnType_Void* method = NULL )
|
||||
{
|
||||
m_method = method;
|
||||
}
|
||||
|
||||
protected:
|
||||
void InvokeEvent()
|
||||
{
|
||||
if( m_method ) m_method();
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
typedef std::list<SysExecEvent*> pxEvtList;
|
||||
|
||||
// --------------------------------------------------------------------------------------
|
||||
// pxEvtHandler
|
||||
// --------------------------------------------------------------------------------------
|
||||
// Purpose: To provide a safe environment for queuing tasks that must be executed in
|
||||
// sequential order (in blocking fashion). Unlike the wxWidgets event handlers, instances
|
||||
// of this handler can be stalled for extended periods of time without affecting the
|
||||
// responsiveness of the GUI or frame updates of the DirectX output windows. This class
|
||||
// is mostly intended to be used from the context of an ExecutorThread.
|
||||
//
|
||||
// Rationales:
|
||||
// * Using the main event handler of wxWidgets is dangerous because it must call itself
|
||||
// recursively when waiting on threaded events such as semaphore and mutexes. Thus,
|
||||
// tasks such as suspending the VM would invoke the event queue while waiting,
|
||||
// running events that expect the suspend to be complete while the suspend was still
|
||||
// pending.
|
||||
//
|
||||
// * wxWidgets Event Queue (wxEvtHandler) isn't thread-safe and isn't even
|
||||
// intended for use for anything other than wxWindow events (it uses static vars
|
||||
// and checks/modifies wxApp globals while processing), so it's useless to us.
|
||||
// Have to roll our own. -_-
|
||||
//
|
||||
class pxEvtHandler
|
||||
{
|
||||
protected:
|
||||
pxEvtList m_pendingEvents;
|
||||
pxEvtList m_idleEvents;
|
||||
|
||||
Threading::MutexRecursive m_mtx_pending;
|
||||
Threading::Semaphore m_wakeup;
|
||||
wxThreadIdType m_OwnerThreadId;
|
||||
volatile u32 m_Quitting;
|
||||
|
||||
// Used for performance measuring the execution of individual events,
|
||||
// and also for detecting deadlocks during message processing.
|
||||
volatile u64 m_qpc_Start;
|
||||
|
||||
public:
|
||||
pxEvtHandler();
|
||||
virtual ~pxEvtHandler() throw() {}
|
||||
|
||||
virtual wxString GetEventHandlerName() const { return L"pxEvtHandler"; }
|
||||
|
||||
virtual void ShutdownQueue();
|
||||
bool IsShuttingDown() const { return !!m_Quitting; }
|
||||
|
||||
void ProcessEvents( pxEvtList& list );
|
||||
void ProcessPendingEvents();
|
||||
void ProcessIdleEvents();
|
||||
void Idle();
|
||||
|
||||
void AddPendingEvent( SysExecEvent& evt );
|
||||
void PostEvent( SysExecEvent* evt );
|
||||
void PostEvent( const SysExecEvent& evt );
|
||||
void PostIdleEvent( SysExecEvent* evt );
|
||||
void PostIdleEvent( const SysExecEvent& evt );
|
||||
|
||||
void ProcessEvent( SysExecEvent* evt );
|
||||
void ProcessEvent( SysExecEvent& evt );
|
||||
|
||||
bool ProcessMethodSelf( FnType_Void* method );
|
||||
void SetActiveThread();
|
||||
|
||||
protected:
|
||||
virtual void _DoIdle() {}
|
||||
};
|
||||
|
||||
// --------------------------------------------------------------------------------------
|
||||
// ExecutorThread
|
||||
// --------------------------------------------------------------------------------------
|
||||
// Threaded wrapper class for implementing pxEvtHandler. Simply create the desired
|
||||
// EvtHandler, start the thread, and enjoy queued event execution in fully blocking fashion.
|
||||
//
|
||||
class ExecutorThread : public Threading::PersistentThread
|
||||
{
|
||||
typedef Threading::PersistentThread _parent;
|
||||
|
||||
protected:
|
||||
ScopedPtr<wxTimer> m_ExecutorTimer;
|
||||
ScopedPtr<pxEvtHandler> m_EvtHandler;
|
||||
|
||||
public:
|
||||
ExecutorThread( pxEvtHandler* evtandler = NULL );
|
||||
virtual ~ExecutorThread() throw() { }
|
||||
|
||||
virtual void ShutdownQueue();
|
||||
|
||||
void PostEvent( SysExecEvent* evt );
|
||||
void PostEvent( const SysExecEvent& evt );
|
||||
|
||||
void PostIdleEvent( SysExecEvent* evt );
|
||||
void PostIdleEvent( const SysExecEvent& evt );
|
||||
|
||||
void ProcessEvent( SysExecEvent* evt );
|
||||
void ProcessEvent( SysExecEvent& evt );
|
||||
|
||||
bool ProcessMethodSelf( void (*evt)() )
|
||||
{
|
||||
return m_EvtHandler ? m_EvtHandler->ProcessMethodSelf( evt ) : false;
|
||||
}
|
||||
|
||||
protected:
|
||||
void OnStart();
|
||||
void ExecuteTaskInThread();
|
||||
void OnCleanupInThread();
|
||||
};
|
||||
|
||||
|
|
Loading…
Reference in New Issue