~registry/dolphin-emu/triforce

« back to all changes in this revision

Viewing changes to Externals/wxWidgets3/include/wx/evtloop.h

  • Committer: Sérgio Benjamim
  • Date: 2015-02-13 05:54:40 UTC
  • Revision ID: sergio_br2@yahoo.com.br-20150213055440-ey2rt3sjpy27km78
Dolphin Triforce branch from code.google, commit b957980 (4.0-315).

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
///////////////////////////////////////////////////////////////////////////////
 
2
// Name:        wx/evtloop.h
 
3
// Purpose:     declares wxEventLoop class
 
4
// Author:      Vadim Zeitlin
 
5
// Modified by:
 
6
// Created:     01.06.01
 
7
// Copyright:   (c) 2001 Vadim Zeitlin <zeitlin@dptmaths.ens-cachan.fr>
 
8
// Licence:     wxWindows licence
 
9
///////////////////////////////////////////////////////////////////////////////
 
10
 
 
11
#ifndef _WX_EVTLOOP_H_
 
12
#define _WX_EVTLOOP_H_
 
13
 
 
14
#include "wx/event.h"
 
15
#include "wx/utils.h"
 
16
 
 
17
// TODO: implement wxEventLoopSource for MSW (it should wrap a HANDLE and be
 
18
//       monitored using MsgWaitForMultipleObjects())
 
19
#if defined(__WXOSX__) || (defined(__UNIX__) && !defined(__WXMSW__))
 
20
    #define wxUSE_EVENTLOOP_SOURCE 1
 
21
#else
 
22
    #define wxUSE_EVENTLOOP_SOURCE 0
 
23
#endif
 
24
 
 
25
#if wxUSE_EVENTLOOP_SOURCE
 
26
    class wxEventLoopSource;
 
27
    class wxEventLoopSourceHandler;
 
28
#endif
 
29
 
 
30
/*
 
31
    NOTE ABOUT wxEventLoopBase::YieldFor LOGIC
 
32
    ------------------------------------------
 
33
 
 
34
    The YieldFor() function helps to avoid re-entrancy problems and problems
 
35
    caused by out-of-order event processing
 
36
    (see "wxYield-like problems" and "wxProgressDialog+threading BUG" wx-dev threads).
 
37
 
 
38
    The logic behind YieldFor() is simple: it analyzes the queue of the native
 
39
    events generated by the underlying GUI toolkit and picks out and processes
 
40
    only those matching the given mask.
 
41
 
 
42
    It's important to note that YieldFor() is used to selectively process the
 
43
    events generated by the NATIVE toolkit.
 
44
    Events syntethized by wxWidgets code or by user code are instead selectively
 
45
    processed thanks to the logic built into wxEvtHandler::ProcessPendingEvents().
 
46
    In fact, when wxEvtHandler::ProcessPendingEvents gets called from inside a
 
47
    YieldFor() call, wxEventLoopBase::IsEventAllowedInsideYield is used to decide
 
48
    if the pending events for that event handler can be processed.
 
49
    If all the pending events associated with that event handler result as "not processable",
 
50
    the event handler "delays" itself calling wxEventLoopBase::DelayPendingEventHandler
 
51
    (so it's moved: m_handlersWithPendingEvents => m_handlersWithPendingDelayedEvents).
 
52
    Last, wxEventLoopBase::ProcessPendingEvents() before exiting moves the delayed
 
53
    event handlers back into the list of handlers with pending events
 
54
    (m_handlersWithPendingDelayedEvents => m_handlersWithPendingEvents) so that
 
55
    a later call to ProcessPendingEvents() (possibly outside the YieldFor() call)
 
56
    will process all pending events as usual.
 
57
*/
 
58
 
 
59
// ----------------------------------------------------------------------------
 
60
// wxEventLoopBase: interface for wxEventLoop
 
61
// ----------------------------------------------------------------------------
 
62
 
 
63
class WXDLLIMPEXP_BASE wxEventLoopBase
 
64
{
 
65
public:
 
66
    // trivial, but needed (because of wxEventLoopBase) ctor
 
67
    wxEventLoopBase();
 
68
 
 
69
    // dtor
 
70
    virtual ~wxEventLoopBase() { }
 
71
 
 
72
    // use this to check whether the event loop was successfully created before
 
73
    // using it
 
74
    virtual bool IsOk() const { return true; }
 
75
 
 
76
    // returns true if this is the main loop
 
77
    bool IsMain() const;
 
78
 
 
79
#if wxUSE_EVENTLOOP_SOURCE
 
80
    // create a new event loop source wrapping the given file descriptor and
 
81
    // monitor it for events occurring on this descriptor in all event loops
 
82
    static wxEventLoopSource *
 
83
      AddSourceForFD(int fd, wxEventLoopSourceHandler *handler, int flags);
 
84
#endif // wxUSE_EVENTLOOP_SOURCE
 
85
 
 
86
    // dispatch&processing
 
87
    // -------------------
 
88
 
 
89
    // start the event loop, return the exit code when it is finished
 
90
    //
 
91
    // notice that wx ports should override DoRun(), this method is virtual
 
92
    // only to allow overriding it in the user code for custom event loops
 
93
    virtual int Run();
 
94
 
 
95
    // is this event loop running now?
 
96
    //
 
97
    // notice that even if this event loop hasn't terminated yet but has just
 
98
    // spawned a nested (e.g. modal) event loop, this would return false
 
99
    bool IsRunning() const;
 
100
 
 
101
    // exit from the loop with the given exit code
 
102
    //
 
103
    // this can be only used to exit the currently running loop, use
 
104
    // ScheduleExit() if this might not be the case
 
105
    virtual void Exit(int rc = 0);
 
106
 
 
107
    // ask the event loop to exit with the given exit code, can be used even if
 
108
    // this loop is not running right now but the loop must have been started,
 
109
    // i.e. Run() should have been already called
 
110
    virtual void ScheduleExit(int rc = 0) = 0;
 
111
 
 
112
    // return true if any events are available
 
113
    virtual bool Pending() const = 0;
 
114
 
 
115
    // dispatch a single event, return false if we should exit from the loop
 
116
    virtual bool Dispatch() = 0;
 
117
 
 
118
    // same as Dispatch() but doesn't wait for longer than the specified (in
 
119
    // ms) timeout, return true if an event was processed, false if we should
 
120
    // exit the loop or -1 if timeout expired
 
121
    virtual int DispatchTimeout(unsigned long timeout) = 0;
 
122
 
 
123
    // implement this to wake up the loop: usually done by posting a dummy event
 
124
    // to it (can be called from non main thread)
 
125
    virtual void WakeUp() = 0;
 
126
 
 
127
 
 
128
    // idle handling
 
129
    // -------------
 
130
 
 
131
        // make sure that idle events are sent again
 
132
    virtual void WakeUpIdle();
 
133
 
 
134
        // this virtual function is called  when the application
 
135
        // becomes idle and by default it forwards to wxApp::ProcessIdle() and
 
136
        // while it can be overridden in a custom event loop, you must call the
 
137
        // base class version to ensure that idle events are still generated
 
138
        //
 
139
        // it should return true if more idle events are needed, false if not
 
140
    virtual bool ProcessIdle();
 
141
 
 
142
 
 
143
    // Yield-related hooks
 
144
    // -------------------
 
145
 
 
146
    // process all currently pending events right now
 
147
    //
 
148
    // it is an error to call Yield() recursively unless the value of
 
149
    // onlyIfNeeded is true
 
150
    //
 
151
    // WARNING: this function is dangerous as it can lead to unexpected
 
152
    //          reentrancies (i.e. when called from an event handler it
 
153
    //          may result in calling the same event handler again), use
 
154
    //          with _extreme_ care or, better, don't use at all!
 
155
    bool Yield(bool onlyIfNeeded = false);
 
156
    virtual bool YieldFor(long eventsToProcess) = 0;
 
157
 
 
158
    // returns true if the main thread is inside a Yield() call
 
159
    virtual bool IsYielding() const
 
160
        { return m_isInsideYield; }
 
161
 
 
162
    // returns true if events of the given event category should be immediately
 
163
    // processed inside a wxApp::Yield() call or rather should be queued for
 
164
    // later processing by the main event loop
 
165
    virtual bool IsEventAllowedInsideYield(wxEventCategory cat) const
 
166
        { return (m_eventsToProcessInsideYield & cat) != 0; }
 
167
 
 
168
    // no SafeYield hooks since it uses wxWindow which is not available when wxUSE_GUI=0
 
169
 
 
170
 
 
171
    // active loop
 
172
    // -----------
 
173
 
 
174
    // return currently active (running) event loop, may be NULL
 
175
    static wxEventLoopBase *GetActive() { return ms_activeLoop; }
 
176
 
 
177
    // set currently active (running) event loop
 
178
    static void SetActive(wxEventLoopBase* loop);
 
179
 
 
180
 
 
181
protected:
 
182
    // real implementation of Run()
 
183
    virtual int DoRun() = 0;
 
184
 
 
185
    // this function should be called before the event loop terminates, whether
 
186
    // this happens normally (because of Exit() call) or abnormally (because of
 
187
    // an exception thrown from inside the loop)
 
188
    virtual void OnExit();
 
189
 
 
190
    // Return true if we're currently inside our Run(), even if another nested
 
191
    // event loop is currently running, unlike IsRunning() (which should have
 
192
    // been really called IsActive() but it's too late to change this now).
 
193
    bool IsInsideRun() const { return m_isInsideRun; }
 
194
 
 
195
 
 
196
    // the pointer to currently active loop
 
197
    static wxEventLoopBase *ms_activeLoop;
 
198
 
 
199
    // should we exit the loop?
 
200
    bool m_shouldExit;
 
201
 
 
202
    // YieldFor() helpers:
 
203
    bool m_isInsideYield;
 
204
    long m_eventsToProcessInsideYield;
 
205
 
 
206
private:
 
207
    // this flag is set on entry into Run() and reset before leaving it
 
208
    bool m_isInsideRun;
 
209
 
 
210
    wxDECLARE_NO_COPY_CLASS(wxEventLoopBase);
 
211
};
 
212
 
 
213
#if defined(__WINDOWS__) || defined(__WXMAC__) || defined(__WXDFB__) || (defined(__UNIX__) && !defined(__WXOSX__))
 
214
 
 
215
// this class can be used to implement a standard event loop logic using
 
216
// Pending() and Dispatch()
 
217
//
 
218
// it also handles idle processing automatically
 
219
class WXDLLIMPEXP_BASE wxEventLoopManual : public wxEventLoopBase
 
220
{
 
221
public:
 
222
    wxEventLoopManual();
 
223
 
 
224
    // sets the "should exit" flag and wakes up the loop so that it terminates
 
225
    // soon
 
226
    virtual void ScheduleExit(int rc = 0);
 
227
 
 
228
protected:
 
229
    // enters a loop calling OnNextIteration(), Pending() and Dispatch() and
 
230
    // terminating when Exit() is called
 
231
    virtual int DoRun();
 
232
 
 
233
    // may be overridden to perform some action at the start of each new event
 
234
    // loop iteration
 
235
    virtual void OnNextIteration() { }
 
236
 
 
237
 
 
238
    // the loop exit code
 
239
    int m_exitcode;
 
240
 
 
241
private:
 
242
    // process all already pending events and dispatch a new one (blocking
 
243
    // until it appears in the event queue if necessary)
 
244
    //
 
245
    // returns the return value of Dispatch()
 
246
    bool ProcessEvents();
 
247
 
 
248
    wxDECLARE_NO_COPY_CLASS(wxEventLoopManual);
 
249
};
 
250
 
 
251
#endif // platforms using "manual" loop
 
252
 
 
253
// we're moving away from old m_impl wxEventLoop model as otherwise the user
 
254
// code doesn't have access to platform-specific wxEventLoop methods and this
 
255
// can sometimes be very useful (e.g. under MSW this is necessary for
 
256
// integration with MFC) but currently this is not done for all ports yet (e.g.
 
257
// wxX11) so fall back to the old wxGUIEventLoop definition below for them
 
258
 
 
259
#if defined(__DARWIN__)
 
260
    // CoreFoundation-based event loop is currently in wxBase so include it in
 
261
    // any case too (although maybe it actually shouldn't be there at all)
 
262
    #include "wx/osx/core/evtloop.h"
 
263
#endif
 
264
 
 
265
// include the header defining wxConsoleEventLoop
 
266
#if defined(__UNIX__) && !defined(__WXMSW__)
 
267
    #include "wx/unix/evtloop.h"
 
268
#elif defined(__WINDOWS__)
 
269
    #include "wx/msw/evtloopconsole.h"
 
270
#endif
 
271
 
 
272
#if wxUSE_GUI
 
273
 
 
274
// include the appropriate header defining wxGUIEventLoop
 
275
 
 
276
#if defined(__WXMSW__)
 
277
    #include "wx/msw/evtloop.h"
 
278
#elif defined(__WXCOCOA__)
 
279
    #include "wx/cocoa/evtloop.h"
 
280
#elif defined(__WXOSX__)
 
281
    #include "wx/osx/evtloop.h"
 
282
#elif defined(__WXDFB__)
 
283
    #include "wx/dfb/evtloop.h"
 
284
#elif defined(__WXGTK20__)
 
285
    #include "wx/gtk/evtloop.h"
 
286
#else // other platform
 
287
 
 
288
#include "wx/stopwatch.h"   // for wxMilliClock_t
 
289
 
 
290
class WXDLLIMPEXP_FWD_CORE wxEventLoopImpl;
 
291
 
 
292
class WXDLLIMPEXP_CORE wxGUIEventLoop : public wxEventLoopBase
 
293
{
 
294
public:
 
295
    wxGUIEventLoop() { m_impl = NULL; }
 
296
    virtual ~wxGUIEventLoop();
 
297
 
 
298
    virtual void ScheduleExit(int rc = 0);
 
299
    virtual bool Pending() const;
 
300
    virtual bool Dispatch();
 
301
    virtual int DispatchTimeout(unsigned long timeout)
 
302
    {
 
303
        // TODO: this is, of course, horribly inefficient and a proper wait with
 
304
        //       timeout should be implemented for all ports natively...
 
305
        const wxMilliClock_t timeEnd = wxGetLocalTimeMillis() + timeout;
 
306
        for ( ;; )
 
307
        {
 
308
            if ( Pending() )
 
309
                return Dispatch();
 
310
 
 
311
            if ( wxGetLocalTimeMillis() >= timeEnd )
 
312
                return -1;
 
313
        }
 
314
    }
 
315
    virtual void WakeUp() { }
 
316
    virtual bool YieldFor(long eventsToProcess);
 
317
 
 
318
protected:
 
319
    virtual int DoRun();
 
320
 
 
321
    // the pointer to the port specific implementation class
 
322
    wxEventLoopImpl *m_impl;
 
323
 
 
324
    wxDECLARE_NO_COPY_CLASS(wxGUIEventLoop);
 
325
};
 
326
 
 
327
#endif // platforms
 
328
 
 
329
#endif // wxUSE_GUI
 
330
 
 
331
#if wxUSE_GUI
 
332
    // we use a class rather than a typedef because wxEventLoop is
 
333
    // forward-declared in many places
 
334
    class wxEventLoop : public wxGUIEventLoop { };
 
335
#else // !wxUSE_GUI
 
336
    // we can't define wxEventLoop differently in GUI and base libraries so use
 
337
    // a #define to still allow writing wxEventLoop in the user code
 
338
    #if wxUSE_CONSOLE_EVENTLOOP && (defined(__WINDOWS__) || defined(__UNIX__))
 
339
        #define wxEventLoop wxConsoleEventLoop
 
340
    #else // we still must define it somehow for the code below...
 
341
        #define wxEventLoop wxEventLoopBase
 
342
    #endif
 
343
#endif
 
344
 
 
345
inline bool wxEventLoopBase::IsRunning() const { return GetActive() == this; }
 
346
 
 
347
#if wxUSE_GUI && !defined(__WXOSX__)
 
348
// ----------------------------------------------------------------------------
 
349
// wxModalEventLoop
 
350
// ----------------------------------------------------------------------------
 
351
 
 
352
// this is a naive generic implementation which uses wxWindowDisabler to
 
353
// implement modality, we will surely need platform-specific implementations
 
354
// too, this generic implementation is here only temporarily to see how it
 
355
// works
 
356
class WXDLLIMPEXP_CORE wxModalEventLoop : public wxGUIEventLoop
 
357
{
 
358
public:
 
359
    wxModalEventLoop(wxWindow *winModal)
 
360
    {
 
361
        m_windowDisabler = new wxWindowDisabler(winModal);
 
362
    }
 
363
 
 
364
protected:
 
365
    virtual void OnExit()
 
366
    {
 
367
        delete m_windowDisabler;
 
368
        m_windowDisabler = NULL;
 
369
 
 
370
        wxGUIEventLoop::OnExit();
 
371
    }
 
372
 
 
373
private:
 
374
    wxWindowDisabler *m_windowDisabler;
 
375
};
 
376
 
 
377
#endif //wxUSE_GUI
 
378
 
 
379
// ----------------------------------------------------------------------------
 
380
// wxEventLoopActivator: helper class for wxEventLoop implementations
 
381
// ----------------------------------------------------------------------------
 
382
 
 
383
// this object sets the wxEventLoop given to the ctor as the currently active
 
384
// one and unsets it in its dtor, this is especially useful in presence of
 
385
// exceptions but is more tidy even when we don't use them
 
386
class wxEventLoopActivator
 
387
{
 
388
public:
 
389
    wxEventLoopActivator(wxEventLoopBase *evtLoop)
 
390
    {
 
391
        m_evtLoopOld = wxEventLoopBase::GetActive();
 
392
        wxEventLoopBase::SetActive(evtLoop);
 
393
    }
 
394
 
 
395
    ~wxEventLoopActivator()
 
396
    {
 
397
        // restore the previously active event loop
 
398
        wxEventLoopBase::SetActive(m_evtLoopOld);
 
399
    }
 
400
 
 
401
private:
 
402
    wxEventLoopBase *m_evtLoopOld;
 
403
};
 
404
 
 
405
#if wxUSE_CONSOLE_EVENTLOOP
 
406
 
 
407
class wxEventLoopGuarantor
 
408
{
 
409
public:
 
410
    wxEventLoopGuarantor()
 
411
    {
 
412
        m_evtLoopNew = NULL;
 
413
        if (!wxEventLoop::GetActive())
 
414
        {
 
415
            m_evtLoopNew = new wxEventLoop;
 
416
            wxEventLoop::SetActive(m_evtLoopNew);
 
417
        }
 
418
    }
 
419
 
 
420
    ~wxEventLoopGuarantor()
 
421
    {
 
422
        if (m_evtLoopNew)
 
423
        {
 
424
            wxEventLoop::SetActive(NULL);
 
425
            delete m_evtLoopNew;
 
426
        }
 
427
    }
 
428
 
 
429
private:
 
430
    wxEventLoop *m_evtLoopNew;
 
431
};
 
432
 
 
433
#endif // wxUSE_CONSOLE_EVENTLOOP
 
434
 
 
435
#endif // _WX_EVTLOOP_H_