mirror of https://github.com/PCSX2/pcsx2.git
Added some hourglass cursors for various things; renamed more Semaphore and Mutex APIs (I'm too indecisive >_<)
git-svn-id: http://pcsx2.googlecode.com/svn/trunk@2109 96395faa-99c1-11dd-bbfe-3dabce05a288
This commit is contained in:
parent
4e69680c81
commit
376a2c94b1
|
@ -170,8 +170,8 @@ namespace Threading
|
|||
void Post();
|
||||
void Post( int multiple );
|
||||
|
||||
void WaitRaw();
|
||||
bool WaitRaw( const wxTimeSpan& timeout );
|
||||
void WaitWithoutYield();
|
||||
bool WaitWithoutYield( const wxTimeSpan& timeout );
|
||||
void WaitNoCancel();
|
||||
void WaitNoCancel( const wxTimeSpan& timeout );
|
||||
int Count();
|
||||
|
@ -199,8 +199,8 @@ namespace Threading
|
|||
bool TryAcquire();
|
||||
void Release();
|
||||
|
||||
void FullBlockingAcquire();
|
||||
bool FullBlockingAcquire( const wxTimeSpan& timeout );
|
||||
void AcquireWithoutYield();
|
||||
bool AcquireWithoutYield( const wxTimeSpan& timeout );
|
||||
|
||||
void Wait();
|
||||
bool Wait( const wxTimeSpan& timeout );
|
||||
|
|
|
@ -15,7 +15,11 @@
|
|||
|
||||
#pragma once
|
||||
|
||||
#if wxUSE_GUI
|
||||
|
||||
#include "Dependencies.h"
|
||||
#include "ScopedPtr.h"
|
||||
#include <stack>
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
// wxGuiTools.h
|
||||
|
@ -122,6 +126,53 @@ protected:
|
|||
}
|
||||
};
|
||||
|
||||
// --------------------------------------------------------------------------------------
|
||||
// MoreStockCursors
|
||||
// --------------------------------------------------------------------------------------
|
||||
// Because (inexplicably) the ArrowWait cursor isn't in wxWidgets stock list.
|
||||
//
|
||||
class MoreStockCursors
|
||||
{
|
||||
protected:
|
||||
ScopedPtr<wxCursor> m_arrowWait;
|
||||
|
||||
public:
|
||||
MoreStockCursors() { }
|
||||
virtual ~MoreStockCursors() throw() { }
|
||||
const wxCursor& GetArrowWait();
|
||||
};
|
||||
|
||||
enum BusyCursorType
|
||||
{
|
||||
Cursor_NotBusy,
|
||||
Cursor_KindaBusy,
|
||||
Cursor_ReallyBusy,
|
||||
};
|
||||
|
||||
extern MoreStockCursors StockCursors;
|
||||
|
||||
// --------------------------------------------------------------------------------------
|
||||
// ScopedBusyCursor
|
||||
// --------------------------------------------------------------------------------------
|
||||
// ... because wxWidgets wxBusyCursor doesn't really do proper nesting (doesn't let me
|
||||
// override a partially-busy cursor with a really busy one)
|
||||
|
||||
class ScopedBusyCursor
|
||||
{
|
||||
protected:
|
||||
static std::stack<BusyCursorType> m_cursorStack;
|
||||
static BusyCursorType m_defBusyType;
|
||||
|
||||
public:
|
||||
ScopedBusyCursor( BusyCursorType busytype );
|
||||
virtual ~ScopedBusyCursor() throw();
|
||||
|
||||
static void SetDefault( BusyCursorType busytype );
|
||||
static void SetManualBusyCursor( BusyCursorType busytype );
|
||||
};
|
||||
|
||||
|
||||
extern bool pxIsValidWindowPosition( const wxWindow& window, const wxPoint& windowPos );
|
||||
extern wxRect wxGetDisplayArea();
|
||||
|
||||
#endif
|
||||
|
|
|
@ -18,6 +18,7 @@
|
|||
|
||||
#include "Threading.h"
|
||||
#include "wxBaseTools.h"
|
||||
#include "wxGuiTools.h"
|
||||
#include "ThreadingInternal.h"
|
||||
|
||||
namespace Threading
|
||||
|
@ -112,12 +113,13 @@ bool Threading::Mutex::RecreateIfLocked()
|
|||
// if used from the main GUI thread, since it typically results in an unresponsive program.
|
||||
// Call this method directly only if you know the code in question will be run from threads
|
||||
// other than the main thread.
|
||||
void Threading::Mutex::FullBlockingAcquire()
|
||||
void Threading::Mutex::AcquireWithoutYield()
|
||||
{
|
||||
pxAssertMsg( !wxThread::IsMain(), "Unyielding mutex acquire issued from the main/gui thread. Please use Acquire() instead." );
|
||||
pthread_mutex_lock( &m_mutex );
|
||||
}
|
||||
|
||||
bool Threading::Mutex::FullBlockingAcquire( const wxTimeSpan& timeout )
|
||||
bool Threading::Mutex::AcquireWithoutYield( const wxTimeSpan& timeout )
|
||||
{
|
||||
wxDateTime megafail( wxDateTime::UNow() + timeout );
|
||||
const timespec fail = { megafail.GetTicks(), megafail.GetMillisecond() * 1000000 };
|
||||
|
@ -134,7 +136,7 @@ bool Threading::Mutex::TryAcquire()
|
|||
return EBUSY != pthread_mutex_trylock( &m_mutex );
|
||||
}
|
||||
|
||||
// This is a wxApp-safe rendition of FullBlockingAcquire, which makes sure to execute pending app events
|
||||
// This is a wxApp-safe rendition of AcquireWithoutYield, which makes sure to execute pending app events
|
||||
// and messages *if* the lock is performed from the main GUI thread.
|
||||
//
|
||||
// Exceptions:
|
||||
|
@ -145,20 +147,20 @@ void Threading::Mutex::Acquire()
|
|||
#if wxUSE_GUI
|
||||
if( !wxThread::IsMain() || (wxTheApp == NULL) )
|
||||
{
|
||||
FullBlockingAcquire();
|
||||
pthread_mutex_lock( &m_mutex );
|
||||
}
|
||||
else if( _WaitGui_RecursionGuard( "Mutex::Acquire" ) )
|
||||
{
|
||||
if( !FullBlockingAcquire(def_deadlock_timeout) )
|
||||
if( !AcquireWithoutYield(def_deadlock_timeout) )
|
||||
throw Exception::ThreadTimedOut();
|
||||
}
|
||||
else
|
||||
{
|
||||
while( !FullBlockingAcquire(def_yieldgui_interval) )
|
||||
while( !AcquireWithoutYield(def_yieldgui_interval) )
|
||||
wxTheApp->Yield( true );
|
||||
}
|
||||
#else
|
||||
FullBlockingAcquire();
|
||||
pthread_mutex_lock( &m_mutex );
|
||||
#endif
|
||||
}
|
||||
|
||||
|
@ -170,23 +172,26 @@ bool Threading::Mutex::Acquire( const wxTimeSpan& timeout )
|
|||
#if wxUSE_GUI
|
||||
if( !wxThread::IsMain() || (wxTheApp == NULL) )
|
||||
{
|
||||
return FullBlockingAcquire(timeout);
|
||||
return AcquireWithoutYield(timeout);
|
||||
}
|
||||
else if( _WaitGui_RecursionGuard( "Mutex::Acquire(timeout)" ) )
|
||||
{
|
||||
ScopedBusyCursor hourglass( Cursor_ReallyBusy );
|
||||
|
||||
if( timeout > def_deadlock_timeout )
|
||||
{
|
||||
if( FullBlockingAcquire(def_deadlock_timeout) ) return true;
|
||||
if( AcquireWithoutYield(def_deadlock_timeout) ) return true;
|
||||
throw Exception::ThreadTimedOut();
|
||||
}
|
||||
return FullBlockingAcquire( timeout );
|
||||
return AcquireWithoutYield( timeout );
|
||||
}
|
||||
else
|
||||
{
|
||||
ScopedBusyCursor hourglass( Cursor_KindaBusy );
|
||||
wxTimeSpan countdown( (timeout) );
|
||||
|
||||
do {
|
||||
if( FullBlockingAcquire( def_yieldgui_interval ) ) break;
|
||||
if( AcquireWithoutYield( def_yieldgui_interval ) ) break;
|
||||
wxTheApp->Yield(true);
|
||||
countdown -= def_yieldgui_interval;
|
||||
} while( countdown.GetMilliseconds() > 0 );
|
||||
|
@ -198,7 +203,7 @@ bool Threading::Mutex::Acquire( const wxTimeSpan& timeout )
|
|||
throw Exception::ThreadTimedOut();
|
||||
|
||||
#else
|
||||
return FullBlockingAcquire();
|
||||
return AcquireWithoutYield();
|
||||
#endif
|
||||
}
|
||||
|
||||
|
|
|
@ -18,6 +18,7 @@
|
|||
|
||||
#include "Threading.h"
|
||||
#include "wxBaseTools.h"
|
||||
#include "wxGuiTools.h"
|
||||
#include "ThreadingInternal.h"
|
||||
|
||||
// --------------------------------------------------------------------------------------
|
||||
|
@ -59,12 +60,13 @@ void Threading::Semaphore::Post( int multiple )
|
|||
#endif
|
||||
}
|
||||
|
||||
void Threading::Semaphore::WaitRaw()
|
||||
void Threading::Semaphore::WaitWithoutYield()
|
||||
{
|
||||
pxAssertMsg( !wxThread::IsMain(), "Unyielding semaphore wait issued from the main/gui thread. Please use Wait() instead." );
|
||||
sem_wait( &m_sema );
|
||||
}
|
||||
|
||||
bool Threading::Semaphore::WaitRaw( const wxTimeSpan& timeout )
|
||||
bool Threading::Semaphore::WaitWithoutYield( const wxTimeSpan& timeout )
|
||||
{
|
||||
wxDateTime megafail( wxDateTime::UNow() + timeout );
|
||||
const timespec fail = { megafail.GetTicks(), megafail.GetMillisecond() * 1000000 };
|
||||
|
@ -85,24 +87,26 @@ void Threading::Semaphore::Wait()
|
|||
#if wxUSE_GUI
|
||||
if( !wxThread::IsMain() || (wxTheApp == NULL) )
|
||||
{
|
||||
WaitRaw();
|
||||
sem_wait( &m_sema );
|
||||
}
|
||||
else if( _WaitGui_RecursionGuard( "Semaphore::Wait" ) )
|
||||
{
|
||||
if( !WaitRaw(def_yieldgui_interval) ) // default is 4 seconds
|
||||
ScopedBusyCursor hourglass( Cursor_ReallyBusy );
|
||||
if( !WaitWithoutYield(def_yieldgui_interval) ) // default is 4 seconds
|
||||
throw Exception::ThreadTimedOut();
|
||||
}
|
||||
else
|
||||
{
|
||||
while( !WaitRaw( def_yieldgui_interval ) )
|
||||
ScopedBusyCursor hourglass( Cursor_KindaBusy );
|
||||
while( !WaitWithoutYield( def_yieldgui_interval ) )
|
||||
wxTheApp->Yield( true );
|
||||
}
|
||||
#else
|
||||
WaitRaw();
|
||||
sem_wait( &m_sema );
|
||||
#endif
|
||||
}
|
||||
|
||||
// This is a wxApp-safe implementation of WaitRaw, which makes sure and executes the App's
|
||||
// This is a wxApp-safe implementation of WaitWithoutYield, which makes sure and executes the App's
|
||||
// pending messages *if* the Wait is performed on the Main/GUI thread. This ensures that
|
||||
// user input continues to be handled and that windows continue to repaint. If the Wait is
|
||||
// called from another thread, no message pumping is performed.
|
||||
|
@ -119,23 +123,25 @@ bool Threading::Semaphore::Wait( const wxTimeSpan& timeout )
|
|||
#if wxUSE_GUI
|
||||
if( !wxThread::IsMain() || (wxTheApp == NULL) )
|
||||
{
|
||||
return WaitRaw( timeout );
|
||||
return WaitWithoutYield( timeout );
|
||||
}
|
||||
else if( _WaitGui_RecursionGuard( "Semaphore::Wait(timeout)" ) )
|
||||
{
|
||||
ScopedBusyCursor hourglass( Cursor_ReallyBusy );
|
||||
if( timeout > def_deadlock_timeout )
|
||||
{
|
||||
if( WaitRaw(def_deadlock_timeout) ) return true;
|
||||
if( WaitWithoutYield(def_deadlock_timeout) ) return true;
|
||||
throw Exception::ThreadTimedOut();
|
||||
}
|
||||
return WaitRaw( timeout );
|
||||
return WaitWithoutYield( timeout );
|
||||
}
|
||||
else
|
||||
{
|
||||
ScopedBusyCursor hourglass( Cursor_KindaBusy );
|
||||
wxTimeSpan countdown( (timeout) );
|
||||
|
||||
do {
|
||||
if( WaitRaw( def_yieldgui_interval ) ) break;
|
||||
if( WaitWithoutYield( def_yieldgui_interval ) ) break;
|
||||
wxTheApp->Yield(true);
|
||||
countdown -= def_yieldgui_interval;
|
||||
} while( countdown.GetMilliseconds() > 0 );
|
||||
|
@ -143,7 +149,7 @@ bool Threading::Semaphore::Wait( const wxTimeSpan& timeout )
|
|||
return countdown.GetMilliseconds() > 0;
|
||||
}
|
||||
#else
|
||||
return WaitRaw( timeout );
|
||||
return WaitWithoutYield( timeout );
|
||||
#endif
|
||||
}
|
||||
|
||||
|
@ -152,14 +158,14 @@ bool Threading::Semaphore::Wait( const wxTimeSpan& timeout )
|
|||
// the stack and passed to another thread via GUI message or such, avoiding complications where
|
||||
// the thread might be canceled and the stack value becomes invalid.
|
||||
//
|
||||
// Performance note: this function has quite a bit more overhead compared to Semaphore::WaitRaw(), so
|
||||
// consider manually specifying the thread as uncancellable and using WaitRaw() instead if you need
|
||||
// Performance note: this function has quite a bit more overhead compared to Semaphore::WaitWithoutYield(), so
|
||||
// consider manually specifying the thread as uncancellable and using WaitWithoutYield() instead if you need
|
||||
// to do a lot of no-cancel waits in a tight loop worker thread, for example.
|
||||
void Threading::Semaphore::WaitNoCancel()
|
||||
{
|
||||
int oldstate;
|
||||
pthread_setcancelstate( PTHREAD_CANCEL_DISABLE, &oldstate );
|
||||
WaitRaw();
|
||||
WaitWithoutYield();
|
||||
pthread_setcancelstate( oldstate, NULL );
|
||||
}
|
||||
|
||||
|
@ -167,7 +173,7 @@ void Threading::Semaphore::WaitNoCancel( const wxTimeSpan& timeout )
|
|||
{
|
||||
int oldstate;
|
||||
pthread_setcancelstate( PTHREAD_CANCEL_DISABLE, &oldstate );
|
||||
WaitRaw( timeout );
|
||||
WaitWithoutYield( timeout );
|
||||
pthread_setcancelstate( oldstate, NULL );
|
||||
}
|
||||
|
||||
|
|
|
@ -496,7 +496,7 @@ void Threading::BaseTaskThread::WaitForResult()
|
|||
#ifdef wxUSE_GUI
|
||||
m_post_TaskComplete.Wait();
|
||||
#else
|
||||
m_post_TaskComplete.WaitRaw();
|
||||
m_post_TaskComplete.WaitWithoutYield();
|
||||
#endif
|
||||
|
||||
m_post_TaskComplete.Reset();
|
||||
|
@ -507,7 +507,7 @@ void Threading::BaseTaskThread::ExecuteTaskInThread()
|
|||
while( !m_Done )
|
||||
{
|
||||
// Wait for a job -- or get a pthread_cancel. I'm easy.
|
||||
m_sem_event.WaitRaw();
|
||||
m_sem_event.WaitWithoutYield();
|
||||
|
||||
Task();
|
||||
m_lock_TaskComplete.Acquire();
|
||||
|
|
|
@ -16,6 +16,7 @@
|
|||
#include "PrecompiledHeader.h"
|
||||
#include "wxGuiTools.h"
|
||||
|
||||
#include <wx/app.h>
|
||||
#include <wx/window.h>
|
||||
|
||||
// Returns FALSE if the window position is considered invalid, which means that it's title
|
||||
|
@ -39,3 +40,70 @@ wxRect wxGetDisplayArea()
|
|||
return wxRect( wxPoint(), wxGetDisplaySize() );
|
||||
}
|
||||
|
||||
// --------------------------------------------------------------------------------------
|
||||
// ScopedBusyCursor Implementations
|
||||
// --------------------------------------------------------------------------------------
|
||||
|
||||
std::stack<BusyCursorType> ScopedBusyCursor::m_cursorStack;
|
||||
BusyCursorType ScopedBusyCursor::m_defBusyType;
|
||||
|
||||
ScopedBusyCursor::ScopedBusyCursor( BusyCursorType busytype )
|
||||
{
|
||||
pxAssert( wxTheApp != NULL );
|
||||
|
||||
BusyCursorType curtype = Cursor_NotBusy;
|
||||
if( !m_cursorStack.empty() )
|
||||
curtype = m_cursorStack.top();
|
||||
|
||||
if( curtype < busytype )
|
||||
SetManualBusyCursor( curtype=busytype );
|
||||
|
||||
m_cursorStack.push( curtype );
|
||||
}
|
||||
|
||||
ScopedBusyCursor::~ScopedBusyCursor() throw()
|
||||
{
|
||||
if( !pxAssert( wxTheApp != NULL ) ) return;
|
||||
|
||||
if( !pxAssert( !m_cursorStack.empty() ) )
|
||||
{
|
||||
SetManualBusyCursor( m_defBusyType );
|
||||
return;
|
||||
}
|
||||
|
||||
BusyCursorType curtype = m_cursorStack.top();
|
||||
m_cursorStack.pop();
|
||||
|
||||
if( m_cursorStack.empty() )
|
||||
SetManualBusyCursor( m_defBusyType );
|
||||
else if( m_cursorStack.top() != curtype )
|
||||
SetManualBusyCursor( m_cursorStack.top() );
|
||||
}
|
||||
|
||||
void ScopedBusyCursor::SetDefault( BusyCursorType busytype )
|
||||
{
|
||||
if( busytype == m_defBusyType ) return;
|
||||
m_defBusyType = busytype;
|
||||
|
||||
if( m_cursorStack.empty() )
|
||||
SetManualBusyCursor( busytype );
|
||||
}
|
||||
|
||||
void ScopedBusyCursor::SetManualBusyCursor( BusyCursorType busytype )
|
||||
{
|
||||
switch( busytype )
|
||||
{
|
||||
case Cursor_NotBusy: wxSetCursor( wxNullCursor ); break;
|
||||
case Cursor_KindaBusy: wxSetCursor( StockCursors.GetArrowWait() ); break;
|
||||
case Cursor_ReallyBusy: wxSetCursor( *wxHOURGLASS_CURSOR ); break;
|
||||
}
|
||||
}
|
||||
|
||||
const wxCursor& MoreStockCursors::GetArrowWait()
|
||||
{
|
||||
if( !m_arrowWait )
|
||||
m_arrowWait = new wxCursor( wxCURSOR_ARROWWAIT );
|
||||
return *m_arrowWait;
|
||||
}
|
||||
|
||||
MoreStockCursors StockCursors;
|
||||
|
|
|
@ -246,7 +246,7 @@ void mtgsThreadObject::ExecuteTaskInThread()
|
|||
// is very optimized (only 1 instruction test in most cases), so no point in trying
|
||||
// to avoid it.
|
||||
|
||||
m_sem_event.WaitRaw();
|
||||
m_sem_event.WaitWithoutYield();
|
||||
StateCheckInThread();
|
||||
|
||||
m_RingBufferIsBusy = true;
|
||||
|
|
|
@ -232,7 +232,7 @@ void SysCoreThread::ExecuteTaskInThread()
|
|||
|
||||
tls_coreThread = this;
|
||||
|
||||
m_sem_event.WaitRaw();
|
||||
m_sem_event.WaitWithoutYield();
|
||||
PCSX2_PAGEFAULT_PROTECT {
|
||||
StateCheckInThread();
|
||||
Cpu->Execute();
|
||||
|
|
|
@ -40,7 +40,7 @@ void SysThreadBase::Start()
|
|||
|
||||
Sleep( 1 );
|
||||
|
||||
if( !m_ResumeEvent.WaitRaw( wxTimeSpan(0, 0, 1, 500) ) )
|
||||
if( !m_ResumeEvent.WaitWithoutYield( wxTimeSpan(0, 0, 1, 500) ) )
|
||||
{
|
||||
RethrowException();
|
||||
if( pxAssertDev( m_ExecMode == ExecMode_Closing, "Unexpected thread status during SysThread startup." ) )
|
||||
|
@ -103,16 +103,19 @@ bool SysThreadBase::Suspend( bool isBlocking )
|
|||
{
|
||||
ScopedLock locker( m_ExecModeMutex );
|
||||
|
||||
// Check again -- status could have changed since above.
|
||||
if( m_ExecMode == ExecMode_Closed ) return false;
|
||||
|
||||
if( m_ExecMode == ExecMode_Pausing || m_ExecMode == ExecMode_Paused )
|
||||
throw Exception::CancelEvent( "Another thread is pausing the VM state." );
|
||||
|
||||
if( m_ExecMode == ExecMode_Opened )
|
||||
switch( m_ExecMode )
|
||||
{
|
||||
m_ExecMode = ExecMode_Closing;
|
||||
retval = true;
|
||||
// Check again -- status could have changed since above.
|
||||
case ExecMode_Closed: return false;
|
||||
|
||||
case ExecMode_Pausing:
|
||||
case ExecMode_Paused:
|
||||
throw Exception::CancelEvent( "Another thread is pausing the VM state." );
|
||||
|
||||
case ExecMode_Opened:
|
||||
m_ExecMode = ExecMode_Closing;
|
||||
retval = true;
|
||||
break;
|
||||
}
|
||||
|
||||
pxAssertDev( m_ExecMode == ExecMode_Closing, "ExecMode should be nothing other than Closing..." );
|
||||
|
@ -198,7 +201,7 @@ void SysThreadBase::Resume()
|
|||
// The entire state coming out of a Wait is indeterminate because of user input
|
||||
// and pending messages being handled. So after each call we do some seemingly redundant
|
||||
// sanity checks against m_ExecMode/m_Running status, and if something doesn't feel
|
||||
// right, we should abort.
|
||||
// right, we should abort; the user may have canceled the action before it even finished.
|
||||
|
||||
switch( m_ExecMode )
|
||||
{
|
||||
|
@ -206,10 +209,6 @@ void SysThreadBase::Resume()
|
|||
|
||||
case ExecMode_NoThreadYet:
|
||||
{
|
||||
/*static int __Guard = 0;
|
||||
RecursionGuard guard( __Guard );
|
||||
if( guard.IsReentrant() ) return;*/
|
||||
|
||||
Start();
|
||||
if( !m_running || (m_ExecMode == ExecMode_NoThreadYet) )
|
||||
throw Exception::ThreadCreationError();
|
||||
|
@ -290,7 +289,7 @@ void SysThreadBase::StateCheckInThread()
|
|||
|
||||
case ExecMode_Paused:
|
||||
while( m_ExecMode == ExecMode_Paused )
|
||||
m_ResumeEvent.WaitRaw();
|
||||
m_ResumeEvent.WaitWithoutYield();
|
||||
|
||||
m_RunningLock.Acquire();
|
||||
OnResumeInThread( false );
|
||||
|
@ -307,7 +306,7 @@ void SysThreadBase::StateCheckInThread()
|
|||
|
||||
case ExecMode_Closed:
|
||||
while( m_ExecMode == ExecMode_Closed )
|
||||
m_ResumeEvent.WaitRaw();
|
||||
m_ResumeEvent.WaitWithoutYield();
|
||||
|
||||
m_RunningLock.Acquire();
|
||||
OnResumeInThread( true );
|
||||
|
|
|
@ -29,6 +29,8 @@ AppCoreThread::~AppCoreThread() throw()
|
|||
|
||||
void AppCoreThread::Reset()
|
||||
{
|
||||
ScopedBusyCursor::SetDefault( Cursor_KindaBusy );
|
||||
|
||||
_parent::Reset();
|
||||
|
||||
wxCommandEvent evt( pxEVT_CoreThreadStatus );
|
||||
|
@ -38,6 +40,7 @@ void AppCoreThread::Reset()
|
|||
|
||||
bool AppCoreThread::Suspend( bool isBlocking )
|
||||
{
|
||||
ScopedBusyCursor::SetDefault( Cursor_KindaBusy );
|
||||
bool retval = _parent::Suspend( isBlocking );
|
||||
|
||||
// Clear the sticky key statuses, because hell knows what'll change while the PAD
|
||||
|
@ -67,6 +70,7 @@ void AppCoreThread::Resume()
|
|||
return;
|
||||
}
|
||||
|
||||
ScopedBusyCursor::SetDefault( Cursor_KindaBusy );
|
||||
_parent::Resume();
|
||||
|
||||
if( m_ExecMode != ExecMode_Opened )
|
||||
|
|
|
@ -138,6 +138,7 @@ void Pcsx2App::Ping() const
|
|||
void Pcsx2App::OnCoreThreadStatus( wxCommandEvent& evt )
|
||||
{
|
||||
m_evtsrc_CoreThreadStatus.Dispatch( evt );
|
||||
ScopedBusyCursor::SetDefault( Cursor_NotBusy );
|
||||
}
|
||||
|
||||
void Pcsx2App::OnSemaphorePing( wxCommandEvent& evt )
|
||||
|
@ -497,9 +498,11 @@ void Pcsx2App::SysExecute( CDVD_SourceType cdvdsrc, const wxString& elf_override
|
|||
|
||||
// This message performs actual system execution (as dictated by SysExecute variants).
|
||||
// It is implemented as a message handler so that it can be triggered in response to
|
||||
// the completion of other dependent activites, namely loading plugins.
|
||||
// the completion of other dependent activities, namely loading plugins.
|
||||
void Pcsx2App::OnSysExecute( wxCommandEvent& evt )
|
||||
{
|
||||
CoreThread.ReleaseResumeLock();
|
||||
|
||||
if( sys_resume_lock > 0 )
|
||||
{
|
||||
Console.WriteLn( "SysExecute: State is locked, ignoring Execute request!" );
|
||||
|
@ -520,7 +523,6 @@ void Pcsx2App::OnSysExecute( wxCommandEvent& evt )
|
|||
if( !CoreThread.HasValidState() )
|
||||
CoreThread.SetElfOverride( _sysexec_elf_override );
|
||||
|
||||
CoreThread.ReleaseResumeLock();
|
||||
CoreThread.Resume();
|
||||
}
|
||||
|
||||
|
@ -528,6 +530,7 @@ void Pcsx2App::OnSysExecute( wxCommandEvent& evt )
|
|||
void Pcsx2App::SysReset()
|
||||
{
|
||||
CoreThread.Reset();
|
||||
CoreThread.ReleaseResumeLock();
|
||||
m_CorePlugins = NULL;
|
||||
}
|
||||
|
||||
|
|
|
@ -410,8 +410,8 @@ namespace Panels
|
|||
SafeList<EnumeratedPluginInfo> Results; // array of plugin results.
|
||||
|
||||
protected:
|
||||
PluginSelectorPanel& m_master;
|
||||
|
||||
PluginSelectorPanel& m_master;
|
||||
ScopedBusyCursor m_hourglass;
|
||||
public:
|
||||
virtual ~EnumThread() throw()
|
||||
{
|
||||
|
|
|
@ -545,6 +545,7 @@ Panels::PluginSelectorPanel::EnumThread::EnumThread( PluginSelectorPanel& master
|
|||
PersistentThread()
|
||||
, Results( master.FileCount(), L"PluginSelectorResults" )
|
||||
, m_master( master )
|
||||
, m_hourglass( Cursor_KindaBusy )
|
||||
{
|
||||
Results.MatchLengthToAllocatedSize();
|
||||
}
|
||||
|
|
|
@ -93,10 +93,10 @@ public:
|
|||
PluginManager* Result;
|
||||
|
||||
protected:
|
||||
wxString m_folders[PluginId_Count];
|
||||
|
||||
wxString m_folders[PluginId_Count];
|
||||
ScopedBusyCursor m_hourglass;
|
||||
public:
|
||||
LoadPluginsTask( const wxString (&folders)[PluginId_Count] ) : Result( NULL )
|
||||
LoadPluginsTask( const wxString (&folders)[PluginId_Count] ) : Result( NULL ), m_hourglass( Cursor_KindaBusy )
|
||||
{
|
||||
for(int i=0; i<PluginId_Count; ++i )
|
||||
m_folders[i] = folders[i];
|
||||
|
|
Loading…
Reference in New Issue