From 8d60daa8d3d4ff1df00129b679713809f91f6ec5 Mon Sep 17 00:00:00 2001 From: Francesco Montorsi Date: Sun, 15 Feb 2009 23:18:04 +0000 Subject: [PATCH] wxApp::DoYield => wxGUIEventLoop::YieldFor (part of r58911) git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@58923 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775 --- src/cocoa/app.mm | 69 -------------------------------------- src/cocoa/evtloop.mm | 57 +++++++++++++++++++++++++++++++ src/osx/carbon/app.cpp | 54 ----------------------------- src/osx/carbon/evtloop.cpp | 36 ++++++++++++++++++++ 4 files changed, 93 insertions(+), 123 deletions(-) diff --git a/src/cocoa/app.mm b/src/cocoa/app.mm index 7cde079e14..80402ff4f9 100644 --- a/src/cocoa/app.mm +++ b/src/cocoa/app.mm @@ -294,75 +294,6 @@ void wxApp::Exit() wxAppConsole::Exit(); } -// Yield to other processes -bool wxApp::DoYield(bool onlyIfNeeded, long eventsToProcess) -{ -#if wxUSE_LOG - // disable log flushing from here because a call to wxYield() shouldn't - // normally result in message boxes popping up &c - wxLog::Suspend(); -#endif // wxUSE_LOG - - if (m_isInsideYield) - { - if ( !onlyIfNeeded ) - { - wxFAIL_MSG( wxT("wxYield called recursively" ) ); - } - - return false; - } - - m_isInsideYield = true; - m_eventsToProcessInsideYield = eventsToProcess; - - // Run the event loop until it is out of events - while(1) - { - // TODO: implement event filtering using the eventsToProcess mask - - wxAutoNSAutoreleasePool pool; - /* NOTE: It may be better to use something like - NSEventTrackingRunLoopMode since we don't necessarily want all - timers/sources/observers to run, only those which would - run while tracking events. However, it should be noted that - NSEventTrackingRunLoopMode is in the common set of modes - so it may not effectively make much of a difference. - */ - NSEvent *event = [GetNSApplication() - nextEventMatchingMask:NSAnyEventMask - untilDate:[NSDate distantPast] - inMode:NSDefaultRunLoopMode - dequeue: YES]; - if(!event) - break; - [GetNSApplication() sendEvent: event]; - } - - /* - Because we just told NSApplication to avoid blocking it will in turn - run the CFRunLoop with a timeout of 0 seconds. In that case, our - run loop observer on kCFRunLoopBeforeWaiting never fires because - no waiting occurs. Therefore, no idle events are sent. - - Believe it or not, this is actually desirable because we do not want - to process idle from here. However, we do want to process pending - events because some user code expects to do work in a thread while - the main thread waits and then notify the main thread by posting - an event. - */ - ProcessPendingEvents(); - -#if wxUSE_LOG - // let the logs be flashed again - wxLog::Resume(); -#endif // wxUSE_LOG - - m_isInsideYield = false; - - return true; -} - void wxApp::WakeUpIdle() { /* When called from the main thread the NSAutoreleasePool managed by diff --git a/src/cocoa/evtloop.mm b/src/cocoa/evtloop.mm index b46b1ffcee..abffb75f88 100644 --- a/src/cocoa/evtloop.mm +++ b/src/cocoa/evtloop.mm @@ -117,3 +117,60 @@ int wxGUIEventLoop::DispatchTimeout(unsigned long timeout) return true; } +bool wxGUIEventLoop::YieldFor(long eventsToProcess) +{ +#if wxUSE_LOG + // disable log flushing from here because a call to wxYield() shouldn't + // normally result in message boxes popping up &c + wxLog::Suspend(); +#endif // wxUSE_LOG + + m_isInsideYield = true; + m_eventsToProcessInsideYield = eventsToProcess; + + // Run the event loop until it is out of events + while (1) + { + // TODO: implement event filtering using the eventsToProcess mask + + wxAutoNSAutoreleasePool pool; + /* NOTE: It may be better to use something like + NSEventTrackingRunLoopMode since we don't necessarily want all + timers/sources/observers to run, only those which would + run while tracking events. However, it should be noted that + NSEventTrackingRunLoopMode is in the common set of modes + so it may not effectively make much of a difference. + */ + NSEvent *event = [GetNSApplication() + nextEventMatchingMask:NSAnyEventMask + untilDate:[NSDate distantPast] + inMode:NSDefaultRunLoopMode + dequeue: YES]; + if(!event) + break; + [GetNSApplication() sendEvent: event]; + } + + /* + Because we just told NSApplication to avoid blocking it will in turn + run the CFRunLoop with a timeout of 0 seconds. In that case, our + run loop observer on kCFRunLoopBeforeWaiting never fires because + no waiting occurs. Therefore, no idle events are sent. + + Believe it or not, this is actually desirable because we do not want + to process idle from here. However, we do want to process pending + events because some user code expects to do work in a thread while + the main thread waits and then notify the main thread by posting + an event. + */ + ProcessPendingEvents(); + +#if wxUSE_LOG + // let the logs be flashed again + wxLog::Resume(); +#endif // wxUSE_LOG + + m_isInsideYield = false; + + return true; +} diff --git a/src/osx/carbon/app.cpp b/src/osx/carbon/app.cpp index 2b8c675d3d..b1854d2b76 100644 --- a/src/osx/carbon/app.cpp +++ b/src/osx/carbon/app.cpp @@ -1117,60 +1117,6 @@ void wxCYield() wxYield() ; } -// Yield to other processes - -bool wxApp::DoYield(bool onlyIfNeeded, long eventsToProcess) -{ -#if wxUSE_THREADS - // Yielding from a non-gui thread needs to bail out, otherwise we end up - // possibly sending events in the thread too. - if ( !wxThread::IsMain() ) - { - return true; - } -#endif // wxUSE_THREADS - - if (m_isInsideYield) - { - if ( !onlyIfNeeded ) - { - wxFAIL_MSG( wxT("wxYield called recursively" ) ); - } - - return false; - } - - m_isInsideYield = true; - m_eventsToProcessInsideYield = eventsToProcess; - -#if wxUSE_LOG - // disable log flushing from here because a call to wxYield() shouldn't - // normally result in message boxes popping up &c - wxLog::Suspend(); -#endif // wxUSE_LOG - - wxEventLoop * const - loop = static_cast(wxEventLoop::GetActive()); - if ( loop ) - { - // process all pending events: - while ( loop->Pending() ) - loop->Dispatch(); - } - - // it's necessary to call ProcessIdle() to update the frames sizes which - // might have been changed (it also will update other things set from - // OnUpdateUI() which is a nice (and desired) side effect) - while ( ProcessIdle() ) {} - -#if wxUSE_LOG - wxLog::Resume(); -#endif // wxUSE_LOG - m_isInsideYield = false; - - return true; -} - // virtual void wxApp::MacHandleUnhandledEvent( WXEVENTREF WXUNUSED(evr) ) { diff --git a/src/osx/carbon/evtloop.cpp b/src/osx/carbon/evtloop.cpp index 45aad41e25..1a2937afbc 100644 --- a/src/osx/carbon/evtloop.cpp +++ b/src/osx/carbon/evtloop.cpp @@ -137,3 +137,39 @@ int wxGUIEventLoop::DispatchTimeout(unsigned long timeout) } } +bool wxGUIEventLoop::YieldFor(long eventsToProcess) +{ +#if wxUSE_THREADS + // Yielding from a non-gui thread needs to bail out, otherwise we end up + // possibly sending events in the thread too. + if ( !wxThread::IsMain() ) + { + return true; + } +#endif // wxUSE_THREADS + + m_isInsideYield = true; + m_eventsToProcessInsideYield = eventsToProcess; + +#if wxUSE_LOG + // disable log flushing from here because a call to wxYield() shouldn't + // normally result in message boxes popping up &c + wxLog::Suspend(); +#endif // wxUSE_LOG + + // process all pending events: + while ( Pending() ) + Dispatch(); + + // it's necessary to call ProcessIdle() to update the frames sizes which + // might have been changed (it also will update other things set from + // OnUpdateUI() which is a nice (and desired) side effect) + while ( ProcessIdle() ) {} + +#if wxUSE_LOG + wxLog::Resume(); +#endif // wxUSE_LOG + m_isInsideYield = false; + + return true; +} -- 2.47.2