]>
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