1 /////////////////////////////////////////////////////////////////////////////
3 // Purpose: wxTimer implementation
4 // Author: Stefan Csomor
8 // Copyright: (c) Stefan Csomor
9 // Licence: wxWindows licence
10 /////////////////////////////////////////////////////////////////////////////
12 #include "wx/wxprec.h"
16 IMPLEMENT_ABSTRACT_CLASS(wxTimer
, wxEvtHandler
)
19 #include "wx/mac/private.h"
25 #include "wx/dynarray.h"
27 #define wxMAC_USE_CARBON_TIMER 1
29 #if wxMAC_USE_CARBON_TIMER
34 EventLoopTimerUPP m_proc
;
35 EventLoopTimerRef m_timerRef
;
38 static pascal void wxProcessTimer( EventLoopTimerRef theTimer
, void *data
) ;
39 static pascal void wxProcessTimer( EventLoopTimerRef theTimer
, void *data
)
44 wxTimer
* timer
= (wxTimer
*) data
;
46 if ( timer
->IsOneShot() )
54 m_info
= new MacTimerInfo() ;
55 m_info
->m_timer
= this ;
56 m_info
->m_proc
= NULL
;
57 m_info
->m_timerRef
= kInvalidID
;
60 bool wxTimer::IsRunning() const
62 return ( m_info
->m_timerRef
!= kInvalidID
) ;
74 bool wxTimer::Start(int milliseconds
,bool mode
)
76 (void)wxTimerBase::Start(milliseconds
, mode
);
78 wxCHECK_MSG( m_milli
> 0, false, wxT("invalid value for timer timeout") );
79 wxCHECK_MSG( m_info
->m_timerRef
== NULL
, false, wxT("attempting to restart a timer") );
81 m_info
->m_timer
= this ;
82 m_info
->m_proc
= NewEventLoopTimerUPP( &wxProcessTimer
);
83 verify_noerr( InstallEventLoopTimer (
85 m_milli
*kEventDurationMillisecond
,
86 IsOneShot() ? 0 : m_milli
*kEventDurationMillisecond
,
89 &m_info
->m_timerRef
) ) ;
95 if (m_info
->m_timerRef
)
96 RemoveEventLoopTimer( m_info
->m_timerRef
) ;
98 DisposeEventLoopTimerUPP(m_info
->m_proc
) ;
99 m_info
->m_proc
= NULL
;
100 m_info
->m_timerRef
= kInvalidID
;
105 typedef struct MacTimerInfo
108 wxMacNotifierTableRef m_table
;
112 static void wxProcessTimer( unsigned long event
, void *data
) ;
114 static pascal void MacTimerProc( TMTask
* t
)
116 MacTimerInfo
* tm
= (MacTimerInfo
*) t
;
117 wxMacAddEvent( tm
->m_table
, wxProcessTimer
, 0 , (void*) tm
->m_timer
, TRUE
) ;
120 // we need this array to track timers that are being deleted within the Notify procedure
121 // adding the timer before the Notify call and checking after whether it still is in there
122 // as the destructor would have removed it from the array
124 wxArrayPtrVoid gTimersInProcess
;
126 static void wxProcessTimer( unsigned long event
, void *data
)
131 wxTimer
* timer
= (wxTimer
*) data
;
133 if ( timer
->IsOneShot() )
136 gTimersInProcess
.Add( timer
) ;
140 int index
= gTimersInProcess
.Index( timer
) ;
142 if ( index
!= wxNOT_FOUND
)
144 gTimersInProcess
.RemoveAt( index
) ;
146 if ( !timer
->IsOneShot() && timer
->m_info
->m_task
.tmAddr
)
148 PrimeTime( (QElemPtr
) &timer
->m_info
->m_task
, timer
->GetInterval() ) ;
156 m_info
= new MacTimerInfo() ;
157 m_info
->m_task
.tmAddr
= NULL
;
158 m_info
->m_task
.tmWakeUp
= 0 ;
159 m_info
->m_task
.tmReserved
= 0 ;
160 m_info
->m_task
.qType
= 0 ;
161 m_info
->m_table
= wxMacGetNotifierTable() ;
162 m_info
->m_timer
= this ;
165 bool wxTimer::IsRunning() const
167 // as the qType may already indicate it is elapsed, but it
168 // was not handled internally yet
169 return ( m_info
->m_task
.tmAddr
!= NULL
) ;
175 if (m_info
!= NULL
) {
179 int index
= gTimersInProcess
.Index( this ) ;
180 if ( index
!= wxNOT_FOUND
)
181 gTimersInProcess
.RemoveAt( index
) ;
184 bool wxTimer::Start(int milliseconds
,bool mode
)
186 (void)wxTimerBase::Start(milliseconds
, mode
);
188 wxCHECK_MSG( m_milli
> 0, false, wxT("invalid value for timer timeout") );
189 wxCHECK_MSG( m_info
->m_task
.tmAddr
== NULL
, false, wxT("attempting to restart a timer") );
191 m_info
->m_task
.tmAddr
= NewTimerUPP( MacTimerProc
) ;
192 m_info
->m_task
.tmWakeUp
= 0 ;
193 m_info
->m_task
.tmReserved
= 0 ;
194 m_info
->m_task
.qType
= 0 ;
195 m_info
->m_timer
= this ;
196 InsXTime((QElemPtr
) &m_info
->m_task
) ;
197 PrimeTime( (QElemPtr
) &m_info
->m_task
, m_milli
) ;
203 if ( m_info
->m_task
.tmAddr
)
205 RmvTime( (QElemPtr
) &m_info
->m_task
) ;
206 DisposeTimerUPP(m_info
->m_task
.tmAddr
) ;
207 m_info
->m_task
.tmAddr
= NULL
;
209 wxMacRemoveAllNotifiersForData( wxMacGetNotifierTable() , this ) ;