]> git.saurik.com Git - wxWidgets.git/commitdiff
Make wxEventLoop::AddSourceForFD() static.
authorVadim Zeitlin <vadim@wxwidgets.org>
Wed, 3 Jul 2013 00:28:42 +0000 (00:28 +0000)
committerVadim Zeitlin <vadim@wxwidgets.org>
Wed, 3 Jul 2013 00:28:42 +0000 (00:28 +0000)
Any event sources should be registered with all the event loops, including the
ones that will be started in the future, and not only the current (and
potentially not even existing yet) one. So make AddSourceForFD() method static.

To still allow it to do different things in console and GUI applications, as
it must, virtualize it via the new wxEventLoopSourcesManager class which has
different implementations in the two cases, returned via wxAppTraits as usual.

Notice that this required moving the implementation of this method from
src/osx/core/evtloop_cf.cpp to src/osx/core/utilsexc_cf.cpp as the former file
is base-only and didn't have access to wxGUIAppTraits.

See #10258.

git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@74341 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775

13 files changed:
include/wx/evtloop.h
include/wx/gtk/evtloop.h
include/wx/osx/core/evtloop.h
include/wx/osx/evtloopsrc.h
include/wx/private/eventloopsourcesmanager.h [new file with mode: 0644]
include/wx/unix/apptbase.h
include/wx/unix/apptrait.h
include/wx/unix/evtloop.h
src/common/evtloopcmn.cpp
src/gtk/evtloop.cpp
src/osx/core/evtloop_cf.cpp
src/osx/core/utilsexc_cf.cpp
src/unix/evtloopunix.cpp

index 2abbd9cef49ec63cf1aa1e7765bc2df52d9d3ef8..a9034aeac8a03744c35bd82de5d53b72838c2c15 100644 (file)
@@ -79,9 +79,9 @@ public:
 
 #if wxUSE_EVENTLOOP_SOURCE
     // create a new event loop source wrapping the given file descriptor and
-    // start monitoring it
-    virtual wxEventLoopSource *
-      AddSourceForFD(int fd, wxEventLoopSourceHandler *handler, int flags) = 0;
+    // monitor it for events occurring on this descriptor in all event loops
+    static wxEventLoopSource *
+      AddSourceForFD(int fd, wxEventLoopSourceHandler *handler, int flags);
 #endif // wxUSE_EVENTLOOP_SOURCE
 
     // dispatch&processing
@@ -296,19 +296,6 @@ public:
     wxGUIEventLoop() { m_impl = NULL; }
     virtual ~wxGUIEventLoop();
 
-#if wxUSE_EVENTLOOP_SOURCE
-    // We need to define a base class pure virtual method but we can't provide
-    // a generic implementation for it so simply fail.
-    virtual wxEventLoopSource *
-    AddSourceForFD(int WXUNUSED(fd),
-                   wxEventLoopSourceHandler * WXUNUSED(handler),
-                   int WXUNUSED(flags))
-    {
-        wxFAIL_MSG( "support for event loop sources not implemented" );
-        return NULL;
-    }
-#endif // wxUSE_EVENTLOOP_SOURCE
-
     virtual void ScheduleExit(int rc = 0);
     virtual bool Pending() const;
     virtual bool Dispatch();
index af4d00348df8d089216360d144d3a052610b0dde..9fb55aa226c3522414d070331eebf42aba4473f2 100644 (file)
@@ -29,11 +29,6 @@ public:
     virtual void WakeUp();
     virtual bool YieldFor(long eventsToProcess);
 
-#if wxUSE_EVENTLOOP_SOURCE
-    virtual wxEventLoopSource *
-      AddSourceForFD(int fd, wxEventLoopSourceHandler *handler, int flags);
-#endif // wxUSE_EVENTLOOP_SOURCE
-
     void StoreGdkEventForLaterProcessing(GdkEvent* ev)
         { m_arrGdkEvents.Add(ev); }
 
index 862a4d9d54689c07c77fad35e751fbafd177301c..5bc53b0c16cd67a74019966d666de856f32ef980 100644 (file)
@@ -45,11 +45,6 @@ public:
 
     virtual bool YieldFor(long eventsToProcess);
 
-#if wxUSE_EVENTLOOP_SOURCE
-    virtual wxEventLoopSource *
-      AddSourceForFD(int fd, wxEventLoopSourceHandler *handler, int flags);
-#endif // wxUSE_EVENTLOOP_SOURCE
-
     bool ShouldProcessIdleEvents() const { return m_processIdleEvents ; }
     
 #if wxUSE_UIACTIONSIMULATOR
index 3c18bba764624caba84e2261dd1a3a8ce4bddb66..646190eb7277586cd6de174d820dd1492b449077 100644 (file)
@@ -17,7 +17,7 @@ typedef struct __CFFileDescriptor *CFFileDescriptorRef;
 // wxCFEventLoopSource: CoreFoundation-based wxEventLoopSource for OS X
 // ----------------------------------------------------------------------------
 
-class wxCFEventLoopSource : public wxEventLoopSource
+class WXDLLIMPEXP_BASE wxCFEventLoopSource : public wxEventLoopSource
 {
 public:
     wxCFEventLoopSource(wxEventLoopSourceHandler *handler, int flags)
diff --git a/include/wx/private/eventloopsourcesmanager.h b/include/wx/private/eventloopsourcesmanager.h
new file mode 100644 (file)
index 0000000..82aadf5
--- /dev/null
@@ -0,0 +1,26 @@
+///////////////////////////////////////////////////////////////////////////////
+// Name:        wx/private/eventloopsourcesmanager.h
+// Purpose:     declares wxEventLoopSourcesManagerBase class
+// Author:      Rob Bresalier
+// Created:     2013-06-19
+// RCS-ID:      $Id$
+// Copyright:   (c) 2013 Rob Bresalier
+// Licence:     wxWindows licence
+///////////////////////////////////////////////////////////////////////////////
+
+#ifndef _WX_PRIVATE_EVENTLOOPSOURCESMANAGER_H_
+#define _WX_PRIVATE_EVENTLOOPSOURCESMANAGER_H_
+
+// For pulling in the value of wxUSE_EVENTLOOP_SOURCE
+#include "wx/evtloop.h"
+
+class WXDLLIMPEXP_BASE wxEventLoopSourcesManagerBase
+{
+public:
+#if wxUSE_EVENTLOOP_SOURCE
+    virtual wxEventLoopSource*
+    AddSourceForFD(int fd, wxEventLoopSourceHandler *handler, int flags) = 0;
+#endif
+};
+
+#endif // _WX_PRIVATE_EVENTLOOPSOURCESMANAGER_H_
index 8bf6b4cb97efe82b83880420ab01a666581ad5c6..fd624aeed4f10624eb69fb61d177a472b8e063d3 100644 (file)
@@ -15,6 +15,7 @@
 struct wxEndProcessData;
 struct wxExecuteData;
 class wxFDIOManager;
+class wxEventLoopSourcesManagerBase;
 
 // ----------------------------------------------------------------------------
 // wxAppTraits: the Unix version adds extra hooks needed by Unix code
@@ -56,6 +57,10 @@ public:
     virtual wxFDIOManager *GetFDIOManager();
 #endif // wxUSE_SOCKETS
 
+    // Return a non-NULL pointer to the object responsible for managing the
+    // event loop sources in this kind of application.
+    virtual wxEventLoopSourcesManagerBase* GetEventLoopSourcesManager();
+
 protected:
     // a helper for the implementation of WaitForChild() in wxGUIAppTraits:
     // checks the streams used for redirected IO in execData and returns true
index 04109204e9eeef9ae6df8c1db3262de439a9a955..5f56733d2896e8a61590a56d0086f6a36bae1bd5 100644 (file)
@@ -88,6 +88,8 @@ public:
 #endif
 
 #endif // wxUSE_SOCKETS
+
+    virtual wxEventLoopSourcesManagerBase* GetEventLoopSourcesManager();
 };
 
 #endif // wxUSE_GUI
index 5f1cf59ea1b6a3a8b19f4bf2f493b73b1b557590..0b717660683f43e3c21f64dc34086f9818559cac 100644 (file)
@@ -41,11 +41,6 @@ public:
     virtual bool IsOk() const { return m_dispatcher != NULL; }
     virtual bool YieldFor(long WXUNUSED(eventsToProcess)) { return true; }
 
-#if wxUSE_EVENTLOOP_SOURCE
-    virtual wxEventLoopSource *
-      AddSourceForFD(int fd, wxEventLoopSourceHandler *handler, int flags);
-#endif // wxUSE_EVENTLOOP_SOURCE
-
 protected:
     virtual void OnNextIteration();
 
index da0b79fba477db3a2d3e24443bb7a7fd0ad3e74a..8564f525171cc0cd100476676ed11d260c622ac7 100644 (file)
@@ -23,6 +23,8 @@
 #endif //WX_PRECOMP
 
 #include "wx/scopeguard.h"
+#include "wx/apptrait.h"
+#include "wx/private/eventloopsourcesmanager.h"
 
 // ----------------------------------------------------------------------------
 // wxEventLoopBase
@@ -115,6 +117,29 @@ bool wxEventLoopBase::Yield(bool onlyIfNeeded)
     return YieldFor(wxEVT_CATEGORY_ALL);
 }
 
+#if wxUSE_EVENTLOOP_SOURCE
+
+wxEventLoopSource*
+wxEventLoopBase::AddSourceForFD(int fd,
+                                wxEventLoopSourceHandler *handler,
+                                int flags)
+{
+    // Ensure that we have some valid traits.
+    wxConsoleAppTraits traitsConsole;
+    wxAppTraits *traits = wxTheApp ? wxTheApp->GetTraits() : NULL;
+    if ( !traits )
+        traits = &traitsConsole;
+
+    // And delegate to the event loop sources manager defined by it.
+    wxEventLoopSourcesManagerBase* const
+        manager = traits->GetEventLoopSourcesManager();
+    wxCHECK_MSG( manager, NULL, wxS("Must have wxEventLoopSourcesManager") );
+
+    return manager->AddSourceForFD(fd, handler, flags);
+}
+
+#endif // wxUSE_EVENTLOOP_SOURCE
+
 // wxEventLoopManual is unused in the other ports
 #if defined(__WINDOWS__) || defined(__WXDFB__) || ( ( defined(__UNIX__) && !defined(__WXOSX__) ) && wxUSE_BASE)
 
index d104d82f0c7c09935b9901ef1d25a620f85e2998..ea5b43b9d178993879a9c24d0c4cd1a778f2d6b7 100644 (file)
@@ -32,6 +32,9 @@
     #include "wx/log.h"
 #endif // WX_PRECOMP
 
+#include "wx/private/eventloopsourcesmanager.h"
+#include "wx/apptrait.h"
+
 #include <gtk/gtk.h>
 #include <glib.h>
 
@@ -133,41 +136,50 @@ static gboolean wx_on_channel_event(GIOChannel *channel,
 }
 }
 
-wxEventLoopSource *
-wxGUIEventLoop::AddSourceForFD(int fd,
-                               wxEventLoopSourceHandler *handler,
-                               int flags)
+class wxGUIEventLoopSourcesManager : public wxEventLoopSourcesManagerBase
 {
-    wxCHECK_MSG( fd != -1, NULL, "can't monitor invalid fd" );
-
-    int condition = 0;
-    if (flags & wxEVENT_SOURCE_INPUT)
-        condition |= G_IO_IN | G_IO_PRI;
-    if (flags & wxEVENT_SOURCE_OUTPUT)
-        condition |= G_IO_OUT;
-    if (flags & wxEVENT_SOURCE_EXCEPTION)
-        condition |= G_IO_ERR | G_IO_HUP | G_IO_NVAL;
-
-    GIOChannel* channel = g_io_channel_unix_new(fd);
-    const unsigned sourceId  = g_io_add_watch
-                               (
-                                channel,
-                                (GIOCondition)condition,
-                                &wx_on_channel_event,
-                                handler
-                               );
-    // it was ref'd by g_io_add_watch() so we can unref it here
-    g_io_channel_unref(channel);
-
-    if ( !sourceId )
-        return NULL;
-
-    wxLogTrace(wxTRACE_EVT_SOURCE,
-               "Adding event loop source for fd=%d with GTK id=%u",
-               fd, sourceId);
+public:
+    virtual wxEventLoopSource*
+    AddSourceForFD(int fd, wxEventLoopSourceHandler *handler, int flags)
+    {
+        wxCHECK_MSG( fd != -1, NULL, "can't monitor invalid fd" );
+
+        int condition = 0;
+        if ( flags & wxEVENT_SOURCE_INPUT )
+            condition |= G_IO_IN | G_IO_PRI | G_IO_HUP;
+        if ( flags & wxEVENT_SOURCE_OUTPUT )
+            condition |= G_IO_OUT;
+        if ( flags & wxEVENT_SOURCE_EXCEPTION )
+            condition |= G_IO_ERR | G_IO_NVAL;
+
+        GIOChannel* channel = g_io_channel_unix_new(fd);
+        const unsigned sourceId  = g_io_add_watch
+                                   (
+                                    channel,
+                                    (GIOCondition)condition,
+                                    &wx_on_channel_event,
+                                    handler
+                                   );
+        // it was ref'd by g_io_add_watch() so we can unref it here
+        g_io_channel_unref(channel);
+
+        if ( !sourceId )
+            return NULL;
+
+        wxLogTrace(wxTRACE_EVT_SOURCE,
+                   "Adding event loop source for fd=%d with GTK id=%u",
+                   fd, sourceId);
+
+
+        return new wxGTKEventLoopSource(sourceId, handler, flags);
+    }
+};
 
+wxEventLoopSourcesManagerBase* wxGUIAppTraits::GetEventLoopSourcesManager()
+{
+    static wxGUIEventLoopSourcesManager s_eventLoopSourcesManager;
 
-    return new wxGTKEventLoopSource(sourceId, handler, flags);
+    return &s_eventLoopSourcesManager;
 }
 
 wxGTKEventLoopSource::~wxGTKEventLoopSource()
index 12ecb2c87292d3e0945739a81bfc141a23a63266..704a8334134328e52694ad5caef368b2eb417440 100644 (file)
 
 #if wxUSE_EVENTLOOP_SOURCE
 
-namespace
-{
-
-void EnableDescriptorCallBacks(CFFileDescriptorRef cffd, int flags)
-{
-    if ( flags & wxEVENT_SOURCE_INPUT )
-        CFFileDescriptorEnableCallBacks(cffd, kCFFileDescriptorReadCallBack);
-    if ( flags & wxEVENT_SOURCE_OUTPUT )
-        CFFileDescriptorEnableCallBacks(cffd, kCFFileDescriptorWriteCallBack);
-}
-
-void
-wx_cffiledescriptor_callback(CFFileDescriptorRef cffd,
-                             CFOptionFlags flags,
-                             void *ctxData)
-{
-    wxLogTrace(wxTRACE_EVT_SOURCE,
-               "CFFileDescriptor callback, flags=%d", flags);
-
-    wxCFEventLoopSource * const
-        source = static_cast<wxCFEventLoopSource *>(ctxData);
-
-    wxEventLoopSourceHandler * const
-        handler = source->GetHandler();
-    if ( flags & kCFFileDescriptorReadCallBack )
-        handler->OnReadWaiting();
-    if ( flags & kCFFileDescriptorWriteCallBack )
-        handler->OnWriteWaiting();
-
-    // we need to re-enable callbacks to be called again
-    EnableDescriptorCallBacks(cffd, source->GetFlags());
-}
-
-} // anonymous namespace
-
-wxEventLoopSource *
-wxCFEventLoop::AddSourceForFD(int fd,
-                              wxEventLoopSourceHandler *handler,
-                              int flags)
-{
-    wxCHECK_MSG( fd != -1, NULL, "can't monitor invalid fd" );
-
-    wxScopedPtr<wxCFEventLoopSource>
-        source(new wxCFEventLoopSource(handler, flags));
-
-    CFFileDescriptorContext ctx = { 0, source.get(), NULL, NULL, NULL };
-    wxCFRef<CFFileDescriptorRef>
-        cffd(CFFileDescriptorCreate
-             (
-                  kCFAllocatorDefault,
-                  fd,
-                  true,   // close on invalidate
-                  wx_cffiledescriptor_callback,
-                  &ctx
-             ));
-    if ( !cffd )
-        return NULL;
-
-    wxCFRef<CFRunLoopSourceRef>
-        cfsrc(CFFileDescriptorCreateRunLoopSource(kCFAllocatorDefault, cffd, 0));
-    if ( !cfsrc )
-        return NULL;
-
-    CFRunLoopRef cfloop = CFGetCurrentRunLoop();
-    CFRunLoopAddSource(cfloop, cfsrc, kCFRunLoopDefaultMode);
-
-    // Enable the callbacks initially.
-    EnableDescriptorCallBacks(cffd, source->GetFlags());
-
-    source->SetFileDescriptor(cffd.release());
-
-    return source.release();
-}
-
 void wxCFEventLoopSource::SetFileDescriptor(CFFileDescriptorRef cffd)
 {
     wxASSERT_MSG( !m_cffd, "shouldn't be called more than once" );
index fe010f63be2a976febe7f5b9cfd57e81b678fabc..221bbb322d5f399f3ac29b5df7a19157362728b6 100644 (file)
 #include "wx/thread.h"
 #include "wx/process.h"
 
+#include "wx/evtloop.h"
+#include "wx/evtloopsrc.h"
+#include "wx/private/eventloopsourcesmanager.h"
+
 #include <sys/wait.h>
 
+#include <CoreFoundation/CFFileDescriptor.h>
 #include <CoreFoundation/CFSocket.h>
 
 /*!
@@ -104,6 +109,93 @@ int wxGUIAppTraits::AddProcessCallback(wxEndProcessData *proc_data, int fd)
     return ++s_last_tag;
 }
 
+#if wxUSE_EVENTLOOP_SOURCE
+
+namespace
+{
+
+void EnableDescriptorCallBacks(CFFileDescriptorRef cffd, int flags)
+{
+    if ( flags & wxEVENT_SOURCE_INPUT )
+        CFFileDescriptorEnableCallBacks(cffd, kCFFileDescriptorReadCallBack);
+    if ( flags & wxEVENT_SOURCE_OUTPUT )
+        CFFileDescriptorEnableCallBacks(cffd, kCFFileDescriptorWriteCallBack);
+}
+
+void
+wx_cffiledescriptor_callback(CFFileDescriptorRef cffd,
+                             CFOptionFlags flags,
+                             void *ctxData)
+{
+    wxLogTrace(wxTRACE_EVT_SOURCE,
+               "CFFileDescriptor callback, flags=%d", flags);
+
+    wxCFEventLoopSource * const
+        source = static_cast<wxCFEventLoopSource *>(ctxData);
+
+    wxEventLoopSourceHandler * const
+        handler = source->GetHandler();
+    if ( flags & kCFFileDescriptorReadCallBack )
+        handler->OnReadWaiting();
+    if ( flags & kCFFileDescriptorWriteCallBack )
+        handler->OnWriteWaiting();
+
+    // we need to re-enable callbacks to be called again
+    EnableDescriptorCallBacks(cffd, source->GetFlags());
+}
+
+} // anonymous namespace
+
+class wxCFEventLoopSourcesManager : public wxEventLoopSourcesManagerBase
+{
+public:
+    wxEventLoopSource *
+    AddSourceForFD(int fd, wxEventLoopSourceHandler *handler, int flags)
+    {
+        wxCHECK_MSG( fd != -1, NULL, "can't monitor invalid fd" );
+
+        wxScopedPtr<wxCFEventLoopSource>
+            source(new wxCFEventLoopSource(handler, flags));
+
+        CFFileDescriptorContext ctx = { 0, source.get(), NULL, NULL, NULL };
+        wxCFRef<CFFileDescriptorRef>
+            cffd(CFFileDescriptorCreate
+                 (
+                      kCFAllocatorDefault,
+                      fd,
+                      true,   // close on invalidate
+                      wx_cffiledescriptor_callback,
+                      &ctx
+                 ));
+        if ( !cffd )
+            return NULL;
+
+        wxCFRef<CFRunLoopSourceRef>
+            cfsrc(CFFileDescriptorCreateRunLoopSource(kCFAllocatorDefault, cffd, 0));
+        if ( !cfsrc )
+            return NULL;
+
+        CFRunLoopRef cfloop = CFRunLoopGetCurrent();
+        CFRunLoopAddSource(cfloop, cfsrc, kCFRunLoopDefaultMode);
+
+        // Enable the callbacks initially.
+        EnableDescriptorCallBacks(cffd, source->GetFlags());
+
+        source->SetFileDescriptor(cffd.release());
+
+        return source.release();
+    }
+};
+
+wxEventLoopSourcesManagerBase* wxGUIAppTraits::GetEventLoopSourcesManager()
+{
+    static wxCFEventLoopSourcesManager s_eventLoopSourcesManager;
+
+    return &s_eventLoopSourcesManager;
+}
+
+#endif // wxUSE_EVENTLOOP_SOURCE
+
 /////////////////////////////////////////////////////////////////////////////
 
 // NOTE: This doesn't really belong here but this was a handy file to
index 784241c6631f468be6f845b29c573c66414f38da..763b73ef73b38480d177314e3b205261c983b82a 100644 (file)
@@ -36,7 +36,9 @@
 #include "wx/unix/private/epolldispatcher.h"
 #include "wx/unix/private/wakeuppipe.h"
 #include "wx/private/selectdispatcher.h"
+#include "wx/private/eventloopsourcesmanager.h"
 #include "wx/private/fdioeventloopsourcehandler.h"
+#include "wx/private/eventloopsourcesmanager.h"
 
 #if wxUSE_EVENTLOOP_SOURCE
     #include "wx/evtloopsrc.h"
@@ -87,27 +89,37 @@ wxConsoleEventLoop::~wxConsoleEventLoop()
 
 #if wxUSE_EVENTLOOP_SOURCE
 
-wxEventLoopSource *
-wxConsoleEventLoop::AddSourceForFD(int fd,
-                                   wxEventLoopSourceHandler *handler,
-                                   int flags)
+class wxConsoleEventLoopSourcesManager : public wxEventLoopSourcesManagerBase
 {
-    wxCHECK_MSG( fd != -1, NULL, "can't monitor invalid fd" );
+public:
+    wxEventLoopSource* AddSourceForFD( int fd,
+                                       wxEventLoopSourceHandler *handler,
+                                       int flags)
+    {
+        wxCHECK_MSG( fd != -1, NULL, "can't monitor invalid fd" );
 
-    wxLogTrace(wxTRACE_EVT_SOURCE,
-                "Adding event loop source for fd=%d", fd);
+        wxLogTrace(wxTRACE_EVT_SOURCE,
+                    "Adding event loop source for fd=%d", fd);
+
+        // we need a bridge to wxFDIODispatcher
+        //
+        // TODO: refactor the code so that only wxEventLoopSourceHandler is used
+        wxScopedPtr<wxFDIOHandler>
+            fdioHandler(new wxFDIOEventLoopSourceHandler(handler));
 
-    // we need a bridge to wxFDIODispatcher
-    //
-    // TODO: refactor the code so that only wxEventLoopSourceHandler is used
-    wxScopedPtr<wxFDIOHandler>
-        fdioHandler(new wxFDIOEventLoopSourceHandler(handler));
+        if ( !wxFDIODispatcher::Get()->RegisterFD(fd, fdioHandler.get(), flags) )
+            return NULL;
 
-    if ( !m_dispatcher->RegisterFD(fd, fdioHandler.get(), flags) )
-        return NULL;
+        return new wxUnixEventLoopSource(wxFDIODispatcher::Get(), fdioHandler.release(),
+                                         fd, handler, flags);
+    }
+};
+
+wxEventLoopSourcesManagerBase* wxAppTraits::GetEventLoopSourcesManager()
+{
+    static wxConsoleEventLoopSourcesManager s_eventLoopSourcesManager;
 
-    return new wxUnixEventLoopSource(m_dispatcher, fdioHandler.release(),
-                                     fd, handler, flags);
+    return &s_eventLoopSourcesManager;
 }
 
 wxUnixEventLoopSource::~wxUnixEventLoopSource()