X-Git-Url: https://git.saurik.com/wxWidgets.git/blobdiff_plain/a7d980f639a5051b62bacc17ef5bfb84986a7f58..9a6aafe0039fef580ca1bfcf0e87c1ba8e2953ba:/src/common/appbase.cpp diff --git a/src/common/appbase.cpp b/src/common/appbase.cpp index 1efd57addd..d159c9bdd8 100644 --- a/src/common/appbase.cpp +++ b/src/common/appbase.cpp @@ -42,7 +42,7 @@ #include "wx/evtloop.h" #include "wx/filename.h" #include "wx/msgout.h" -#include "wx/ptr_scpd.h" +#include "wx/scopedptr.h" #include "wx/tokenzr.h" #include "wx/thread.h" @@ -63,19 +63,6 @@ #include "wx/fontmap.h" #endif // wxUSE_FONTMAP -#if defined(__DARWIN__) && defined(_MSL_USING_MW_C_HEADERS) && _MSL_USING_MW_C_HEADERS - // For MacTypes.h for Debugger function - #include -#endif - -#if defined(__WXMAC__) - #ifdef __DARWIN__ - #include - #else - #include "wx/mac/private.h" // includes mac headers - #endif -#endif // __WXMAC__ - #ifdef __WXDEBUG__ #if wxUSE_STACKWALKER #include "wx/stackwalk.h" @@ -124,6 +111,8 @@ wxAppConsole *wxAppConsoleBase::ms_appInstance = NULL; wxAppInitializerFunction wxAppConsoleBase::ms_appInitFn = NULL; +wxSocketManager *wxAppTraitsBase::ms_manager = NULL; + // ---------------------------------------------------------------------------- // wxEventLoopPtr // ---------------------------------------------------------------------------- @@ -144,7 +133,7 @@ wxAppConsoleBase::wxAppConsoleBase() m_traits = NULL; m_mainLoop = NULL; - ms_appInstance = wx_static_cast(wxAppConsole *, this); + ms_appInstance = static_cast(this); #ifdef __WXDEBUG__ SetTraceMasks(); @@ -174,7 +163,8 @@ bool wxAppConsoleBase::Initialize(int& WXUNUSED(argc), wxChar **argv) #endif // wxUSE_INTL #if wxUSE_THREADS - wxPendingEventsLocker = new wxCriticalSection; + wxHandlersWithPendingEventsLocker = new wxCriticalSection; + wxHandlersWithPendingDelayedEvents = new wxList; #endif #ifndef __WXPALMOS__ @@ -201,12 +191,15 @@ void wxAppConsoleBase::CleanUp() m_mainLoop = NULL; } - delete wxPendingEvents; - wxPendingEvents = NULL; + delete wxHandlersWithPendingEvents; + wxHandlersWithPendingEvents = NULL; + + delete wxHandlersWithPendingDelayedEvents; + wxHandlersWithPendingDelayedEvents = NULL; #if wxUSE_THREADS - delete wxPendingEventsLocker; - wxPendingEventsLocker = NULL; + delete wxHandlersWithPendingEventsLocker; + wxHandlersWithPendingEventsLocker = NULL; #endif // wxUSE_THREADS } @@ -254,7 +247,7 @@ int wxAppConsoleBase::OnExit() #if wxUSE_CONFIG // delete the config object if any (don't use Get() here, but Set() // because Get() could create a new config object) - delete wxConfigBase::Set((wxConfigBase *) NULL); + delete wxConfigBase::Set(NULL); #endif // wxUSE_CONFIG return 0; @@ -290,6 +283,13 @@ wxAppTraits *wxAppConsoleBase::GetTraits() return m_traits; } +/* static */ +wxAppTraits *wxAppConsoleBase::GetTraitsIfExists() +{ + wxAppConsole * const app = GetInstance(); + return app ? app->GetTraits() : NULL; +} + // ---------------------------------------------------------------------------- // event processing // ---------------------------------------------------------------------------- @@ -331,15 +331,25 @@ bool wxAppConsoleBase::Dispatch() bool wxAppConsoleBase::HasPendingEvents() const { - wxENTER_CRIT_SECT( *wxPendingEventsLocker ); + wxENTER_CRIT_SECT( *wxHandlersWithPendingEventsLocker ); - bool has = wxPendingEvents && !wxPendingEvents->IsEmpty(); + bool has = wxHandlersWithPendingEvents && !wxHandlersWithPendingEvents->IsEmpty(); - wxLEAVE_CRIT_SECT( *wxPendingEventsLocker ); + wxLEAVE_CRIT_SECT( *wxHandlersWithPendingEventsLocker ); return has; } +void wxAppConsoleBase::SuspendProcessingOfPendingEvents() +{ + wxENTER_CRIT_SECT( *wxHandlersWithPendingEventsLocker ); +} + +void wxAppConsoleBase::ResumeProcessingOfPendingEvents() +{ + wxLEAVE_CRIT_SECT( *wxHandlersWithPendingEventsLocker ); +} + /* static */ bool wxAppConsoleBase::IsMainLoopRunning() { @@ -351,34 +361,51 @@ bool wxAppConsoleBase::IsMainLoopRunning() void wxAppConsoleBase::ProcessPendingEvents() { #if wxUSE_THREADS - if ( !wxPendingEventsLocker ) + if ( !wxHandlersWithPendingEventsLocker ) return; #endif - wxENTER_CRIT_SECT( *wxPendingEventsLocker ); + wxENTER_CRIT_SECT( *wxHandlersWithPendingEventsLocker ); - if (wxPendingEvents) + wxCHECK_RET( wxHandlersWithPendingDelayedEvents->IsEmpty(), + "this helper list should be empty" ); + + if (wxHandlersWithPendingEvents) { // iterate until the list becomes empty: the handlers remove themselves // from it when they don't have any more pending events - wxList::compatibility_iterator node = wxPendingEvents->GetFirst(); + wxList::compatibility_iterator node = wxHandlersWithPendingEvents->GetFirst(); while (node) { - // In ProcessPendingEvents(), new handlers might be add + // In ProcessPendingEvents(), new handlers might be added // and we can safely leave the critical section here. - wxLEAVE_CRIT_SECT( *wxPendingEventsLocker ); + wxLEAVE_CRIT_SECT( *wxHandlersWithPendingEventsLocker ); wxEvtHandler *handler = (wxEvtHandler *)node->GetData(); handler->ProcessPendingEvents(); - wxENTER_CRIT_SECT( *wxPendingEventsLocker ); + wxENTER_CRIT_SECT( *wxHandlersWithPendingEventsLocker ); // restart as the iterators could have been invalidated - node = wxPendingEvents->GetFirst(); + node = wxHandlersWithPendingEvents->GetFirst(); } } - wxLEAVE_CRIT_SECT( *wxPendingEventsLocker ); + // 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 (!wxHandlersWithPendingDelayedEvents->IsEmpty()) + { + if (!wxHandlersWithPendingEvents) + wxHandlersWithPendingEvents = new wxList; + + WX_APPEND_LIST(wxHandlersWithPendingEvents, wxHandlersWithPendingDelayedEvents); + wxHandlersWithPendingDelayedEvents->Clear(); + } + + wxLEAVE_CRIT_SECT( *wxHandlersWithPendingEventsLocker ); } void wxAppConsoleBase::WakeUpIdle() @@ -389,6 +416,9 @@ void wxAppConsoleBase::WakeUpIdle() bool wxAppConsoleBase::ProcessIdle() { + // process pending wx events before sending idle events + ProcessPendingEvents(); + wxIdleEvent event; event.SetEventObject(this); @@ -417,6 +447,20 @@ wxAppConsoleBase::HandleEvent(wxEvtHandler *handler, (handler->*func)(event); } +void wxAppConsoleBase::CallEventHandler(wxEvtHandler *handler, + wxEventFunctor& functor, + wxEvent& event) const +{ + // If the functor holds a method then, for backward compatibility, call + // HandleEvent(): + wxEventFunction eventFunction = functor.GetMethod(); + + if ( eventFunction ) + HandleEvent(handler, eventFunction, event); + else + functor(handler, event); +} + void wxAppConsoleBase::OnUnhandledException() { #ifdef __WXDEBUG__ @@ -673,12 +717,16 @@ void wxAppTraitsBase::MutexGuiLeave() void WXDLLIMPEXP_BASE wxMutexGuiEnter() { - wxAppConsoleBase::GetInstance()->GetTraits()->MutexGuiEnter(); + wxAppTraits * const traits = wxAppConsoleBase::GetTraitsIfExists(); + if ( traits ) + traits->MutexGuiEnter(); } void WXDLLIMPEXP_BASE wxMutexGuiLeave() { - wxAppConsoleBase::GetInstance()->GetTraits()->MutexGuiLeave(); + wxAppTraits * const traits = wxAppConsoleBase::GetTraitsIfExists(); + if ( traits ) + traits->MutexGuiLeave(); } #endif // wxUSE_THREADS