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).
|
||||
- Add wxDateTime::GetWeekBasedYear().
|
||||
- Specialize std::hash<> for wxString when using C++11.
|
||||
- Allow recursive calls to wxYield().
|
||||
|
||||
Unix:
|
||||
|
||||
|
@@ -145,8 +145,8 @@ public:
|
||||
|
||||
// process all currently pending events right now
|
||||
//
|
||||
// it is an error to call Yield() recursively unless the value of
|
||||
// onlyIfNeeded is true
|
||||
// if onlyIfNeeded is true, returns false without doing anything else if
|
||||
// we're already inside Yield()
|
||||
//
|
||||
// WARNING: this function is dangerous as it can lead to unexpected
|
||||
// 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
|
||||
virtual bool IsYielding() const
|
||||
{ return m_isInsideYield; }
|
||||
{ return m_yieldLevel != 0; }
|
||||
|
||||
// returns true if events of the given event category should be immediately
|
||||
// processed inside a wxApp::Yield() call or rather should be queued for
|
||||
@@ -214,8 +214,10 @@ protected:
|
||||
// should we exit the loop?
|
||||
bool m_shouldExit;
|
||||
|
||||
// YieldFor() helpers:
|
||||
bool m_isInsideYield;
|
||||
// incremented each time on entering Yield() and decremented on leaving it
|
||||
int m_yieldLevel;
|
||||
|
||||
// the argument of the last call to YieldFor()
|
||||
long m_eventsToProcessInsideYield;
|
||||
|
||||
private:
|
||||
|
@@ -224,7 +224,6 @@ public:
|
||||
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 ::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
|
||||
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
|
||||
iteration), call wxLog::FlushActive.
|
||||
|
||||
Calling Yield() recursively is normally an error and an assert failure is
|
||||
raised in debug build if such situation is detected. However if the
|
||||
@a onlyIfNeeded parameter is @true, the method will just silently
|
||||
return @false instead.
|
||||
If @a onlyIfNeeded parameter is @true and the flow control is already
|
||||
inside Yield(), i.e. IsYielding() returns @true, the method just
|
||||
silently returns @false and doesn't do anything.
|
||||
*/
|
||||
bool Yield(bool onlyIfNeeded = false);
|
||||
|
||||
|
@@ -34,7 +34,7 @@ wxEventLoopBase::wxEventLoopBase()
|
||||
{
|
||||
m_isInsideRun = false;
|
||||
m_shouldExit = false;
|
||||
m_isInsideYield = false;
|
||||
m_yieldLevel = 0;
|
||||
m_eventsToProcessInsideYield = wxEVT_CATEGORY_ALL;
|
||||
}
|
||||
|
||||
@@ -100,15 +100,8 @@ bool wxEventLoopBase::ProcessIdle()
|
||||
|
||||
bool wxEventLoopBase::Yield(bool onlyIfNeeded)
|
||||
{
|
||||
if ( m_isInsideYield )
|
||||
{
|
||||
if ( !onlyIfNeeded )
|
||||
{
|
||||
wxFAIL_MSG( wxT("wxYield called recursively" ) );
|
||||
}
|
||||
|
||||
if ( onlyIfNeeded && IsYielding() )
|
||||
return false;
|
||||
}
|
||||
|
||||
return YieldFor(wxEVT_CATEGORY_ALL);
|
||||
}
|
||||
@@ -124,10 +117,14 @@ bool wxEventLoopBase::YieldFor(long eventsToProcess)
|
||||
#endif // wxUSE_THREADS
|
||||
|
||||
// set the flag and don't forget to reset it before returning
|
||||
m_isInsideYield = true;
|
||||
m_eventsToProcessInsideYield = eventsToProcess;
|
||||
const int yieldLevelOld = m_yieldLevel;
|
||||
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
|
||||
// disable log flushing from here because a call to wxYield() shouldn't
|
||||
|
Reference in New Issue
Block a user