X-Git-Url: https://git.saurik.com/wxWidgets.git/blobdiff_plain/272ebf16f85536aced3277ebd69e0c70eabf8d0a..ad3628fa86caa8eb9ded43eacb115f44558eb1ee:/src/os2/timer.cpp diff --git a/src/os2/timer.cpp b/src/os2/timer.cpp index f102ace512..46f01a8ded 100644 --- a/src/os2/timer.cpp +++ b/src/os2/timer.cpp @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Name: timer.cpp +// Name: src/os2/timer.cpp // Purpose: wxTimer implementation // Author: David Webster // Modified by: @@ -9,58 +9,72 @@ // Licence: wxWindows licence ///////////////////////////////////////////////////////////////////////////// -#ifdef __GNUG__ - #pragma implementation "timer.h" -#endif - // For compilers that support precompilation, includes "wx.h". #include "wx/wxprec.h" -#include "wx/window.h" -#include "wx/os2/private.h" +#include "wx/os2/private/timer.h" #ifndef WX_PRECOMP - #include "wx/setup.h" #include "wx/list.h" + #include "wx/window.h" #include "wx/event.h" #include "wx/app.h" + #include "wx/intl.h" + #include "wx/log.h" #endif -#include "wx/intl.h" -#include "wx/log.h" - -#include "wx/timer.h" +#include "wx/os2/private.h" #include #include #include + +// ---------------------------------------------------------------------------- +// private globals +// ---------------------------------------------------------------------------- + +// define a hash containing all the timers: it is indexed by timer id and +// contains the corresponding timer +WX_DECLARE_HASH_MAP(unsigned long, wxOS2TimerImpl *, wxIntegerHash, wxIntegerEqual, + wxTimerMap); + +// instead of using a global here, wrap it in a static function as otherwise it +// could have been used before being initialized if a timer object were created +// globally +static wxTimerMap& TimerMap() +{ + static wxTimerMap s_timerMap; + + return s_timerMap; +} + // ---------------------------------------------------------------------------- // private functions // ---------------------------------------------------------------------------- -wxList wxTimerList(wxKEY_INTEGER); +// timer callback used for all timers ULONG wxTimerProc(HWND hwnd, ULONG, int nIdTimer, ULONG); +// ============================================================================ +// implementation +// ============================================================================ + // ---------------------------------------------------------------------------- -// macros +// wxTimer class // ---------------------------------------------------------------------------- -IMPLEMENT_ABSTRACT_CLASS(wxTimer, wxObject) - -void wxTimer::Init() +void wxOS2TimerImpl::Init() { m_ulId = 0; } -wxTimer::~wxTimer() +wxOS2TimerImpl::~wxOS2TimerImpl() { - wxTimer::Stop(); - - wxTimerList.DeleteObject(this); + wxOS2TimerImpl::Stop(); } -void wxTimer::Notify() +void wxOS2TimerImpl::Notify() { // // The base class version generates an event if it has owner - which it @@ -76,20 +90,13 @@ void wxTimer::Notify() (void)m_owner->ProcessEvent(vEvent); } // end of wxTimer::Notify -bool wxTimer::Start( - int nMilliseconds -, bool bOneShot -) +bool wxOS2TimerImpl::Start( int nMilliseconds, bool bOneShot ) { - (void)wxTimerBase::Start( nMilliseconds - ,bOneShot - ); + (void)wxTimerImpl::Start( nMilliseconds, bOneShot ); - wxCHECK_MSG( m_milli > 0L, FALSE, wxT("invalid value for timer") ); + wxCHECK_MSG( m_milli > 0L, false, wxT("invalid value for timer") ); - wxTimerList.DeleteObject(this); - - wxWindow* pWin = NULL; + wxWindow* pWin = NULL; if (m_owner) { @@ -108,20 +115,33 @@ bool wxTimer::Start( ); if (m_ulId > 0L) { - wxTimerList.Append( m_ulId - ,this - ); - return(TRUE); + // check that SetTimer() didn't reuse an existing id: according to + // the MSDN this can happen and this would be catastrophic to us as + // we rely on ids uniquely identifying the timers because we use + // them as keys in the hash + if ( TimerMap().find(m_ulId) != TimerMap().end() ) + { + wxLogError(_("Timer creation failed.")); + + ::WinStopTimer(m_Hab, pWin?(pWin->GetHWND()):NULL, m_ulId); + m_ulId = 0; + + return false; + } + + TimerMap()[m_ulId] = this; + + return true; } else { wxLogSysError(_("Couldn't create a timer")); - return(FALSE); + return false; } } -void wxTimer::Stop() +void wxOS2TimerImpl::Stop() { if ( m_ulId ) { @@ -133,7 +153,8 @@ void wxTimer::Stop() } else ::WinStopTimer(m_Hab, NULLHANDLE, m_ulId); - wxTimerList.DeleteObject(this); + + TimerMap().erase(m_ulId); } m_ulId = 0L; } @@ -143,7 +164,7 @@ void wxTimer::Stop() // ---------------------------------------------------------------------------- void wxProcessTimer( - wxTimer& rTimer + wxOS2TimerImpl& rTimer ) { // @@ -165,11 +186,10 @@ ULONG wxTimerProc( , ULONG ) { - wxNode* pNode = wxTimerList.Find((ULONG)nIdTimer); + wxTimerMap::iterator node = TimerMap().find((ULONG)nIdTimer); - wxCHECK_MSG(pNode, 0, wxT("bogus timer id in wxTimerProc") ); - if (pNode) - wxProcessTimer(*(wxTimer *)pNode->Data()); + wxCHECK_MSG(node != TimerMap().end(), 0, + wxT("bogus timer id in wxTimerProc") ); + wxProcessTimer(*(node->second)); return 0; } -