]> git.saurik.com Git - wxWidgets.git/blame - src/x11/timer.cpp
Fix for the splashscreen bitmap not showing up in wxGTK.
[wxWidgets.git] / src / x11 / timer.cpp
CommitLineData
83df96d6 1/////////////////////////////////////////////////////////////////////////////
b513212d 2// Name: x11/timer.cpp
83df96d6 3// Purpose: wxTimer implementation
b513212d
JS
4// Author: Vaclav Slavik
5// Id: $Id$
6// Copyright: (c) 2001 SciTech Software, Inc. (www.scitechsoft.com)
7// Licence: wxWindows licence
83df96d6
JS
8/////////////////////////////////////////////////////////////////////////////
9
b513212d 10
83df96d6
JS
11#ifdef __GNUG__
12#pragma implementation "timer.h"
13#endif
14
b513212d
JS
15// For compilers that support precompilation, includes "wx.h".
16#include "wx/wxprec.h"
83df96d6 17
b513212d
JS
18#ifdef __BORLANDC__
19 #pragma hdrstop
83df96d6 20#endif
bc797f4c 21
b513212d
JS
22#include "wx/timer.h"
23
24#if wxUSE_TIMER
83df96d6 25
b513212d
JS
26#include "wx/log.h"
27#include "wx/module.h"
bc797f4c 28#include "wx/x11/private.h"
83df96d6 29
b513212d
JS
30// ----------------------------------------------------------------------------
31// helper structures and wxTimerScheduler
32// ----------------------------------------------------------------------------
83df96d6 33
b513212d
JS
34class wxTimerDesc
35{
36public:
37 wxTimerDesc(wxTimer *t) :
38 timer(t), running(FALSE), next(NULL), prev(NULL),
39 shotTime(0), deleteFlag(NULL) {}
40
41 wxTimer *timer;
42 bool running;
43 wxTimerDesc *next, *prev;
44 unsigned long shotTime;
45 volatile bool *deleteFlag; // see comment in ~wxTimer
46};
47
48class wxTimerScheduler
49{
50public:
51 wxTimerScheduler() : m_timers(NULL) {}
52
53 void QueueTimer(wxTimerDesc *desc, unsigned long when = 0);
54 void RemoveTimer(wxTimerDesc *desc);
55 void NotifyTimers();
56
57private:
58 wxTimerDesc *m_timers;
59};
60
61void wxTimerScheduler::QueueTimer(wxTimerDesc *desc, unsigned long when)
62{
63 if ( desc->running )
64 return; // already scheduled
178572bb
RR
65
66#pragma
67#if 0
b513212d
JS
68 if ( when == 0 )
69 when = wxGetLocalTimeMillis() + desc->timer->GetInterval();
178572bb 70#endif
b513212d
JS
71 desc->shotTime = when;
72 desc->running = TRUE;
73
74 wxLogTrace("mgl_timer", "queued timer %p at tick %i",
75 desc->timer, when);
76
77 if ( m_timers )
78 {
79 wxTimerDesc *d = m_timers;
80 while ( d->next && d->next->shotTime < when ) d = d->next;
81 desc->next = d->next;
82 desc->prev = d;
83 if ( d->next )
84 d->next->prev = desc;
85 d->next = desc;
86 }
87 else
88 {
89 m_timers = desc;
90 desc->prev = desc->next = NULL;
91 }
92}
83df96d6 93
b513212d 94void wxTimerScheduler::RemoveTimer(wxTimerDesc *desc)
83df96d6 95{
b513212d
JS
96 desc->running = FALSE;
97 if ( desc == m_timers )
98 m_timers = desc->next;
99 if ( desc->prev )
100 desc->prev->next = desc->next;
101 if ( desc->next )
102 desc->next->prev = desc->prev;
103 desc->prev = desc->next = NULL;
104}
83df96d6 105
b513212d
JS
106void wxTimerScheduler::NotifyTimers()
107{
108 if ( m_timers )
109 {
110 bool oneShot;
111 volatile bool timerDeleted;
178572bb
RR
112#pragma
113 unsigned long now;
114#if 0
115 now = wxGetLocalTimeMillis();
116#endif
b513212d
JS
117 wxTimerDesc *desc;
118
119 while ( m_timers && m_timers->shotTime <= now )
120 {
121 desc = m_timers;
122 oneShot = desc->timer->IsOneShot();
123 RemoveTimer(desc);
124
125 timerDeleted = FALSE;
126 desc->deleteFlag = &timerDeleted;
127 desc->timer->Notify();
128
129 if ( !timerDeleted )
130 {
131 wxLogTrace("mgl_timer", "notified timer %p sheduled for %i",
132 desc->timer, desc->shotTime);
133
134 desc->deleteFlag = NULL;
135 if ( !oneShot )
136 QueueTimer(desc, now + desc->timer->GetInterval());
137 }
138 }
139 }
83df96d6
JS
140}
141
b513212d
JS
142
143
144// ----------------------------------------------------------------------------
145// wxTimer
146// ----------------------------------------------------------------------------
147
148IMPLEMENT_ABSTRACT_CLASS(wxTimer,wxObject)
149
150wxTimerScheduler *gs_scheduler = NULL;
151
83df96d6
JS
152void wxTimer::Init()
153{
b513212d
JS
154 if ( !gs_scheduler )
155 gs_scheduler = new wxTimerScheduler;
156 m_desc = new wxTimerDesc(this);
83df96d6
JS
157}
158
159wxTimer::~wxTimer()
160{
b513212d
JS
161 wxLogTrace("mgl_timer", "destroying timer %p...", this);
162 if ( IsRunning() )
163 Stop();
164
165 // NB: this is a hack: wxTimerScheduler must have some way of knowing
166 // that wxTimer object was deleted under its hands -- this may
167 // happen if somebody is really nasty and deletes the timer
168 // from wxTimer::Notify()
169 if ( m_desc->deleteFlag != NULL )
170 *m_desc->deleteFlag = TRUE;
171
172 delete m_desc;
173 wxLogTrace("mgl_timer", " ...done destroying timer %p...", this);
83df96d6
JS
174}
175
b513212d 176bool wxTimer::IsRunning() const
83df96d6 177{
b513212d
JS
178 return m_desc->running;
179}
180
181bool wxTimer::Start(int millisecs, bool oneShot)
182{
183 wxLogTrace("mgl_timer", "started timer %p: %i ms, oneshot=%i",
184 this, millisecs, oneShot);
185
186 if ( !wxTimerBase::Start(millisecs, oneShot) )
187 return FALSE;
188
189 gs_scheduler->QueueTimer(m_desc);
83df96d6
JS
190 return TRUE;
191}
192
193void wxTimer::Stop()
194{
b513212d
JS
195 if ( !m_desc->running ) return;
196
197 gs_scheduler->RemoveTimer(m_desc);
83df96d6
JS
198}
199
b513212d
JS
200/*static*/ void wxTimer::NotifyTimers()
201{
202 if ( gs_scheduler )
203 gs_scheduler->NotifyTimers();
204}
205
206
207
208// A module to deallocate memory properly:
209class wxTimerModule: public wxModule
210{
211DECLARE_DYNAMIC_CLASS(wxTimerModule)
212public:
213 wxTimerModule() {}
214 bool OnInit() { return TRUE; }
215 void OnExit() { delete gs_scheduler; gs_scheduler = NULL; }
216};
217
218IMPLEMENT_DYNAMIC_CLASS(wxTimerModule, wxModule)
219
83df96d6 220
b513212d 221#endif //wxUSE_TIMER