X-Git-Url: https://git.saurik.com/wxWidgets.git/blobdiff_plain/dde19c2180ef8d6415af7bb2492bfcb0a2d5c7e4..fdb45ab7e968e56c2008565bb89b48818422b280:/src/common/appbase.cpp diff --git a/src/common/appbase.cpp b/src/common/appbase.cpp index 8a774ae6a0..a78e93d1d4 100644 --- a/src/common/appbase.cpp +++ b/src/common/appbase.cpp @@ -153,7 +153,7 @@ wxAppConsoleBase::~wxAppConsoleBase() } // ---------------------------------------------------------------------------- -// initilization/cleanup +// initialization/cleanup // ---------------------------------------------------------------------------- bool wxAppConsoleBase::Initialize(int& WXUNUSED(argc), wxChar **argv) @@ -313,34 +313,6 @@ bool wxAppConsoleBase::Dispatch() return loop && loop->Dispatch(); } -bool wxAppConsoleBase::HasPendingEvents() const -{ - wxEventLoopBase * const loop = wxEventLoopBase::GetActive(); - - return loop && loop->HasPendingEvents(); -} - -void wxAppConsoleBase::SuspendProcessingOfPendingEvents() -{ - wxEventLoopBase * const loop = wxEventLoopBase::GetActive(); - - if (loop) loop->SuspendProcessingOfPendingEvents(); -} - -void wxAppConsoleBase::ResumeProcessingOfPendingEvents() -{ - wxEventLoopBase * const loop = wxEventLoopBase::GetActive(); - - if (loop) loop->ResumeProcessingOfPendingEvents(); -} - -void wxAppConsoleBase::ProcessPendingEvents() -{ - wxEventLoopBase * const loop = wxEventLoopBase::GetActive(); - - if (loop) loop->ProcessPendingEvents(); -} - bool wxAppConsoleBase::Yield(bool onlyIfNeeded) { wxEventLoopBase * const loop = wxEventLoopBase::GetActive(); @@ -379,6 +351,117 @@ int wxAppConsoleBase::FilterEvent(wxEvent& WXUNUSED(event)) return -1; } +void wxAppConsoleBase::DelayPendingEventHandler(wxEvtHandler* toDelay) +{ + wxENTER_CRIT_SECT(m_handlersWithPendingEventsLocker); + + // move the handler from the list of handlers with processable pending events + // to the list of handlers with pending events which needs to be processed later + m_handlersWithPendingEvents.Remove(toDelay); + + if (m_handlersWithPendingDelayedEvents.Index(toDelay) == wxNOT_FOUND) + m_handlersWithPendingDelayedEvents.Add(toDelay); + + wxLEAVE_CRIT_SECT(m_handlersWithPendingEventsLocker); +} + +void wxAppConsoleBase::RemovePendingEventHandler(wxEvtHandler* toRemove) +{ + wxENTER_CRIT_SECT(m_handlersWithPendingEventsLocker); + + if (m_handlersWithPendingEvents.Index(toRemove) != wxNOT_FOUND) + { + m_handlersWithPendingEvents.Remove(toRemove); + + // check that the handler was present only once in the list + wxASSERT_MSG( m_handlersWithPendingEvents.Index(toRemove) == wxNOT_FOUND, + "Handler occurs twice in the m_handlersWithPendingEvents list!" ); + } + //else: it wasn't in this list at all, it's ok + + if (m_handlersWithPendingDelayedEvents.Index(toRemove) != wxNOT_FOUND) + { + m_handlersWithPendingDelayedEvents.Remove(toRemove); + + // check that the handler was present only once in the list + wxASSERT_MSG( m_handlersWithPendingDelayedEvents.Index(toRemove) == wxNOT_FOUND, + "Handler occurs twice in m_handlersWithPendingDelayedEvents list!" ); + } + //else: it wasn't in this list at all, it's ok + + wxLEAVE_CRIT_SECT(m_handlersWithPendingEventsLocker); +} + +void wxAppConsoleBase::AppendPendingEventHandler(wxEvtHandler* toAppend) +{ + wxENTER_CRIT_SECT(m_handlersWithPendingEventsLocker); + + if ( m_handlersWithPendingEvents.Index(toAppend) == wxNOT_FOUND ) + m_handlersWithPendingEvents.Add(toAppend); + + wxLEAVE_CRIT_SECT(m_handlersWithPendingEventsLocker); +} + +bool wxAppConsoleBase::HasPendingEvents() const +{ + wxENTER_CRIT_SECT(const_cast(this)->m_handlersWithPendingEventsLocker); + + bool has = !m_handlersWithPendingEvents.IsEmpty(); + + wxLEAVE_CRIT_SECT(const_cast(this)->m_handlersWithPendingEventsLocker); + + return has; +} + +void wxAppConsoleBase::SuspendProcessingOfPendingEvents() +{ + wxENTER_CRIT_SECT(m_handlersWithPendingEventsLocker); + // entering the critical section locks blocks calls to ProcessPendingEvents() +} + +void wxAppConsoleBase::ResumeProcessingOfPendingEvents() +{ + wxLEAVE_CRIT_SECT(m_handlersWithPendingEventsLocker); +} + +void wxAppConsoleBase::ProcessPendingEvents() +{ + wxENTER_CRIT_SECT(m_handlersWithPendingEventsLocker); + + wxCHECK_RET( m_handlersWithPendingDelayedEvents.IsEmpty(), + "this helper list should be empty" ); + + // iterate until the list becomes empty: the handlers remove themselves + // from it when they don't have any more pending events + while (!m_handlersWithPendingEvents.IsEmpty()) + { + // In ProcessPendingEvents(), new handlers might be added + // and we can safely leave the critical section here. + wxLEAVE_CRIT_SECT(m_handlersWithPendingEventsLocker); + + // NOTE: we always call ProcessPendingEvents() on the first event handler + // with pending events because handlers auto-remove themselves + // from this list (see RemovePendingEventHandler) if they have no + // more pending events. + m_handlersWithPendingEvents[0]->ProcessPendingEvents(); + + wxENTER_CRIT_SECT(m_handlersWithPendingEventsLocker); + } + + // now the wxHandlersWithPendingEvents is surely empty; however some event + // handlers may have moved themselves into wxHandlersWithPendingDelayedEvents + // because of a selective wxYield call in progress. + // Now we need to move them back to wxHandlersWithPendingEvents so the next + // call to this function has the chance of processing them: + if (!m_handlersWithPendingDelayedEvents.IsEmpty()) + { + WX_APPEND_ARRAY(m_handlersWithPendingEvents, m_handlersWithPendingDelayedEvents); + m_handlersWithPendingDelayedEvents.Clear(); + } + + wxLEAVE_CRIT_SECT(m_handlersWithPendingEventsLocker); +} + // ---------------------------------------------------------------------------- // exception handling // ----------------------------------------------------------------------------