]> git.saurik.com Git - wxWidgets.git/blobdiff - src/common/appbase.cpp
extend wxXLocale with wxStrto[d,l,ul] functions; make wxXLocale::Init() a little...
[wxWidgets.git] / src / common / appbase.cpp
index d159c9bdd8eb71738a15fa4b43e776ff77318fa0..111ff3c7afac4a95e3057e26cf591199c1bf3871 100644 (file)
@@ -132,6 +132,7 @@ wxAppConsoleBase::wxAppConsoleBase()
 {
     m_traits = NULL;
     m_mainLoop = NULL;
+    m_bDoPendingEventProcessing = true;
 
     ms_appInstance = static_cast<wxAppConsole *>(this);
 
@@ -153,7 +154,7 @@ wxAppConsoleBase::~wxAppConsoleBase()
 }
 
 // ----------------------------------------------------------------------------
-// initilization/cleanup
+// initialization/cleanup
 // ----------------------------------------------------------------------------
 
 bool wxAppConsoleBase::Initialize(int& WXUNUSED(argc), wxChar **argv)
@@ -162,11 +163,6 @@ bool wxAppConsoleBase::Initialize(int& WXUNUSED(argc), wxChar **argv)
     GetTraits()->SetLocale();
 #endif // wxUSE_INTL
 
-#if wxUSE_THREADS
-    wxHandlersWithPendingEventsLocker = new wxCriticalSection;
-    wxHandlersWithPendingDelayedEvents = new wxList;
-#endif
-
 #ifndef __WXPALMOS__
     if ( m_appName.empty() && argv && argv[0] )
     {
@@ -190,17 +186,6 @@ void wxAppConsoleBase::CleanUp()
         delete m_mainLoop;
         m_mainLoop = NULL;
     }
-
-    delete wxHandlersWithPendingEvents;
-    wxHandlersWithPendingEvents = NULL;
-
-    delete wxHandlersWithPendingDelayedEvents;
-    wxHandlersWithPendingDelayedEvents = NULL;
-
-#if wxUSE_THREADS
-    delete wxHandlersWithPendingEventsLocker;
-    wxHandlersWithPendingEventsLocker = NULL;
-#endif // wxUSE_THREADS
 }
 
 // ----------------------------------------------------------------------------
@@ -291,7 +276,7 @@ wxAppTraits *wxAppConsoleBase::GetTraitsIfExists()
 }
 
 // ----------------------------------------------------------------------------
-// event processing
+// wxEventLoop redirection
 // ----------------------------------------------------------------------------
 
 int wxAppConsoleBase::MainLoop()
@@ -329,27 +314,30 @@ bool wxAppConsoleBase::Dispatch()
     return loop && loop->Dispatch();
 }
 
-bool wxAppConsoleBase::HasPendingEvents() const
+bool wxAppConsoleBase::Yield(bool onlyIfNeeded)
 {
-    wxENTER_CRIT_SECT( *wxHandlersWithPendingEventsLocker );
-
-    bool has = wxHandlersWithPendingEvents && !wxHandlersWithPendingEvents->IsEmpty();
-
-    wxLEAVE_CRIT_SECT( *wxHandlersWithPendingEventsLocker );
+    wxEventLoopBase * const loop = wxEventLoopBase::GetActive();
 
-    return has;
+    return loop && loop->Yield(onlyIfNeeded);
 }
 
-void wxAppConsoleBase::SuspendProcessingOfPendingEvents()
+void wxAppConsoleBase::WakeUpIdle()
 {
-    wxENTER_CRIT_SECT( *wxHandlersWithPendingEventsLocker );
+    if ( m_mainLoop )
+        m_mainLoop->WakeUp();
 }
 
-void wxAppConsoleBase::ResumeProcessingOfPendingEvents()
+bool wxAppConsoleBase::ProcessIdle()
 {
-    wxLEAVE_CRIT_SECT( *wxHandlersWithPendingEventsLocker );
+    wxEventLoopBase * const loop = wxEventLoopBase::GetActive();
+
+    return loop && loop->ProcessIdle();
 }
 
+// ----------------------------------------------------------------------------
+// events
+// ----------------------------------------------------------------------------
+
 /* static */
 bool wxAppConsoleBase::IsMainLoopRunning()
 {
@@ -358,37 +346,109 @@ bool wxAppConsoleBase::IsMainLoopRunning()
     return app && app->m_mainLoop != NULL;
 }
 
+int wxAppConsoleBase::FilterEvent(wxEvent& WXUNUSED(event))
+{
+    // process the events normally by default
+    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<wxAppConsoleBase*>(this)->m_handlersWithPendingEventsLocker);
+
+    bool has = !m_handlersWithPendingEvents.IsEmpty();
+
+    wxLEAVE_CRIT_SECT(const_cast<wxAppConsoleBase*>(this)->m_handlersWithPendingEventsLocker);
+
+    return has;
+}
+
+void wxAppConsoleBase::SuspendProcessingOfPendingEvents()
+{
+    m_bDoPendingEventProcessing = false;
+}
+
+void wxAppConsoleBase::ResumeProcessingOfPendingEvents()
+{
+    m_bDoPendingEventProcessing = true;
+}
+
 void wxAppConsoleBase::ProcessPendingEvents()
 {
-#if wxUSE_THREADS
-    if ( !wxHandlersWithPendingEventsLocker )
+    if (!m_bDoPendingEventProcessing)
         return;
-#endif
 
-    wxENTER_CRIT_SECT( *wxHandlersWithPendingEventsLocker );
+    wxENTER_CRIT_SECT(m_handlersWithPendingEventsLocker);
 
-    wxCHECK_RET( wxHandlersWithPendingDelayedEvents->IsEmpty(),
+    wxCHECK_RET( m_handlersWithPendingDelayedEvents.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
+    while (!m_handlersWithPendingEvents.IsEmpty())
     {
-        // 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 = wxHandlersWithPendingEvents->GetFirst();
-        while (node)
-        {
-            // In ProcessPendingEvents(), new handlers might be added
-            // and we can safely leave the critical section here.
-            wxLEAVE_CRIT_SECT( *wxHandlersWithPendingEventsLocker );
+        // In ProcessPendingEvents(), new handlers might be added
+        // and we can safely leave the critical section here.
+        wxLEAVE_CRIT_SECT(m_handlersWithPendingEventsLocker);
 
-            wxEvtHandler *handler = (wxEvtHandler *)node->GetData();
-            handler->ProcessPendingEvents();
+        // 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( *wxHandlersWithPendingEventsLocker );
-
-            // restart as the iterators could have been invalidated
-            node = wxHandlersWithPendingEvents->GetFirst();
-        }
+        wxENTER_CRIT_SECT(m_handlersWithPendingEventsLocker);
     }
 
     // now the wxHandlersWithPendingEvents is surely empty; however some event
@@ -396,40 +456,28 @@ void wxAppConsoleBase::ProcessPendingEvents()
     // 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 (!m_handlersWithPendingDelayedEvents.IsEmpty())
     {
-        if (!wxHandlersWithPendingEvents)
-            wxHandlersWithPendingEvents = new wxList;
-
-        WX_APPEND_LIST(wxHandlersWithPendingEvents, wxHandlersWithPendingDelayedEvents);
-        wxHandlersWithPendingDelayedEvents->Clear();
+        WX_APPEND_ARRAY(m_handlersWithPendingEvents, m_handlersWithPendingDelayedEvents);
+        m_handlersWithPendingDelayedEvents.Clear();
     }
 
-    wxLEAVE_CRIT_SECT( *wxHandlersWithPendingEventsLocker );
+    wxLEAVE_CRIT_SECT(m_handlersWithPendingEventsLocker);
 }
 
-void wxAppConsoleBase::WakeUpIdle()
+void wxAppConsoleBase::DeletePendingEvents()
 {
-    if ( m_mainLoop )
-        m_mainLoop->WakeUp();
-}
+    wxENTER_CRIT_SECT(m_handlersWithPendingEventsLocker);
 
-bool wxAppConsoleBase::ProcessIdle()
-{
-    // process pending wx events before sending idle events
-    ProcessPendingEvents();
+    wxCHECK_RET( m_handlersWithPendingDelayedEvents.IsEmpty(),
+                 "this helper list should be empty" );
 
-    wxIdleEvent event;
+    for (unsigned int i=0; i<m_handlersWithPendingEvents.GetCount(); i++)
+        m_handlersWithPendingEvents[i]->DeletePendingEvents();
 
-    event.SetEventObject(this);
-    ProcessEvent(event);
-    return event.MoreRequested();
-}
+    m_handlersWithPendingEvents.Clear();
 
-int wxAppConsoleBase::FilterEvent(wxEvent& WXUNUSED(event))
-{
-    // process the events normally by default
-    return -1;
+    wxLEAVE_CRIT_SECT(m_handlersWithPendingEventsLocker);
 }
 
 // ----------------------------------------------------------------------------
@@ -603,7 +651,6 @@ bool wxAppConsoleBase::CheckBuildOptions(const char *optionsSignature,
         // normally wxLogFatalError doesn't return
         return false;
     }
-#undef wxCMP
 
     return true;
 }