]> git.saurik.com Git - wxWidgets.git/blame - src/mgl/timer.cpp
fixed bug with redoing the command when there was nothing to redo
[wxWidgets.git] / src / mgl / timer.cpp
CommitLineData
32b8ec41 1/////////////////////////////////////////////////////////////////////////////
1acd70f9 2// Name: mgl/timer.cpp
32b8ec41 3// Purpose: wxTimer implementation
1acd70f9 4// Author: Vaclav Slavik
32b8ec41 5// Id: $Id$
1acd70f9 6// Copyright: (c) 2001 SciTech Software, Inc. (www.scitechsoft.com)
32b8ec41
VZ
7// Licence: wxWindows licence
8/////////////////////////////////////////////////////////////////////////////
9
10
11#ifdef __GNUG__
12#pragma implementation "timer.h"
13#endif
14
15#include "wx/timer.h"
16
1acd70f9
VS
17#if wxUSE_TIMER
18
19#include "wx/mgl/private.h"
20
21extern "C" ulong _EVT_getTicks();
22
23// ----------------------------------------------------------------------------
24// helper structures and wxTimerScheduler
25// ----------------------------------------------------------------------------
26
27class wxTimerDesc
28{
29public:
30 wxTimerDesc(wxTimer *t) : timer(t), running(FALSE), next(NULL), prev(NULL) {}
31
32 wxTimer *timer;
33 bool running;
34 wxTimerDesc *next, *prev;
35 unsigned long shotTime;
36};
37
38class wxTimerScheduler
39{
40public:
41 wxTimerScheduler() : m_timers(NULL) {}
42
43 void QueueTimer(wxTimerDesc *desc, unsigned long when = 0);
44 void RemoveTimer(wxTimerDesc *desc);
45 void NotifyTimers();
46
47private:
48 wxTimerDesc *m_timers;
49};
50
51void wxTimerScheduler::QueueTimer(wxTimerDesc *desc, unsigned long when)
52{
53 if ( when == 0 )
54 when = _EVT_getTicks() + desc->timer->GetInterval();
55 desc->shotTime = when;
56 desc->running = TRUE;
57
58 if ( m_timers )
59 {
60 wxTimerDesc *d = m_timers;
61 while ( d->next && d->next->shotTime < when ) d = d->next;
62 desc->next = d->next;
63 desc->prev = d;
64 if ( d->next )
65 d->next->prev = desc;
66 d->next = desc;
67 }
68 else
69 {
70 m_timers = desc;
71 desc->prev = desc->next = NULL;
72 }
73}
74
75void wxTimerScheduler::RemoveTimer(wxTimerDesc *desc)
76{
77 desc->running = FALSE;
78 if ( desc == m_timers )
79 m_timers = desc->next;
80 if ( desc->prev )
81 desc->prev->next = desc->next;
82 if ( desc->next )
83 desc->next->prev = desc->prev;
84 desc->prev = desc->next = NULL;
85}
86
87void wxTimerScheduler::NotifyTimers()
88{
89 if ( m_timers )
90 {
91 unsigned long now = _EVT_getTicks();
92 wxTimerDesc *desc;
93
94 while ( m_timers && m_timers->shotTime <= now )
95 {
96 desc = m_timers;
97 desc->timer->Notify();
98 RemoveTimer(desc);
99 if ( !desc->timer->IsOneShot() )
100 {
101 QueueTimer(desc, now + desc->timer->GetInterval());
102 }
103 }
104 }
105}
106
107
32b8ec41
VZ
108
109// ----------------------------------------------------------------------------
110// wxTimer
111// ----------------------------------------------------------------------------
112
113IMPLEMENT_ABSTRACT_CLASS(wxTimer,wxObject)
114
1acd70f9
VS
115wxTimerScheduler *wxTimer::ms_scheduler = NULL;
116size_t wxTimer::ms_timersCnt = 0;
117
118void wxTimer::Init()
119{
120 if ( ms_timersCnt++ == 0 )
121 ms_scheduler = new wxTimerScheduler;
122 m_desc = new wxTimerDesc(this);
123}
124
125wxTimer::~wxTimer()
126{
127 if ( IsRunning() )
128 Stop();
129
130 if ( --ms_timersCnt == 0 )
131 {
132 delete ms_scheduler;
133 ms_scheduler = NULL;
134 }
135 delete m_desc;
136}
137
138bool wxTimer::IsRunning() const
139{
140 return m_desc->running;
141}
142
143bool wxTimer::Start(int millisecs, bool oneShot)
144{
145 if ( !wxTimerBase::Start(millisecs, oneShot) )
146 return FALSE;
147
148 ms_scheduler->QueueTimer(m_desc);
149 return TRUE;
150}
151
152void wxTimer::Stop()
153{
154 if ( !m_desc->running ) return;
155
156 ms_scheduler->RemoveTimer(m_desc);
157}
158
159/*static*/ void wxTimer::NotifyTimers()
160{
161 ms_scheduler->NotifyTimers();
162}
163
164#endif //wxUSE_TIMER