Allow recursive calls to wxEventLoop::Yield().
There doesn't seem to be any reason to forbid them and this change allows wxExecute() without wxEXEC_NOEVENTS to work without assertion failures when called from inside wxYield(). git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@77650 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775
This commit is contained in:
@@ -44,6 +44,7 @@ All:
|
|||||||
- Allow specifying custom comparator for wxSortedArrayString (Catalin Raceanu).
|
- Allow specifying custom comparator for wxSortedArrayString (Catalin Raceanu).
|
||||||
- Add wxDateTime::GetWeekBasedYear().
|
- Add wxDateTime::GetWeekBasedYear().
|
||||||
- Specialize std::hash<> for wxString when using C++11.
|
- Specialize std::hash<> for wxString when using C++11.
|
||||||
|
- Allow recursive calls to wxYield().
|
||||||
|
|
||||||
Unix:
|
Unix:
|
||||||
|
|
||||||
|
@@ -145,8 +145,8 @@ public:
|
|||||||
|
|
||||||
// process all currently pending events right now
|
// process all currently pending events right now
|
||||||
//
|
//
|
||||||
// it is an error to call Yield() recursively unless the value of
|
// if onlyIfNeeded is true, returns false without doing anything else if
|
||||||
// onlyIfNeeded is true
|
// we're already inside Yield()
|
||||||
//
|
//
|
||||||
// WARNING: this function is dangerous as it can lead to unexpected
|
// WARNING: this function is dangerous as it can lead to unexpected
|
||||||
// reentrancies (i.e. when called from an event handler it
|
// reentrancies (i.e. when called from an event handler it
|
||||||
@@ -162,7 +162,7 @@ public:
|
|||||||
|
|
||||||
// returns true if the main thread is inside a Yield() call
|
// returns true if the main thread is inside a Yield() call
|
||||||
virtual bool IsYielding() const
|
virtual bool IsYielding() const
|
||||||
{ return m_isInsideYield; }
|
{ return m_yieldLevel != 0; }
|
||||||
|
|
||||||
// returns true if events of the given event category should be immediately
|
// returns true if events of the given event category should be immediately
|
||||||
// processed inside a wxApp::Yield() call or rather should be queued for
|
// processed inside a wxApp::Yield() call or rather should be queued for
|
||||||
@@ -214,8 +214,10 @@ protected:
|
|||||||
// should we exit the loop?
|
// should we exit the loop?
|
||||||
bool m_shouldExit;
|
bool m_shouldExit;
|
||||||
|
|
||||||
// YieldFor() helpers:
|
// incremented each time on entering Yield() and decremented on leaving it
|
||||||
bool m_isInsideYield;
|
int m_yieldLevel;
|
||||||
|
|
||||||
|
// the argument of the last call to YieldFor()
|
||||||
long m_eventsToProcessInsideYield;
|
long m_eventsToProcessInsideYield;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
@@ -224,7 +224,6 @@ public:
|
|||||||
user to perform actions which are not compatible with the current task.
|
user to perform actions which are not compatible with the current task.
|
||||||
Disabling menu items or whole menus during processing can avoid unwanted
|
Disabling menu items or whole menus during processing can avoid unwanted
|
||||||
reentrance of code: see ::wxSafeYield for a better function.
|
reentrance of code: see ::wxSafeYield for a better function.
|
||||||
You can avoid unwanted reentrancies also using IsYielding().
|
|
||||||
|
|
||||||
Note that Yield() will not flush the message logs. This is intentional as
|
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
|
calling Yield() is usually done to quickly update the screen and popping up
|
||||||
@@ -232,10 +231,9 @@ public:
|
|||||||
messages immediately (otherwise it will be done during the next idle loop
|
messages immediately (otherwise it will be done during the next idle loop
|
||||||
iteration), call wxLog::FlushActive.
|
iteration), call wxLog::FlushActive.
|
||||||
|
|
||||||
Calling Yield() recursively is normally an error and an assert failure is
|
If @a onlyIfNeeded parameter is @true and the flow control is already
|
||||||
raised in debug build if such situation is detected. However if the
|
inside Yield(), i.e. IsYielding() returns @true, the method just
|
||||||
@a onlyIfNeeded parameter is @true, the method will just silently
|
silently returns @false and doesn't do anything.
|
||||||
return @false instead.
|
|
||||||
*/
|
*/
|
||||||
bool Yield(bool onlyIfNeeded = false);
|
bool Yield(bool onlyIfNeeded = false);
|
||||||
|
|
||||||
|
@@ -34,7 +34,7 @@ wxEventLoopBase::wxEventLoopBase()
|
|||||||
{
|
{
|
||||||
m_isInsideRun = false;
|
m_isInsideRun = false;
|
||||||
m_shouldExit = false;
|
m_shouldExit = false;
|
||||||
m_isInsideYield = false;
|
m_yieldLevel = 0;
|
||||||
m_eventsToProcessInsideYield = wxEVT_CATEGORY_ALL;
|
m_eventsToProcessInsideYield = wxEVT_CATEGORY_ALL;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -100,15 +100,8 @@ bool wxEventLoopBase::ProcessIdle()
|
|||||||
|
|
||||||
bool wxEventLoopBase::Yield(bool onlyIfNeeded)
|
bool wxEventLoopBase::Yield(bool onlyIfNeeded)
|
||||||
{
|
{
|
||||||
if ( m_isInsideYield )
|
if ( onlyIfNeeded && IsYielding() )
|
||||||
{
|
|
||||||
if ( !onlyIfNeeded )
|
|
||||||
{
|
|
||||||
wxFAIL_MSG( wxT("wxYield called recursively" ) );
|
|
||||||
}
|
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
}
|
|
||||||
|
|
||||||
return YieldFor(wxEVT_CATEGORY_ALL);
|
return YieldFor(wxEVT_CATEGORY_ALL);
|
||||||
}
|
}
|
||||||
@@ -124,10 +117,14 @@ bool wxEventLoopBase::YieldFor(long eventsToProcess)
|
|||||||
#endif // wxUSE_THREADS
|
#endif // wxUSE_THREADS
|
||||||
|
|
||||||
// set the flag and don't forget to reset it before returning
|
// set the flag and don't forget to reset it before returning
|
||||||
m_isInsideYield = true;
|
const int yieldLevelOld = m_yieldLevel;
|
||||||
m_eventsToProcessInsideYield = eventsToProcess;
|
const long eventsToProcessOld = m_eventsToProcessInsideYield;
|
||||||
|
|
||||||
wxON_BLOCK_EXIT_SET(m_isInsideYield, false);
|
m_yieldLevel++;
|
||||||
|
wxON_BLOCK_EXIT_SET(m_yieldLevel, yieldLevelOld);
|
||||||
|
|
||||||
|
m_eventsToProcessInsideYield = eventsToProcess;
|
||||||
|
wxON_BLOCK_EXIT_SET(m_eventsToProcessInsideYield, eventsToProcessOld);
|
||||||
|
|
||||||
#if wxUSE_LOG
|
#if wxUSE_LOG
|
||||||
// disable log flushing from here because a call to wxYield() shouldn't
|
// disable log flushing from here because a call to wxYield() shouldn't
|
||||||
|
Reference in New Issue
Block a user