]> git.saurik.com Git - wxWidgets.git/blob - include/wx/evtloop.h
our sockets are always non-blocking anyhow so throw away all the code dealing with...
[wxWidgets.git] / include / wx / evtloop.h
1 ///////////////////////////////////////////////////////////////////////////////
2 // Name: wx/evtloop.h
3 // Purpose: declares wxEventLoop class
4 // Author: Vadim Zeitlin
5 // Modified by:
6 // Created: 01.06.01
7 // RCS-ID: $Id$
8 // Copyright: (c) 2001 Vadim Zeitlin <zeitlin@dptmaths.ens-cachan.fr>
9 // Licence: wxWindows licence
10 ///////////////////////////////////////////////////////////////////////////////
11
12 #ifndef _WX_EVTLOOP_H_
13 #define _WX_EVTLOOP_H_
14
15 #include "wx/utils.h"
16
17 // ----------------------------------------------------------------------------
18 // wxEventLoopBase: interface for wxEventLoop
19 // ----------------------------------------------------------------------------
20
21 class WXDLLIMPEXP_BASE wxEventLoopBase
22 {
23 public:
24 // trivial, but needed (because of wxEventLoopBase) ctor
25 wxEventLoopBase() { }
26
27 // dtor
28 virtual ~wxEventLoopBase() { }
29
30 // use this to check whether the event loop was successfully created before
31 // using it
32 virtual bool IsOk() const { return true; }
33
34
35 // start the event loop, return the exit code when it is finished
36 virtual int Run() = 0;
37
38 // exit from the loop with the given exit code
39 virtual void Exit(int rc = 0) = 0;
40
41 // return true if any events are available
42 virtual bool Pending() const = 0;
43
44 // dispatch a single event, return false if we should exit from the loop
45 virtual bool Dispatch() = 0;
46
47 // same as Dispatch() but doesn't wait for longer than the specified (in
48 // ms) timeout, return true if an event was processed, false if we should
49 // exit the loop or -1 if timeout expired
50 virtual int DispatchTimeout(unsigned long timeout) = 0;
51
52
53 // return currently active (running) event loop, may be NULL
54 static wxEventLoopBase *GetActive() { return ms_activeLoop; }
55
56 // set currently active (running) event loop
57 static void SetActive(wxEventLoopBase* loop) { ms_activeLoop = loop; }
58
59 // is this event loop running now?
60 //
61 // notice that even if this event loop hasn't terminated yet but has just
62 // spawned a nested (e.g. modal) event loop, this would return false
63 bool IsRunning() const;
64
65 // implement this to wake up the loop: usually done by posting a dummy event
66 // to it (can be called from non main thread)
67 virtual void WakeUp() = 0;
68
69 protected:
70 // this function should be called before the event loop terminates, whether
71 // this happens normally (because of Exit() call) or abnormally (because of
72 // an exception thrown from inside the loop)
73 virtual void OnExit() { }
74
75
76 // the pointer to currently active loop
77 static wxEventLoopBase *ms_activeLoop;
78
79 DECLARE_NO_COPY_CLASS(wxEventLoopBase)
80 };
81
82 #if defined(__WXMSW__) || defined(__WXMAC__) || defined(__WXDFB__) || defined(__UNIX__)
83
84 // this class can be used to implement a standard event loop logic using
85 // Pending() and Dispatch()
86 //
87 // it also handles idle processing automatically
88 class WXDLLIMPEXP_BASE wxEventLoopManual : public wxEventLoopBase
89 {
90 public:
91 wxEventLoopManual();
92
93 // enters a loop calling OnNextIteration(), Pending() and Dispatch() and
94 // terminating when Exit() is called
95 virtual int Run();
96
97 // sets the "should exit" flag and wakes up the loop so that it terminates
98 // soon
99 virtual void Exit(int rc = 0);
100
101 protected:
102 // may be overridden to perform some action at the start of each new event
103 // loop iteration
104 virtual void OnNextIteration() { }
105
106
107 // the loop exit code
108 int m_exitcode;
109
110 // should we exit the loop?
111 bool m_shouldExit;
112 };
113
114 #endif // platforms using "manual" loop
115
116 // we're moving away from old m_impl wxEventLoop model as otherwise the user
117 // code doesn't have access to platform-specific wxEventLoop methods and this
118 // can sometimes be very useful (e.g. under MSW this is necessary for
119 // integration with MFC) but currently this is done for MSW only, other ports
120 // should follow a.s.a.p.
121 #if defined(__WXPALMOS__)
122 #include "wx/palmos/evtloop.h"
123 #elif defined(__WXMSW__)
124 #include "wx/msw/evtloop.h"
125 #elif defined(__WXMAC__)
126 #include "wx/osx/evtloop.h"
127 #elif defined(__WXDFB__)
128 #include "wx/dfb/evtloop.h"
129 #elif defined(__WXGTK20__)
130 #include "wx/gtk/evtloop.h"
131 #else // other platform
132
133 #include "wx/stopwatch.h" // for wxMilliClock_t
134
135 class WXDLLIMPEXP_FWD_CORE wxEventLoopImpl;
136
137 class WXDLLIMPEXP_CORE wxGUIEventLoop : public wxEventLoopBase
138 {
139 public:
140 wxGUIEventLoop() { m_impl = NULL; }
141 virtual ~wxGUIEventLoop();
142
143 virtual int Run();
144 virtual void Exit(int rc = 0);
145 virtual bool Pending() const;
146 virtual bool Dispatch();
147 virtual int DispatchTimeout(unsigned long timeout)
148 {
149 // TODO: this is, of course, horribly inefficient and a proper wait with
150 // timeout should be implemented for all ports natively...
151 const wxMilliClock_t timeEnd = wxGetLocalTimeMillis() + timeout;
152 for ( ;; )
153 {
154 if ( Pending() )
155 return Dispatch();
156
157 if ( wxGetLocalTimeMillis() >= timeEnd )
158 return -1;
159 }
160 }
161 virtual void WakeUp() { }
162
163 protected:
164 // the pointer to the port specific implementation class
165 wxEventLoopImpl *m_impl;
166
167 DECLARE_NO_COPY_CLASS(wxGUIEventLoop)
168 };
169
170 #endif // platforms
171
172 // also include the header defining wxConsoleEventLoop for Unix systems
173 #if defined(__UNIX__)
174 #include "wx/unix/evtloop.h"
175 #endif
176
177 // we use a class rather than a typedef because wxEventLoop is forward-declared
178 // in many places
179 #if wxUSE_GUI
180 class wxEventLoop : public wxGUIEventLoop { };
181 #else // !GUI
182 // we can't define wxEventLoop differently in GUI and base libraries so use
183 // a #define to still allow writing wxEventLoop in the user code
184 #if wxUSE_CONSOLE_EVENTLOOP && (defined(__WXMSW__) || defined(__UNIX__))
185 #define wxEventLoop wxConsoleEventLoop
186 #else // we still must define it somehow for the code below...
187 #define wxEventLoop wxEventLoopBase
188 #endif
189 #endif
190
191 inline bool wxEventLoopBase::IsRunning() const { return GetActive() == this; }
192
193 #if wxUSE_GUI
194 // ----------------------------------------------------------------------------
195 // wxModalEventLoop
196 // ----------------------------------------------------------------------------
197
198 // this is a naive generic implementation which uses wxWindowDisabler to
199 // implement modality, we will surely need platform-specific implementations
200 // too, this generic implementation is here only temporarily to see how it
201 // works
202 class WXDLLIMPEXP_CORE wxModalEventLoop : public wxGUIEventLoop
203 {
204 public:
205 wxModalEventLoop(wxWindow *winModal)
206 {
207 m_windowDisabler = new wxWindowDisabler(winModal);
208 }
209
210 protected:
211 virtual void OnExit()
212 {
213 delete m_windowDisabler;
214 m_windowDisabler = NULL;
215
216 wxGUIEventLoop::OnExit();
217 }
218
219 private:
220 wxWindowDisabler *m_windowDisabler;
221 };
222
223 #endif //wxUSE_GUI
224
225 // ----------------------------------------------------------------------------
226 // wxEventLoopActivator: helper class for wxEventLoop implementations
227 // ----------------------------------------------------------------------------
228
229 // this object sets the wxEventLoop given to the ctor as the currently active
230 // one and unsets it in its dtor, this is especially useful in presence of
231 // exceptions but is more tidy even when we don't use them
232 class wxEventLoopActivator
233 {
234 public:
235 wxEventLoopActivator(wxEventLoopBase *evtLoop)
236 {
237 m_evtLoopOld = wxEventLoopBase::GetActive();
238 wxEventLoopBase::SetActive(evtLoop);
239 }
240
241 ~wxEventLoopActivator()
242 {
243 // restore the previously active event loop
244 wxEventLoopBase::SetActive(m_evtLoopOld);
245 }
246
247 private:
248 wxEventLoopBase *m_evtLoopOld;
249 };
250
251 #if wxUSE_CONSOLE_EVENTLOOP
252
253 class wxEventLoopGuarantor
254 {
255 public:
256 wxEventLoopGuarantor()
257 {
258 m_evtLoopNew = NULL;
259 if (!wxEventLoop::GetActive())
260 {
261 m_evtLoopNew = new wxEventLoop;
262 wxEventLoop::SetActive(m_evtLoopNew);
263 }
264 }
265
266 ~wxEventLoopGuarantor()
267 {
268 if (m_evtLoopNew)
269 {
270 wxEventLoop::SetActive(NULL);
271 delete m_evtLoopNew;
272 }
273 }
274
275 private:
276 wxEventLoop *m_evtLoopNew;
277 };
278
279 #endif // wxUSE_CONSOLE_EVENTLOOP
280
281 #endif // _WX_EVTLOOP_H_