added wxApp::Yield()

git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@12095 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775
This commit is contained in:
Vadim Zeitlin
2001-10-19 18:29:32 +00:00
parent 85ee61ac2e
commit 8461e4c253
19 changed files with 2116 additions and 2100 deletions

View File

@@ -603,3 +603,29 @@ This function currently only has effect under GTK.
\docparam{flag}{If TRUE, the app will use the best visual.} \docparam{flag}{If TRUE, the app will use the best visual.}
\membersection{wxApp::Yield}{wxappyield}
\func{bool}{Yield}{\param{bool}{ onlyIfNeeded = FALSE}}
Yields control to pending messages in the windowing system. This can be useful, for example, when a
time-consuming process writes to a text window. Without an occasional
yield, the text window will not be updated properly, and on systems with
cooperative multitasking, such as Windows 3.1 other processes will not respond.
Caution should be exercised, however, since yielding may allow the
user to perform actions which are not compatible with the current task.
Disabling menu items or whole menus during processing can avoid unwanted
reentrance of code: see \helpref{::wxSafeYield}{wxsafeyield} for a better
function.
Note that Yield() will not flush the message logs. This is intentional as
calling Yield() is usually done to quickly update the screen and popping up a
message box dialog may be undesirable. If you do wish to flush the log
messages immediately (otherwise it will be done during the next idle loop
iteration), call \helpref{wxLog::FlushActive}{wxlogflushactive}.
Calling Yield() recursively is normally an error and an assert failure is
raised in debug build if such situation is detected. However if the the
{\it onlyIfNeeded} parameter is {\tt TRUE}, the method will just silently
return {\tt FALSE} instead.

View File

@@ -2143,22 +2143,10 @@ See also \helpref{wxGetResource}{wxgetresource}, \helpref{wxConfigBase}{wxconfig
\func{bool}{wxYield}{\void} \func{bool}{wxYield}{\void}
Yields control to pending messages in the windowing system. This can be useful, for example, when a Calls \helpref{wxApp::Yield}{wxappyield}.
time-consuming process writes to a text window. Without an occasional
yield, the text window will not be updated properly, and on systems with
cooperative multitasking, such as Windows 3.1 other processes will not respond.
Caution should be exercised, however, since yielding may allow the This function is kept only for backwards compatibility, please use the
user to perform actions which are not compatible with the current task. wxApp method instead in any new code.
Disabling menu items or whole menus during processing can avoid unwanted
reentrance of code: see \helpref{::wxSafeYield}{wxsafeyield} for a better
function.
Note that wxYield will not flush the message logs. This is intentional as
calling wxYield is usually done to quickly update the screen and popping up a
message box dialog may be undesirable. If you do wish to flush the log
messages immediately (otherwise it will be done during the next idle loop
iteration), call \helpref{wxLog::FlushActive}{wxlogflushactive}.
\wxheading{Include files} \wxheading{Include files}

View File

@@ -65,9 +65,6 @@ public:
// the virtual functions which may/must be overridden in the derived class // the virtual functions which may/must be overridden in the derived class
// ----------------------------------------------------------------------- // -----------------------------------------------------------------------
#ifdef __DARWIN__
virtual ~wxAppBase() { }
#endif
// called during the program initialization, returning FALSE from here // called during the program initialization, returning FALSE from here
// prevents the program from continuing - it's a good place to create // prevents the program from continuing - it's a good place to create
@@ -135,6 +132,17 @@ public:
// process the first event in the event queue (blocks until an event // process the first event in the event queue (blocks until an event
// apperas if there are none currently) // apperas if there are none currently)
virtual void Dispatch() = 0; virtual void Dispatch() = 0;
// process all currently pending events right now
//
// it is an error to call Yield() recursively unless the value of
// onlyIfNeeded is TRUE
//
// WARNING: this function is dangerous as it can lead to unexpected
// reentrancies (i.e. when called from an event handler it
// may result in calling the same event handler again), use
// with _extreme_ care or, better, don't use at all!
virtual bool Yield(bool onlyIfNeeded = FALSE) = 0;
#endif // wxUSE_GUI #endif // wxUSE_GUI
// application info: name, description, vendor // application info: name, description, vendor
@@ -285,6 +293,11 @@ public:
static wxAppInitializerFunction GetInitializerFunction() static wxAppInitializerFunction GetInitializerFunction()
{ return m_appInitFn; } { return m_appInitFn; }
// needed to avoid link errors
#ifdef __DARWIN__
virtual ~wxAppBase() { }
#endif
// process all events in the wxPendingEvents list // process all events in the wxPendingEvents list
virtual void ProcessPendingEvents(); virtual void ProcessPendingEvents();

View File

@@ -1,5 +1,5 @@
///////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////
// Name: app.h // Name: wx/gtk/app.h
// Purpose: // Purpose:
// Author: Robert Roebling // Author: Robert Roebling
// Id: $Id$ // Id: $Id$
@@ -46,6 +46,7 @@ public:
virtual bool Initialized(); virtual bool Initialized();
virtual bool Pending(); virtual bool Pending();
virtual void Dispatch(); virtual void Dispatch();
virtual bool Yield(bool onlyIfNeeded = FALSE);
virtual wxIcon GetStdIcon(int which) const; virtual wxIcon GetStdIcon(int which) const;

View File

@@ -1,5 +1,5 @@
///////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////
// Name: app.h // Name: wx/gtk/app.h
// Purpose: // Purpose:
// Author: Robert Roebling // Author: Robert Roebling
// Id: $Id$ // Id: $Id$
@@ -46,6 +46,7 @@ public:
virtual bool Initialized(); virtual bool Initialized();
virtual bool Pending(); virtual bool Pending();
virtual void Dispatch(); virtual void Dispatch();
virtual bool Yield(bool onlyIfNeeded = FALSE);
virtual wxIcon GetStdIcon(int which) const; virtual wxIcon GetStdIcon(int which) const;

View File

@@ -51,6 +51,7 @@ class WXDLLEXPORT wxApp: public wxAppBase
virtual bool Initialized(); virtual bool Initialized();
virtual bool Pending() ; virtual bool Pending() ;
virtual void Dispatch() ; virtual void Dispatch() ;
virtual bool Yield(bool onlyIfNeeded = FALSE);
virtual wxIcon GetStdIcon(int which) const; virtual wxIcon GetStdIcon(int which) const;
virtual void SetPrintMode(int mode) { m_printMode = mode; } virtual void SetPrintMode(int mode) { m_printMode = mode; }

View File

@@ -53,6 +53,7 @@ public:
virtual bool Initialized(); virtual bool Initialized();
virtual bool Pending(); virtual bool Pending();
virtual void Dispatch(); virtual void Dispatch();
virtual bool Yield(bool onlyIfNeeded = FALSE);
virtual bool OnInitGui(); virtual bool OnInitGui();

View File

@@ -41,6 +41,7 @@ public:
virtual bool Initialized(); virtual bool Initialized();
virtual bool Pending(); virtual bool Pending();
virtual void Dispatch(); virtual void Dispatch();
virtual bool Yield(bool onlyIfNeeded = FALSE);
virtual wxIcon GetStdIcon(int which) const; virtual wxIcon GetStdIcon(int which) const;

View File

@@ -76,6 +76,7 @@ public:
virtual bool Initialized(void); virtual bool Initialized(void);
virtual bool Pending(void) ; virtual bool Pending(void) ;
virtual void Dispatch(void); virtual void Dispatch(void);
virtual bool Yield(bool onlyIfNeeded = FALSE);
virtual wxIcon GetStdIcon(int which) const; virtual wxIcon GetStdIcon(int which) const;

View File

@@ -20,7 +20,6 @@
#pragma interface "utils.h" #pragma interface "utils.h"
#endif #endif
#include "wx/setup.h"
#include "wx/object.h" #include "wx/object.h"
#include "wx/list.h" #include "wx/list.h"
#include "wx/filefn.h" #include "wx/filefn.h"

View File

@@ -76,13 +76,6 @@ void WXDLLEXPORT wxExit()
abort(); abort();
} }
// Yield to other apps/messages
bool WXDLLEXPORT wxYield()
{
// do nothing
return TRUE;
}
// Yield to other apps/messages // Yield to other apps/messages
void WXDLLEXPORT wxWakeUpIdle() void WXDLLEXPORT wxWakeUpIdle()
{ {

View File

@@ -36,6 +36,7 @@
#include "wx/log.h" #include "wx/log.h"
#if wxUSE_GUI #if wxUSE_GUI
#include "wx/app.h"
#include "wx/window.h" #include "wx/window.h"
#include "wx/frame.h" #include "wx/frame.h"
#include "wx/menu.h" #include "wx/menu.h"
@@ -1312,4 +1313,25 @@ long wxExecute(const wxString& command,
return wxDoExecuteWithCapture(command, output, &error); return wxDoExecuteWithCapture(command, output, &error);
} }
// ----------------------------------------------------------------------------
// wxApp::Yield() wrappers for backwards compatibility
// ----------------------------------------------------------------------------
bool wxYield()
{
#if wxUSE_GUI
return wxTheApp && wxTheApp->Yield();
#else
return FALSE;
#endif
}
bool wxYieldIfNeeded()
{
#if wxUSE_GUI
return wxTheApp && wxTheApp->Yield(TRUE);
#else
return FALSE;
#endif
}

View File

@@ -83,10 +83,21 @@ void wxExit()
// wxYield // wxYield
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
static bool gs_inYield = FALSE; bool wxApp::Yield(bool onlyIfNeeded)
bool wxYield()
{ {
// MT-FIXME
static bool s_inYield = FALSE;
if ( s_inYield )
{
if ( !onlyIfNeeded )
{
wxFAIL_MSG( wxT("wxYield called recursively" ) );
}
return FALSE;
}
#if wxUSE_THREADS #if wxUSE_THREADS
if ( !wxThread::IsMain() ) if ( !wxThread::IsMain() )
{ {
@@ -95,19 +106,14 @@ bool wxYield()
} }
#endif // wxUSE_THREADS #endif // wxUSE_THREADS
#ifdef __WXDEBUG__ s_inYield = TRUE;
if (gs_inYield)
wxFAIL_MSG( wxT("wxYield called recursively" ) );
#endif
gs_inYield = TRUE;
if (!g_isIdle) if (!g_isIdle)
{ {
// We need to remove idle callbacks or the loop will // We need to remove idle callbacks or the loop will
// never finish. // never finish.
gtk_idle_remove( wxTheApp->m_idleTag ); gtk_idle_remove( m_idleTag );
wxTheApp->m_idleTag = 0; m_idleTag = 0;
g_isIdle = TRUE; g_isIdle = TRUE;
} }
@@ -121,29 +127,18 @@ bool wxYield()
/* it's necessary to call ProcessIdle() to update the frames sizes which /* it's necessary to call ProcessIdle() to update the frames sizes which
might have been changed (it also will update other things set from might have been changed (it also will update other things set from
OnUpdateUI() which is a nice (and desired) side effect) */ OnUpdateUI() which is a nice (and desired) side effect) */
while (wxTheApp->ProcessIdle()) { } while ( ProcessIdle() )
{
}
// let the logs be flashed again // let the logs be flashed again
wxLog::Resume(); wxLog::Resume();
gs_inYield = FALSE; s_inYield = FALSE;
return TRUE; return TRUE;
} }
//-----------------------------------------------------------------------------
// wxYieldIfNeeded
// Like wxYield, but fails silently if the yield is recursive.
//-----------------------------------------------------------------------------
bool wxYieldIfNeeded()
{
if (gs_inYield)
return FALSE;
return wxYield();
}
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
// wxWakeUpIdle // wxWakeUpIdle
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------

View File

@@ -83,10 +83,21 @@ void wxExit()
// wxYield // wxYield
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
static bool gs_inYield = FALSE; bool wxApp::Yield(bool onlyIfNeeded)
bool wxYield()
{ {
// MT-FIXME
static bool s_inYield = FALSE;
if ( s_inYield )
{
if ( !onlyIfNeeded )
{
wxFAIL_MSG( wxT("wxYield called recursively" ) );
}
return FALSE;
}
#if wxUSE_THREADS #if wxUSE_THREADS
if ( !wxThread::IsMain() ) if ( !wxThread::IsMain() )
{ {
@@ -95,19 +106,14 @@ bool wxYield()
} }
#endif // wxUSE_THREADS #endif // wxUSE_THREADS
#ifdef __WXDEBUG__ s_inYield = TRUE;
if (gs_inYield)
wxFAIL_MSG( wxT("wxYield called recursively" ) );
#endif
gs_inYield = TRUE;
if (!g_isIdle) if (!g_isIdle)
{ {
// We need to remove idle callbacks or the loop will // We need to remove idle callbacks or the loop will
// never finish. // never finish.
gtk_idle_remove( wxTheApp->m_idleTag ); gtk_idle_remove( m_idleTag );
wxTheApp->m_idleTag = 0; m_idleTag = 0;
g_isIdle = TRUE; g_isIdle = TRUE;
} }
@@ -121,29 +127,18 @@ bool wxYield()
/* it's necessary to call ProcessIdle() to update the frames sizes which /* it's necessary to call ProcessIdle() to update the frames sizes which
might have been changed (it also will update other things set from might have been changed (it also will update other things set from
OnUpdateUI() which is a nice (and desired) side effect) */ OnUpdateUI() which is a nice (and desired) side effect) */
while (wxTheApp->ProcessIdle()) { } while ( ProcessIdle() )
{
}
// let the logs be flashed again // let the logs be flashed again
wxLog::Resume(); wxLog::Resume();
gs_inYield = FALSE; s_inYield = FALSE;
return TRUE; return TRUE;
} }
//-----------------------------------------------------------------------------
// wxYieldIfNeeded
// Like wxYield, but fails silently if the yield is recursive.
//-----------------------------------------------------------------------------
bool wxYieldIfNeeded()
{
if (gs_inYield)
return FALSE;
return wxYield();
}
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
// wxWakeUpIdle // wxWakeUpIdle
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------

View File

@@ -923,16 +923,21 @@ void wxCYield()
// Yield to other processes // Yield to other processes
static bool gs_inYield = FALSE; bool wxApp::Yield(bool onlyIfNeeded)
bool wxYield()
{ {
#ifdef __WXDEBUG__ static bool s_inYield = FALSE;
if (gs_inYield)
wxFAIL_MSG( wxT("wxYield called recursively" ) );
#endif
gs_inYield = TRUE; if (s_inYield)
{
if ( !onlyIfNeeded )
{
wxFAIL_MSG( wxT("wxYield called recursively" ) );
}
return FALSE;
}
s_inYield = TRUE;
#if wxUSE_THREADS #if wxUSE_THREADS
YieldToAnyThread() ; YieldToAnyThread() ;
@@ -950,20 +955,11 @@ bool wxYield()
wxMacProcessNotifierAndPendingEvents() ; wxMacProcessNotifierAndPendingEvents() ;
gs_inYield = FALSE; s_inYield = FALSE;
return TRUE; return TRUE;
} }
// Yield to incoming messages; but fail silently if recursion is detected.
bool wxYieldIfNeeded()
{
if (gs_inYield)
return FALSE;
return wxYield();
}
// platform specifics // platform specifics
void wxApp::MacSuspend( bool convertClipboard ) void wxApp::MacSuspend( bool convertClipboard )

View File

@@ -923,16 +923,21 @@ void wxCYield()
// Yield to other processes // Yield to other processes
static bool gs_inYield = FALSE; bool wxApp::Yield(bool onlyIfNeeded)
bool wxYield()
{ {
#ifdef __WXDEBUG__ static bool s_inYield = FALSE;
if (gs_inYield)
wxFAIL_MSG( wxT("wxYield called recursively" ) );
#endif
gs_inYield = TRUE; if (s_inYield)
{
if ( !onlyIfNeeded )
{
wxFAIL_MSG( wxT("wxYield called recursively" ) );
}
return FALSE;
}
s_inYield = TRUE;
#if wxUSE_THREADS #if wxUSE_THREADS
YieldToAnyThread() ; YieldToAnyThread() ;
@@ -950,20 +955,11 @@ bool wxYield()
wxMacProcessNotifierAndPendingEvents() ; wxMacProcessNotifierAndPendingEvents() ;
gs_inYield = FALSE; s_inYield = FALSE;
return TRUE; return TRUE;
} }
// Yield to incoming messages; but fail silently if recursion is detected.
bool wxYieldIfNeeded()
{
if (gs_inYield)
return FALSE;
return wxYield();
}
// platform specifics // platform specifics
void wxApp::MacSuspend( bool convertClipboard ) void wxApp::MacSuspend( bool convertClipboard )

View File

@@ -737,40 +737,30 @@ void wxExit()
// Yield to other processes // Yield to other processes
static bool gs_inYield = FALSE; bool wxApp::Yield(bool onlyIfNeeded)
bool wxYield()
{ {
#ifdef __WXDEBUG__ bool s_inYield = FALSE;
if (gs_inYield)
wxFAIL_MSG( wxT("wxYield called recursively" ) );
#endif
gs_inYield = TRUE; if ( s_inYield )
{
if ( !onlyIfNeeded )
{
wxFAIL_MSG( wxT("wxYield called recursively" ) );
}
return FALSE;
}
s_inYield = TRUE;
while (wxTheApp && wxTheApp->Pending()) while (wxTheApp && wxTheApp->Pending())
wxTheApp->Dispatch(); wxTheApp->Dispatch();
// VZ: is it the same as this (taken from old wxExecute)? s_inYield = FALSE;
#if 0
XtAppProcessEvent((XtAppContext) wxTheApp->GetAppContext(), XtIMAll);
#endif
gs_inYield = FALSE;
return TRUE; return TRUE;
} }
// Yield to incoming messages; but fail silently if recursion is detected.
bool wxYieldIfNeeded()
{
if (gs_inYield)
return FALSE;
return wxYield();
}
// TODO use XmGetPixmap (?) to get the really standard icons! // TODO use XmGetPixmap (?) to get the really standard icons!
#include "wx/generic/info.xpm" #include "wx/generic/info.xpm"

View File

@@ -1435,20 +1435,26 @@ void wxExit()
// Yield to incoming messages // Yield to incoming messages
static bool gs_inYield = FALSE; bool wxApp::Yield(bool onlyIfNeeded)
bool wxYield()
{ {
// MT-FIXME
static bool s_inYield = FALSE;
// disable log flushing from here because a call to wxYield() shouldn't // disable log flushing from here because a call to wxYield() shouldn't
// normally result in message boxes popping up &c // normally result in message boxes popping up &c
wxLog::Suspend(); wxLog::Suspend();
#ifdef __WXDEBUG__ if ( s_inYield )
if (gs_inYield) {
if ( !onlyIfNeeded )
{
wxFAIL_MSG( wxT("wxYield called recursively" ) ); wxFAIL_MSG( wxT("wxYield called recursively" ) );
#endif }
gs_inYield = TRUE; return FALSE;
}
s_inYield = TRUE;
// we don't want to process WM_QUIT from here - it should be processed in // we don't want to process WM_QUIT from here - it should be processed in
// the main event loop in order to stop it // the main event loop in order to stop it
@@ -1464,27 +1470,17 @@ bool wxYield()
break; break;
} }
// If they are pending events, we must process them. // if there are pending events, we must process them.
if (wxTheApp) ProcessPendingEvents();
wxTheApp->ProcessPendingEvents();
// let the logs be flashed again // let the logs be flashed again
wxLog::Resume(); wxLog::Resume();
gs_inYield = FALSE; s_inYield = FALSE;
return TRUE; return TRUE;
} }
// Yield to incoming messages; but fail silently if recursion is detected.
bool wxYieldIfNeeded()
{
if (gs_inYield)
return FALSE;
return wxYield();
}
bool wxHandleFatalExceptions(bool doit) bool wxHandleFatalExceptions(bool doit)
{ {
#if wxUSE_ON_FATAL_EXCEPTION #if wxUSE_ON_FATAL_EXCEPTION
@@ -1493,7 +1489,7 @@ bool wxHandleFatalExceptions(bool doit)
return TRUE; return TRUE;
#else #else
wxFAIL_MSG(_T("set wxUSE_ON_FATAL_EXCEPTION to 1 to sue this function")); wxFAIL_MSG(_T("set wxUSE_ON_FATAL_EXCEPTION to 1 to use this function"));
(void)doit; (void)doit;
return FALSE; return FALSE;

View File

@@ -1117,13 +1117,23 @@ void wxExit()
wxApp::CleanUp(); wxApp::CleanUp();
} // end of wxExit } // end of wxExit
static bool gs_inYield = FALSE;
// //
// Yield to incoming messages // Yield to incoming messages
// //
bool wxYield() bool wxApp::Yield(bool onlyIfNeeded)
{ {
static bool s_inYield = FALSE;
if ( s_inYield )
{
if ( !onlyIfNeeded )
{
wxFAIL_MSG( _T("wxYield() called recursively") );
}
return FALSE;
}
HAB vHab = 0; HAB vHab = 0;
QMSG vMsg; QMSG vMsg;
@@ -1133,7 +1143,7 @@ bool wxYield()
// //
wxLog::Suspend(); wxLog::Suspend();
gs_inYield = TRUE; s_inYield = TRUE;
// //
// We want to go back to the main message loop // We want to go back to the main message loop
@@ -1157,19 +1167,10 @@ bool wxYield()
// Let the logs be flashed again // Let the logs be flashed again
// //
wxLog::Resume(); wxLog::Resume();
gs_inYield = FALSE; s_inYield = FALSE;
return TRUE; return TRUE;
} // end of wxYield } // end of wxYield
// Yield to incoming messages; but fail silently if recursion is detected.
bool wxYieldIfNeeded()
{
if (gs_inYield)
return FALSE;
return wxYield();
}
wxIcon wxApp::GetStdIcon( wxIcon wxApp::GetStdIcon(
int nWhich int nWhich
) const ) const