2009-08-18 19:47:00 +00:00
|
|
|
#pragma once
|
|
|
|
|
2009-09-29 19:16:00 +00:00
|
|
|
// --------------------------------------------------------------------------------------
|
|
|
|
// ScopedPtr
|
|
|
|
// --------------------------------------------------------------------------------------
|
|
|
|
|
|
|
|
template< typename T >
|
|
|
|
class ScopedPtr
|
|
|
|
{
|
|
|
|
DeclareNoncopyableObject(ScopedPtr);
|
User Interface:
* Fixed and added better Emulation/System menu updating. Suspend/Resume is more consistent, and Reset grays itself out after being used.
* Entering plugin configurations auto-suspends the emulator.
* Changing plugins in the Configuration PAnel takes effect now without a restart.
* Added preliminary support for an ExtensibleConfirmation Dialog box (contains a sizer you can add content to, and also has an optional "[x] Do not show this again" checkbox).
Bugfixes:
* Added some mutex protection to cdvdNewDiskCB; "just in case."
* Resolved several recursion and deadlock scenarios when (very!) rapidly suspending, resuming, and resetting the emu.
Developments / Code Cleanups:
* Renamed SysCoreThread ExecutionModes: Suspend/Resume are now Opened/Closed (which more accurately reflects the fact they opena nd close the plugins, and helps avoid ambiguity with the "Paused" state).
* Added Exception::ThreadTimedOut, which is now thrown from Semaphore::Wait when recursive wxApp::Yield() calls are detected, and a deadlock occurs (basically cancels the current action which, most of the time, allows for full recovery).
* Major Threading namespace cleanups, documentations, etc.
* Removed wxScopedArray (scopedarray.h) and replaced it with a better implemeneted ScopedArray class.
* Removed toUTF8 class, which I only added a couple weeks ago because I didn't realize wxCharBuffer had an implicit typecast to (char*).
* Implemented more Source/Listener events for Pcsx2App. CoreThread events are sourced properly now, and added SettingsApplied and SettingsLoadSave Sources.
git-svn-id: http://pcsx2.googlecode.com/svn/trunk@2010 96395faa-99c1-11dd-bbfe-3dabce05a288
2009-10-16 03:58:29 +00:00
|
|
|
|
2009-09-29 19:16:00 +00:00
|
|
|
protected:
|
|
|
|
T* m_ptr;
|
|
|
|
|
|
|
|
public:
|
|
|
|
typedef T element_type;
|
|
|
|
|
|
|
|
wxEXPLICIT ScopedPtr(T * ptr = NULL) : m_ptr(ptr) { }
|
|
|
|
|
User Interface:
* Fixed and added better Emulation/System menu updating. Suspend/Resume is more consistent, and Reset grays itself out after being used.
* Entering plugin configurations auto-suspends the emulator.
* Changing plugins in the Configuration PAnel takes effect now without a restart.
* Added preliminary support for an ExtensibleConfirmation Dialog box (contains a sizer you can add content to, and also has an optional "[x] Do not show this again" checkbox).
Bugfixes:
* Added some mutex protection to cdvdNewDiskCB; "just in case."
* Resolved several recursion and deadlock scenarios when (very!) rapidly suspending, resuming, and resetting the emu.
Developments / Code Cleanups:
* Renamed SysCoreThread ExecutionModes: Suspend/Resume are now Opened/Closed (which more accurately reflects the fact they opena nd close the plugins, and helps avoid ambiguity with the "Paused" state).
* Added Exception::ThreadTimedOut, which is now thrown from Semaphore::Wait when recursive wxApp::Yield() calls are detected, and a deadlock occurs (basically cancels the current action which, most of the time, allows for full recovery).
* Major Threading namespace cleanups, documentations, etc.
* Removed wxScopedArray (scopedarray.h) and replaced it with a better implemeneted ScopedArray class.
* Removed toUTF8 class, which I only added a couple weeks ago because I didn't realize wxCharBuffer had an implicit typecast to (char*).
* Implemented more Source/Listener events for Pcsx2App. CoreThread events are sourced properly now, and added SettingsApplied and SettingsLoadSave Sources.
git-svn-id: http://pcsx2.googlecode.com/svn/trunk@2010 96395faa-99c1-11dd-bbfe-3dabce05a288
2009-10-16 03:58:29 +00:00
|
|
|
~ScopedPtr() throw()
|
2009-09-29 19:16:00 +00:00
|
|
|
{ Delete(); }
|
|
|
|
|
|
|
|
ScopedPtr& Reassign(T * ptr = NULL)
|
|
|
|
{
|
|
|
|
if ( ptr != m_ptr )
|
|
|
|
{
|
|
|
|
Delete();
|
|
|
|
m_ptr = ptr;
|
|
|
|
}
|
|
|
|
return *this;
|
|
|
|
}
|
|
|
|
|
User Interface:
* Fixed and added better Emulation/System menu updating. Suspend/Resume is more consistent, and Reset grays itself out after being used.
* Entering plugin configurations auto-suspends the emulator.
* Changing plugins in the Configuration PAnel takes effect now without a restart.
* Added preliminary support for an ExtensibleConfirmation Dialog box (contains a sizer you can add content to, and also has an optional "[x] Do not show this again" checkbox).
Bugfixes:
* Added some mutex protection to cdvdNewDiskCB; "just in case."
* Resolved several recursion and deadlock scenarios when (very!) rapidly suspending, resuming, and resetting the emu.
Developments / Code Cleanups:
* Renamed SysCoreThread ExecutionModes: Suspend/Resume are now Opened/Closed (which more accurately reflects the fact they opena nd close the plugins, and helps avoid ambiguity with the "Paused" state).
* Added Exception::ThreadTimedOut, which is now thrown from Semaphore::Wait when recursive wxApp::Yield() calls are detected, and a deadlock occurs (basically cancels the current action which, most of the time, allows for full recovery).
* Major Threading namespace cleanups, documentations, etc.
* Removed wxScopedArray (scopedarray.h) and replaced it with a better implemeneted ScopedArray class.
* Removed toUTF8 class, which I only added a couple weeks ago because I didn't realize wxCharBuffer had an implicit typecast to (char*).
* Implemented more Source/Listener events for Pcsx2App. CoreThread events are sourced properly now, and added SettingsApplied and SettingsLoadSave Sources.
git-svn-id: http://pcsx2.googlecode.com/svn/trunk@2010 96395faa-99c1-11dd-bbfe-3dabce05a288
2009-10-16 03:58:29 +00:00
|
|
|
ScopedPtr& Delete() throw()
|
2009-09-29 19:16:00 +00:00
|
|
|
{
|
|
|
|
// Thread-safe deletion: Set the pointer to NULL first, and then issue
|
|
|
|
// the deletion. This allows pending Application messages that might be
|
|
|
|
// dependent on the current object to nullify their actions.
|
|
|
|
|
|
|
|
T* deleteme = m_ptr;
|
|
|
|
m_ptr = NULL;
|
|
|
|
delete deleteme;
|
|
|
|
|
|
|
|
return *this;
|
|
|
|
}
|
|
|
|
|
|
|
|
// Removes the pointer from scoped management, but does not delete!
|
|
|
|
T *DetachPtr()
|
|
|
|
{
|
|
|
|
T *ptr = m_ptr;
|
|
|
|
m_ptr = NULL;
|
|
|
|
return ptr;
|
|
|
|
}
|
|
|
|
|
|
|
|
// Returns the managed pointer. Can return NULL as a valid result if the ScopedPtr
|
|
|
|
// has no object in management.
|
|
|
|
T* GetPtr() const
|
|
|
|
{
|
|
|
|
return m_ptr;
|
|
|
|
}
|
|
|
|
|
|
|
|
void SwapPtr(ScopedPtr& other)
|
|
|
|
{
|
|
|
|
T * const tmp = other.m_ptr;
|
|
|
|
other.m_ptr = m_ptr;
|
|
|
|
m_ptr = tmp;
|
|
|
|
}
|
|
|
|
|
|
|
|
// ----------------------------------------------------------------------------
|
|
|
|
// ScopedPtr Operators
|
|
|
|
// ----------------------------------------------------------------------------
|
|
|
|
// I've decided to use the ATL's approach to pointer validity tests, opposed to
|
|
|
|
// the wx/boost approach (which uses some bizarre member method pointer crap, and can't
|
|
|
|
// allow the T* implicit casting.
|
|
|
|
|
|
|
|
bool operator!() const throw()
|
|
|
|
{
|
|
|
|
return m_ptr == NULL;
|
|
|
|
}
|
|
|
|
|
|
|
|
operator T*() const
|
|
|
|
{
|
|
|
|
return m_ptr;
|
|
|
|
}
|
|
|
|
|
|
|
|
// Equality
|
|
|
|
bool operator==(T* pT) const throw()
|
|
|
|
{
|
|
|
|
return m_ptr == pT;
|
|
|
|
}
|
|
|
|
|
|
|
|
// Inequality
|
|
|
|
bool operator!=(T* pT) const throw()
|
|
|
|
{
|
|
|
|
return !operator==(pT);
|
|
|
|
}
|
|
|
|
|
|
|
|
// Convenient assignment operator. ScopedPtr = NULL will issue an automatic deletion
|
|
|
|
// of the managed pointer.
|
|
|
|
ScopedPtr& operator=( T* src )
|
|
|
|
{
|
|
|
|
return Reassign( src );
|
|
|
|
}
|
|
|
|
|
|
|
|
// Dereference operator, returns a handle to the managed pointer.
|
|
|
|
// Generates a debug assertion if the object is NULL!
|
|
|
|
T& operator*() const
|
|
|
|
{
|
2009-10-04 15:34:40 +00:00
|
|
|
pxAssert(m_ptr != NULL);
|
2009-09-29 19:16:00 +00:00
|
|
|
return *m_ptr;
|
|
|
|
}
|
|
|
|
|
|
|
|
T* operator->() const
|
|
|
|
{
|
2009-10-04 15:34:40 +00:00
|
|
|
pxAssert(m_ptr != NULL);
|
2009-09-29 19:16:00 +00:00
|
|
|
return m_ptr;
|
|
|
|
}
|
|
|
|
};
|
|
|
|
|
User Interface:
* Fixed and added better Emulation/System menu updating. Suspend/Resume is more consistent, and Reset grays itself out after being used.
* Entering plugin configurations auto-suspends the emulator.
* Changing plugins in the Configuration PAnel takes effect now without a restart.
* Added preliminary support for an ExtensibleConfirmation Dialog box (contains a sizer you can add content to, and also has an optional "[x] Do not show this again" checkbox).
Bugfixes:
* Added some mutex protection to cdvdNewDiskCB; "just in case."
* Resolved several recursion and deadlock scenarios when (very!) rapidly suspending, resuming, and resetting the emu.
Developments / Code Cleanups:
* Renamed SysCoreThread ExecutionModes: Suspend/Resume are now Opened/Closed (which more accurately reflects the fact they opena nd close the plugins, and helps avoid ambiguity with the "Paused" state).
* Added Exception::ThreadTimedOut, which is now thrown from Semaphore::Wait when recursive wxApp::Yield() calls are detected, and a deadlock occurs (basically cancels the current action which, most of the time, allows for full recovery).
* Major Threading namespace cleanups, documentations, etc.
* Removed wxScopedArray (scopedarray.h) and replaced it with a better implemeneted ScopedArray class.
* Removed toUTF8 class, which I only added a couple weeks ago because I didn't realize wxCharBuffer had an implicit typecast to (char*).
* Implemented more Source/Listener events for Pcsx2App. CoreThread events are sourced properly now, and added SettingsApplied and SettingsLoadSave Sources.
git-svn-id: http://pcsx2.googlecode.com/svn/trunk@2010 96395faa-99c1-11dd-bbfe-3dabce05a288
2009-10-16 03:58:29 +00:00
|
|
|
// --------------------------------------------------------------------------------------
|
|
|
|
// ScopedArray - same as ScopedPtr but uses delete[], and has operator[]
|
|
|
|
// --------------------------------------------------------------------------------------
|
|
|
|
|
|
|
|
template< typename T >
|
|
|
|
class ScopedArray
|
|
|
|
{
|
|
|
|
DeclareNoncopyableObject(ScopedArray);
|
|
|
|
|
|
|
|
protected:
|
|
|
|
T* m_array;
|
|
|
|
uint m_valid_range;
|
|
|
|
public:
|
|
|
|
typedef T element_type;
|
|
|
|
|
|
|
|
wxEXPLICIT ScopedArray(T * ptr = NULL) :
|
|
|
|
m_array(ptr)
|
|
|
|
, m_valid_range( 0xffffffff )
|
|
|
|
{
|
|
|
|
}
|
|
|
|
|
|
|
|
wxEXPLICIT ScopedArray( int size ) :
|
|
|
|
m_array( pxAssertDev( size >= 0, "Invalid negative size specified." ) ? new T[size] : NULL )
|
|
|
|
, m_valid_range( (uint)size )
|
|
|
|
{
|
|
|
|
}
|
|
|
|
|
|
|
|
// For breaking the 2gb barrier, lets provision this:
|
|
|
|
wxEXPLICIT ScopedArray( s64 size ) :
|
|
|
|
m_array( pxAssertDev( size >= 0 && (size < UINT_MAX), "Invalid negative size specified to ScopedArray." ) ? new T[size] : NULL )
|
|
|
|
, m_valid_range( (uint)size )
|
|
|
|
{
|
|
|
|
}
|
|
|
|
|
|
|
|
~ScopedArray() throw()
|
|
|
|
{ Delete(); }
|
|
|
|
|
|
|
|
ScopedArray& Reassign(T * ptr = NULL)
|
|
|
|
{
|
|
|
|
if( ptr != m_array )
|
|
|
|
{
|
|
|
|
Delete();
|
|
|
|
m_array = ptr;
|
|
|
|
}
|
|
|
|
return *this;
|
|
|
|
}
|
|
|
|
|
|
|
|
ScopedArray& Delete() throw()
|
|
|
|
{
|
|
|
|
// Thread-safe deletion: Set the pointer to NULL first, and then issue
|
|
|
|
// the deletion. This allows pending Application messages that might be
|
|
|
|
// dependent on the current object to nullify their actions.
|
|
|
|
|
|
|
|
T* deleteme = m_array;
|
|
|
|
m_array = NULL;
|
|
|
|
delete[] deleteme;
|
|
|
|
|
|
|
|
return *this;
|
|
|
|
}
|
|
|
|
|
|
|
|
// Removes the pointer from scoped management, but does not delete!
|
|
|
|
T *DetachPtr()
|
|
|
|
{
|
|
|
|
T *ptr = m_array;
|
|
|
|
m_array = NULL;
|
|
|
|
return ptr;
|
|
|
|
}
|
|
|
|
|
|
|
|
// Returns the managed pointer. Can return NULL as a valid result if the ScopedPtr
|
|
|
|
// has no object in management.
|
|
|
|
T* GetPtr() const
|
|
|
|
{
|
|
|
|
return m_array;
|
|
|
|
}
|
|
|
|
|
|
|
|
void SwapPtr(ScopedArray& other)
|
|
|
|
{
|
|
|
|
T * const tmp = other.m_array;
|
|
|
|
other.m_array = m_array;
|
|
|
|
m_array = tmp;
|
|
|
|
}
|
|
|
|
|
|
|
|
// ----------------------------------------------------------------------------
|
|
|
|
// ScopedPtr Operators
|
|
|
|
// ----------------------------------------------------------------------------
|
|
|
|
// I've decided to use the ATL's approach to pointer validity tests, opposed to
|
|
|
|
// the wx/boost approach (which uses some bizarre member method pointer crap, and can't
|
|
|
|
// allow the T* implicit casting.
|
|
|
|
|
|
|
|
bool operator!() const throw()
|
|
|
|
{
|
|
|
|
return m_array == NULL;
|
|
|
|
}
|
|
|
|
|
|
|
|
// Equality
|
|
|
|
bool operator==(T* pT) const throw()
|
|
|
|
{
|
|
|
|
return m_array == pT;
|
|
|
|
}
|
|
|
|
|
|
|
|
// Inequality
|
|
|
|
bool operator!=(T* pT) const throw()
|
|
|
|
{
|
|
|
|
return !operator==(pT);
|
|
|
|
}
|
|
|
|
|
|
|
|
// Convenient assignment operator. ScopedPtr = NULL will issue an automatic deletion
|
|
|
|
// of the managed pointer.
|
|
|
|
ScopedArray& operator=( T* src )
|
|
|
|
{
|
|
|
|
return Reassign( src );
|
|
|
|
}
|
|
|
|
|
|
|
|
T& operator[]( uint idx ) const
|
|
|
|
{
|
|
|
|
pxAssertDev( idx < m_valid_range, "Array index out of bounds on ScopedArray." );
|
|
|
|
return m_array[idx];
|
|
|
|
}
|
|
|
|
};
|
2009-09-29 19:16:00 +00:00
|
|
|
|
|
|
|
// --------------------------------------------------------------------------------------
|
|
|
|
// pxObjPtr -- fancified version of wxScopedPtr
|
|
|
|
// --------------------------------------------------------------------------------------
|
|
|
|
// This class is a non-null scoped pointer container. What that means is that the object
|
|
|
|
// always resets itself to a valid "placebo" function rather than NULL, such that methods
|
|
|
|
// can be invoked safely without fear of NULL pointer exceptions. This system is useful
|
|
|
|
// for objects where most or all public methods can fail silently, and still allow program
|
|
|
|
// execution flow to continue.
|
|
|
|
//
|
|
|
|
// It also implements basic scoped pointer behavior: when the pxObjPtr class is deleted,
|
|
|
|
// it will automatically delete the pointer in its posession, if the pointer is valid.
|
|
|
|
//
|
|
|
|
// Notes:
|
|
|
|
// * This class intentionally does not implement the "release" API, because it doesn't
|
|
|
|
// really make sense within the context of a non-nullable pointer specification.
|
|
|
|
//
|
|
|
|
template< typename T, T& DefaultStaticInst >
|
|
|
|
class pxObjPtr
|
|
|
|
{
|
|
|
|
DeclareNoncopyableObject(pxObjPtr);
|
|
|
|
|
|
|
|
protected:
|
|
|
|
T * m_ptr;
|
|
|
|
|
|
|
|
public:
|
|
|
|
typedef T element_type;
|
|
|
|
|
|
|
|
explicit pxObjPtr(T * ptr = &DefaultStaticInst) : m_ptr(ptr) { }
|
|
|
|
|
|
|
|
bool IsEmpty() const
|
|
|
|
{
|
|
|
|
return m_ptr != &DefaultStaticInst;
|
|
|
|
}
|
|
|
|
|
|
|
|
~pxObjPtr()
|
|
|
|
{
|
|
|
|
if( !IsEmpty() ) delete m_ptr;
|
|
|
|
m_ptr = NULL;
|
|
|
|
}
|
|
|
|
|
|
|
|
// test for pointer validity: defining conversion to unspecified_bool_type
|
|
|
|
// and not more obvious bool to avoid implicit conversions to integer types
|
|
|
|
typedef T *(pxObjPtr<T,DefaultStaticInst>::*unspecified_bool_type)() const;
|
|
|
|
|
|
|
|
operator unspecified_bool_type() const
|
|
|
|
{
|
2009-09-29 22:05:21 +00:00
|
|
|
return ( !IsEmpty() ) ? &ScopedPtr<T>::get : NULL;
|
2009-09-29 19:16:00 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
void reset(T * ptr = &DefaultStaticInst)
|
|
|
|
{
|
|
|
|
if ( ptr != m_ptr )
|
|
|
|
{
|
|
|
|
if( !IsEmpty() )
|
|
|
|
delete m_ptr;
|
|
|
|
m_ptr = ptr;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
T& operator*() const
|
|
|
|
{
|
2009-10-04 15:34:40 +00:00
|
|
|
pxAssert(m_ptr != NULL);
|
2009-09-29 19:16:00 +00:00
|
|
|
return *m_ptr;
|
|
|
|
}
|
|
|
|
|
|
|
|
T* operator->() const
|
|
|
|
{
|
2009-10-04 15:34:40 +00:00
|
|
|
pxAssert(m_ptr != NULL);
|
2009-09-29 19:16:00 +00:00
|
|
|
return m_ptr;
|
|
|
|
}
|
|
|
|
|
|
|
|
T* get() const
|
|
|
|
{
|
2009-10-04 15:34:40 +00:00
|
|
|
pxAssert(m_ptr != NULL);
|
2009-09-29 19:16:00 +00:00
|
|
|
return m_ptr;
|
|
|
|
}
|
|
|
|
|
|
|
|
void swap(pxObjPtr& other)
|
|
|
|
{
|
|
|
|
// Neither pointer in either container should ever be NULL...
|
2009-10-04 15:34:40 +00:00
|
|
|
pxAssert(m_ptr != NULL);
|
|
|
|
pxAssert(other.m_ptr != NULL);
|
2009-09-29 19:16:00 +00:00
|
|
|
|
|
|
|
T * const tmp = other.m_ptr;
|
|
|
|
other.m_ptr = m_ptr;
|
|
|
|
m_ptr = tmp;
|
|
|
|
}
|
|
|
|
};
|
|
|
|
|