X-Git-Url: https://git.saurik.com/wxWidgets.git/blobdiff_plain/4300caa7a669d1e09e7d5dfd739acf4bb08e8b49..ba5b8a68f7486cfb11e326c200e1c2df3e1a534d:/include/wx/evtloop.h diff --git a/include/wx/evtloop.h b/include/wx/evtloop.h index dcd2a766e0..4a70021ec3 100644 --- a/include/wx/evtloop.h +++ b/include/wx/evtloop.h @@ -12,39 +12,34 @@ #ifndef _WX_EVTLOOP_H_ #define _WX_EVTLOOP_H_ -#if defined(__GNUG__) && !defined(NO_GCC_PRAGMA) - #pragma interface "evtloop.h" -#endif +#include "wx/utils.h" -class WXDLLEXPORT wxEventLoopImpl; +class WXDLLEXPORT wxEventLoop; // ---------------------------------------------------------------------------- // wxEventLoop: a GUI event loop // ---------------------------------------------------------------------------- -class WXDLLEXPORT wxEventLoop +class WXDLLEXPORT wxEventLoopBase { public: - // ctor - wxEventLoop() { m_impl = NULL; } + // trivial, but needed (because of wxEventLoopBase) ctor + wxEventLoopBase() { } // dtor - virtual ~wxEventLoop(); + virtual ~wxEventLoopBase() { } // start the event loop, return the exit code when it is finished - virtual int Run(); + virtual int Run() = 0; // exit from the loop with the given exit code - virtual void Exit(int rc = 0); - - // return TRUE if any events are available - virtual bool Pending() const; + virtual void Exit(int rc = 0) = 0; - // dispatch a single event, return FALSE if we should exit from the loop - virtual bool Dispatch(); + // return true if any events are available + virtual bool Pending() const = 0; - // is the event loop running now? - virtual bool IsRunning() const; + // dispatch a single event, return false if we should exit from the loop + virtual bool Dispatch() = 0; // return currently active (running) event loop, may be NULL static wxEventLoop *GetActive() { return ms_activeLoop; } @@ -52,6 +47,12 @@ public: // set currently active (running) event loop static void SetActive(wxEventLoop* loop) { ms_activeLoop = loop; } + // is this event loop running now? + // + // notice that even if this event loop hasn't terminated yet but has just + // spawned a nested (e.g. modal) event loop, this would return false + bool IsRunning() const; + protected: // this function should be called before the event loop terminates, whether // this happens normally (because of Exit() call) or abnormally (because of @@ -62,12 +63,84 @@ protected: // the pointer to currently active loop static wxEventLoop *ms_activeLoop; + DECLARE_NO_COPY_CLASS(wxEventLoopBase) +}; + +#if defined(__WXMSW__) || defined(__WXMAC__) + +// this class can be used to implement a standard event loop logic using +// Pending() and Dispatch() +// +// it also handles idle processing automatically +class WXDLLEXPORT wxEventLoopManual : public wxEventLoopBase +{ +public: + wxEventLoopManual(); + + // enters a loop calling OnNextIteration(), Pending() and Dispatch() and + // terminating when Exit() is called + virtual int Run(); + + // sets the "should exit" flag and wakes up the loop so that it terminates + // soon + virtual void Exit(int rc = 0); + +protected: + // implement this to wake up the loop: usually done by posting a dummy event + // to it (called from Exit()) + virtual void WakeUp() = 0; + + // may be overridden to perform some action at the start of each new event + // loop iteration + virtual void OnNextIteration() { } + + + // the loop exit code + int m_exitcode; + + // should we exit the loop? + bool m_shouldExit; +}; + +#endif // platforms using "manual" loop + +// we're moving away from old m_impl wxEventLoop model as otherwise the user +// code doesn't have access to platform-specific wxEventLoop methods and this +// can sometimes be very useful (e.g. under MSW this is necessary for +// integration with MFC) but currently this is done for MSW only, other ports +// should follow a.s.a.p. +#if defined(__WXPALMOS__) + #include "wx/palmos/evtloop.h" +#elif defined(__WXMSW__) + #include "wx/msw/evtloop.h" +#elif defined(__WXMAC__) + #include "wx/mac/evtloop.h" +#else // other platform + +class WXDLLEXPORT wxEventLoopImpl; + +class WXDLLEXPORT wxEventLoop : public wxEventLoopBase +{ +public: + wxEventLoop() { m_impl = NULL; } + virtual ~wxEventLoop(); + + virtual int Run(); + virtual void Exit(int rc = 0); + virtual bool Pending() const; + virtual bool Dispatch(); + +protected: // the pointer to the port specific implementation class wxEventLoopImpl *m_impl; DECLARE_NO_COPY_CLASS(wxEventLoop) }; +#endif // platforms + +inline bool wxEventLoopBase::IsRunning() const { return GetActive() == this; } + // ---------------------------------------------------------------------------- // wxModalEventLoop // ---------------------------------------------------------------------------- @@ -97,4 +170,30 @@ private: wxWindowDisabler *m_windowDisabler; }; +// ---------------------------------------------------------------------------- +// wxEventLoopActivator: helper class for wxEventLoop implementations +// ---------------------------------------------------------------------------- + +// this object sets the wxEventLoop given to the ctor as the currently active +// one and unsets it in its dtor, this is especially useful in presence of +// exceptions but is more tidy even when we don't use them +class wxEventLoopActivator +{ +public: + wxEventLoopActivator(wxEventLoop *evtLoop) + { + m_evtLoopOld = wxEventLoop::GetActive(); + wxEventLoop::SetActive(evtLoop); + } + + ~wxEventLoopActivator() + { + // restore the previously active event loop + wxEventLoop::SetActive(m_evtLoopOld); + } + +private: + wxEventLoop *m_evtLoopOld; +}; + #endif // _WX_EVTLOOP_H_