1 /////////////////////////////////////////////////////////////////////////////
3 // Purpose: wxTimer implementation
4 // Author: Stefan Csomor
8 // Copyright: (c) Stefan Csomor
9 // Licence: wxWindows licence
10 /////////////////////////////////////////////////////////////////////////////
12 #if defined(__GNUG__) && !defined(NO_GCC_PRAGMA)
13 #pragma implementation "timer.h"
16 #include "wx/wxprec.h"
20 #if !USE_SHARED_LIBRARY
21 IMPLEMENT_ABSTRACT_CLASS(wxTimer
, wxEvtHandler
)
25 #include "wx/mac/private.h"
31 #include "wx/dynarray.h"
33 #define wxMAC_USE_CARBON_TIMER 1
35 #if wxMAC_USE_CARBON_TIMER
37 typedef struct MacTimerInfo
40 EventLoopTimerUPP m_proc
;
41 EventLoopTimerRef m_timerRef
;
44 static pascal void wxProcessTimer( EventLoopTimerRef theTimer
, void *data
) ;
45 static pascal void wxProcessTimer( EventLoopTimerRef theTimer
, void *data
)
50 wxTimer
* timer
= (wxTimer
*) data
;
52 if ( timer
->IsOneShot() )
60 m_info
= new MacTimerInfo() ;
61 m_info
->m_timer
= this ;
62 m_info
->m_proc
= NULL
;
63 m_info
->m_timerRef
= kInvalidID
;
66 bool wxTimer::IsRunning() const
68 return ( m_info
->m_timerRef
!= kInvalidID
) ;
80 bool wxTimer::Start(int milliseconds
,bool mode
)
82 (void)wxTimerBase::Start(milliseconds
, mode
);
84 wxCHECK_MSG( m_milli
> 0, FALSE
, wxT("invalid value for timer timeout") );
85 wxCHECK_MSG( m_info
->m_timerRef
== NULL
, FALSE
, wxT("attempting to restart a timer") );
87 m_info
->m_timer
= this ;
88 m_info
->m_proc
= NewEventLoopTimerUPP( &wxProcessTimer
);
89 verify_noerr( InstallEventLoopTimer (
91 m_milli
*kEventDurationMillisecond
,
92 IsOneShot() ? 0 : m_milli
*kEventDurationMillisecond
,
95 &m_info
->m_timerRef
) ) ;
101 if (m_info
->m_timerRef
)
102 RemoveEventLoopTimer( m_info
->m_timerRef
) ;
104 DisposeEventLoopTimerUPP(m_info
->m_proc
) ;
105 m_info
->m_proc
= NULL
;
106 m_info
->m_timerRef
= kInvalidID
;
111 typedef struct MacTimerInfo
114 wxMacNotifierTableRef m_table
;
118 static void wxProcessTimer( unsigned long event
, void *data
) ;
120 static pascal void MacTimerProc( TMTask
* t
)
122 MacTimerInfo
* tm
= (MacTimerInfo
*) t
;
123 wxMacAddEvent( tm
->m_table
, wxProcessTimer
, 0 , (void*) tm
->m_timer
, TRUE
) ;
126 // we need this array to track timers that are being deleted within the Notify procedure
127 // adding the timer before the Notify call and checking after whether it still is in there
128 // as the destructor would have removed it from the array
130 wxArrayPtrVoid gTimersInProcess
;
132 static void wxProcessTimer( unsigned long event
, void *data
)
137 wxTimer
* timer
= (wxTimer
*) data
;
139 if ( timer
->IsOneShot() )
142 gTimersInProcess
.Add( timer
) ;
146 int index
= gTimersInProcess
.Index( timer
) ;
148 if ( index
!= wxNOT_FOUND
)
150 gTimersInProcess
.RemoveAt( index
) ;
152 if ( !timer
->IsOneShot() && timer
->m_info
->m_task
.tmAddr
)
154 PrimeTime( (QElemPtr
) &timer
->m_info
->m_task
, timer
->GetInterval() ) ;
162 m_info
= new MacTimerInfo() ;
163 m_info
->m_task
.tmAddr
= NULL
;
164 m_info
->m_task
.tmWakeUp
= 0 ;
165 m_info
->m_task
.tmReserved
= 0 ;
166 m_info
->m_task
.qType
= 0 ;
167 m_info
->m_table
= wxMacGetNotifierTable() ;
168 m_info
->m_timer
= this ;
171 bool wxTimer::IsRunning() const
173 // as the qType may already indicate it is elapsed, but it
174 // was not handled internally yet
175 return ( m_info
->m_task
.tmAddr
!= NULL
) ;
181 if (m_info
!= NULL
) {
185 int index
= gTimersInProcess
.Index( this ) ;
186 if ( index
!= wxNOT_FOUND
)
187 gTimersInProcess
.RemoveAt( index
) ;
190 bool wxTimer::Start(int milliseconds
,bool mode
)
192 (void)wxTimerBase::Start(milliseconds
, mode
);
194 wxCHECK_MSG( m_milli
> 0, FALSE
, wxT("invalid value for timer timeout") );
195 wxCHECK_MSG( m_info
->m_task
.tmAddr
== NULL
, FALSE
, wxT("attempting to restart a timer") );
197 m_info
->m_task
.tmAddr
= NewTimerUPP( MacTimerProc
) ;
198 m_info
->m_task
.tmWakeUp
= 0 ;
199 m_info
->m_task
.tmReserved
= 0 ;
200 m_info
->m_task
.qType
= 0 ;
201 m_info
->m_timer
= this ;
202 InsXTime((QElemPtr
) &m_info
->m_task
) ;
203 PrimeTime( (QElemPtr
) &m_info
->m_task
, m_milli
) ;
209 if ( m_info
->m_task
.tmAddr
)
211 RmvTime( (QElemPtr
) &m_info
->m_task
) ;
212 DisposeTimerUPP(m_info
->m_task
.tmAddr
) ;
213 m_info
->m_task
.tmAddr
= NULL
;
215 wxMacRemoveAllNotifiersForData( wxMacGetNotifierTable() , this ) ;