1 /////////////////////////////////////////////////////////////////////////////
3 // Purpose: wxTimer implementation
4 // Author: Stefan Csomor
8 // Copyright: (c) Stefan Csomor
9 // Licence: wxWindows licence
10 /////////////////////////////////////////////////////////////////////////////
13 #pragma implementation "timer.h"
18 #if !USE_SHARED_LIBRARY
19 IMPLEMENT_ABSTRACT_CLASS(wxTimer
, wxEvtHandler
)
23 #include "wx/mac/private.h"
29 #include "wx/dynarray.h"
31 #define wxMAC_USE_CARBON_TIMER 1
33 #if wxMAC_USE_CARBON_TIMER
35 typedef struct MacTimerInfo
38 EventLoopTimerUPP m_proc
;
39 EventLoopTimerRef m_timerRef
;
42 static pascal void wxProcessTimer( EventLoopTimerRef theTimer
, void *data
) ;
43 static pascal void wxProcessTimer( EventLoopTimerRef theTimer
, void *data
)
48 wxTimer
* timer
= (wxTimer
*) data
;
50 if ( timer
->IsOneShot() )
58 m_info
= new MacTimerInfo() ;
59 m_info
->m_timer
= this ;
60 m_info
->m_proc
= NULL
;
61 m_info
->m_timerRef
= kInvalidID
;
64 bool wxTimer::IsRunning() const
66 return ( m_info
->m_timerRef
!= kInvalidID
) ;
78 bool wxTimer::Start(int milliseconds
,bool mode
)
80 (void)wxTimerBase::Start(milliseconds
, mode
);
82 wxCHECK_MSG( m_milli
> 0, FALSE
, wxT("invalid value for timer timeout") );
83 wxCHECK_MSG( m_info
->m_timerRef
== NULL
, FALSE
, wxT("attempting to restart a timer") );
85 m_info
->m_timer
= this ;
86 m_info
->m_proc
= NewEventLoopTimerUPP( &wxProcessTimer
);
87 verify_noerr( InstallEventLoopTimer (
89 m_milli
*kEventDurationMillisecond
,
90 IsOneShot() ? 0 : m_milli
*kEventDurationMillisecond
,
93 &m_info
->m_timerRef
) ) ;
99 if (m_info
->m_timerRef
)
100 RemoveEventLoopTimer( m_info
->m_timerRef
) ;
102 DisposeEventLoopTimerUPP(m_info
->m_proc
) ;
103 m_info
->m_proc
= NULL
;
104 m_info
->m_timerRef
= kInvalidID
;
109 typedef struct MacTimerInfo
112 wxMacNotifierTableRef m_table
;
116 static void wxProcessTimer( unsigned long event
, void *data
) ;
118 static pascal void MacTimerProc( TMTask
* t
)
120 MacTimerInfo
* tm
= (MacTimerInfo
*) t
;
121 wxMacAddEvent( tm
->m_table
, wxProcessTimer
, 0 , (void*) tm
->m_timer
, TRUE
) ;
124 // we need this array to track timers that are being deleted within the Notify procedure
125 // adding the timer before the Notify call and checking after whether it still is in there
126 // as the destructor would have removed it from the array
128 wxArrayPtrVoid gTimersInProcess
;
130 static void wxProcessTimer( unsigned long event
, void *data
)
135 wxTimer
* timer
= (wxTimer
*) data
;
137 if ( timer
->IsOneShot() )
140 gTimersInProcess
.Add( timer
) ;
144 int index
= gTimersInProcess
.Index( timer
) ;
146 if ( index
!= wxNOT_FOUND
)
148 gTimersInProcess
.RemoveAt( index
) ;
150 if ( !timer
->IsOneShot() && timer
->m_info
->m_task
.tmAddr
)
152 PrimeTime( (QElemPtr
) &timer
->m_info
->m_task
, timer
->GetInterval() ) ;
160 m_info
= new MacTimerInfo() ;
161 m_info
->m_task
.tmAddr
= NULL
;
162 m_info
->m_task
.tmWakeUp
= 0 ;
163 m_info
->m_task
.tmReserved
= 0 ;
164 m_info
->m_task
.qType
= 0 ;
165 m_info
->m_table
= wxMacGetNotifierTable() ;
166 m_info
->m_timer
= this ;
169 bool wxTimer::IsRunning() const
171 // as the qType may already indicate it is elapsed, but it
172 // was not handled internally yet
173 return ( m_info
->m_task
.tmAddr
!= NULL
) ;
179 if (m_info
!= NULL
) {
183 int index
= gTimersInProcess
.Index( this ) ;
184 if ( index
!= wxNOT_FOUND
)
185 gTimersInProcess
.RemoveAt( index
) ;
188 bool wxTimer::Start(int milliseconds
,bool mode
)
190 (void)wxTimerBase::Start(milliseconds
, mode
);
192 wxCHECK_MSG( m_milli
> 0, FALSE
, wxT("invalid value for timer timeout") );
193 wxCHECK_MSG( m_info
->m_task
.tmAddr
== NULL
, FALSE
, wxT("attempting to restart a timer") );
195 m_info
->m_task
.tmAddr
= NewTimerUPP( MacTimerProc
) ;
196 m_info
->m_task
.tmWakeUp
= 0 ;
197 m_info
->m_task
.tmReserved
= 0 ;
198 m_info
->m_task
.qType
= 0 ;
199 m_info
->m_timer
= this ;
200 InsXTime((QElemPtr
) &m_info
->m_task
) ;
201 PrimeTime( (QElemPtr
) &m_info
->m_task
, m_milli
) ;
207 if ( m_info
->m_task
.tmAddr
)
209 RmvTime( (QElemPtr
) &m_info
->m_task
) ;
210 DisposeTimerUPP(m_info
->m_task
.tmAddr
) ;
211 m_info
->m_task
.tmAddr
= NULL
;
213 wxMacRemoveAllNotifiersForData( wxMacGetNotifierTable() , this ) ;