]>
git.saurik.com Git - wxWidgets.git/blob - src/unix/timerunx.cpp
1 /////////////////////////////////////////////////////////////////////////////
2 // Name: src/unix/timerunx.cpp
3 // Purpose: wxTimer implementation for non-GUI applications under Unix
4 // Author: Lukasz Michalski
7 // Copyright: (c) 2007 Lukasz Michalski
8 // Licence: wxWindows licence
9 /////////////////////////////////////////////////////////////////////////////
11 // ============================================================================
13 // ============================================================================
15 // ----------------------------------------------------------------------------
17 // ----------------------------------------------------------------------------
19 #include "wx/wxprec.h"
25 #include "wx/module.h"
28 #include "wx/hashmap.h"
32 #include "wx/longlong.h"
37 #include "wx/unix/private/timer.h"
39 #include "wx/listimpl.cpp"
40 WX_DEFINE_LIST(wxTimerList
);
42 // trace mask for the debugging messages used here
43 #define wxTrace_Timer wxT("timer")
45 // ----------------------------------------------------------------------------
47 // ----------------------------------------------------------------------------
49 // helper function to format wxUsecClock_t
50 static inline wxString
wxUsecClockAsString(wxUsecClock_t usec
)
53 return usec
.ToString();
54 #else // wxUsecClock_t == double
55 return wxString::Format(_T("%.0f"), usec
);
59 // ============================================================================
60 // wxTimerScheduler implementation
61 // ============================================================================
63 wxTimerScheduler
*wxTimerScheduler::ms_instance
= NULL
;
65 wxTimerScheduler::~wxTimerScheduler()
67 for ( wxTimerList::iterator node
= m_timers
.begin();
68 node
!= m_timers
.end();
75 void wxTimerScheduler::AddTimer(wxUnixTimerImpl
*timer
, wxUsecClock_t expiration
)
77 DoAddTimer(new wxTimerSchedule(timer
, expiration
));
80 void wxTimerScheduler::DoAddTimer(wxTimerSchedule
*s
)
82 // do an insertion sort to keep the list sorted in expiration order
83 wxTimerList::iterator node
;
84 for ( node
= m_timers
.begin(); node
!= m_timers
.end(); ++node
)
86 wxASSERT_MSG( (*node
)->m_timer
!= s
->m_timer
,
87 _T("adding the same timer twice?") );
89 if ( (*node
)->m_expiration
> s
->m_expiration
)
93 m_timers
.insert(node
, s
);
95 wxLogTrace(wxTrace_Timer
, wxT("Inserted timer %d expiring at %s"),
97 wxUsecClockAsString(s
->m_expiration
).c_str());
100 void wxTimerScheduler::RemoveTimer(wxUnixTimerImpl
*timer
)
102 wxLogTrace(wxTrace_Timer
, wxT("Removing timer %d"), timer
->GetId());
104 for ( wxTimerList::iterator node
= m_timers
.begin();
105 node
!= m_timers
.end();
108 if ( (*node
)->m_timer
== timer
)
111 m_timers
.erase(node
);
116 wxFAIL_MSG( _T("removing inexistent timer?") );
119 bool wxTimerScheduler::GetNext(wxUsecClock_t
*remaining
) const
121 if ( m_timers
.empty() )
124 wxCHECK_MSG( remaining
, false, _T("NULL pointer") );
126 *remaining
= (*m_timers
.begin())->m_expiration
- wxGetLocalTimeUsec();
127 if ( *remaining
< 0 )
129 // timer already expired, don't wait at all before notifying it
136 void wxTimerScheduler::NotifyExpired()
138 if ( m_timers
.empty() )
141 const wxUsecClock_t now
= wxGetLocalTimeUsec();
143 wxTimerList::iterator cur
,
145 for ( cur
= m_timers
.begin(); cur
!= m_timers
.end(); cur
= next
)
147 wxTimerSchedule
* const s
= *cur
;
148 if ( s
->m_expiration
> now
)
150 // as the list is sorted by expiration time, we can skip the rest
154 // remember next as we will delete the node pointed to by cur
160 // check whether we need to keep this timer
161 wxUnixTimerImpl
* const timer
= s
->m_timer
;
162 if ( timer
->IsOneShot() )
164 // the timer needs to be stopped but don't call its Stop() from
165 // here as it would attempt to remove the timer from our list and
166 // we had already done it, so we just need to reset its state
167 timer
->MarkStopped();
169 // don't need it any more
172 else // reschedule the next timer expiration
174 s
->m_expiration
+= timer
->GetInterval()*1000;
178 // and finally notify the timer
183 // ============================================================================
184 // wxUnixTimerImpl implementation
185 // ============================================================================
187 wxUnixTimerImpl::wxUnixTimerImpl(wxTimer
* timer
)
193 bool wxUnixTimerImpl::Start(int milliseconds
, bool oneShot
)
195 // notice that this will stop an already running timer
196 wxTimerImpl::Start(milliseconds
, oneShot
);
198 wxTimerScheduler::Get().AddTimer(this, wxGetLocalTimeUsec() + m_milli
*1000);
204 void wxUnixTimerImpl::Stop()
208 wxTimerScheduler::Get().RemoveTimer(this);
214 bool wxUnixTimerImpl::IsRunning() const
219 wxUnixTimerImpl::~wxUnixTimerImpl()
221 wxASSERT_MSG( !m_isRunning
, _T("must have been stopped before") );
224 // ============================================================================
225 // wxTimerUnixModule: responsible for freeing the global timer scheduler
226 // ============================================================================
228 class wxTimerUnixModule
: public wxModule
231 wxTimerUnixModule() {}
232 virtual bool OnInit() { return true; }
233 virtual void OnExit() { wxTimerScheduler::Shutdown(); }
235 DECLARE_DYNAMIC_CLASS(wxTimerUnixModule
)
238 IMPLEMENT_DYNAMIC_CLASS(wxTimerUnixModule
, wxModule
)
240 // ============================================================================
242 // ============================================================================
244 wxUsecClock_t
wxGetLocalTimeUsec()
246 #ifdef HAVE_GETTIMEOFDAY
248 if ( wxGetTimeOfDay(&tv
) != -1 )
250 wxUsecClock_t val
= 1000000L; // usec/sec
252 return val
+ tv
.tv_usec
;
254 #endif // HAVE_GETTIMEOFDAY
256 return wxGetLocalTimeMillis() * 1000L;
259 #endif // wxUSE_TIMER