]> git.saurik.com Git - wxWidgets.git/commitdiff
* Added threads event propagation. Should compile on GTK (tested).
authorGuilhem Lavaux <lavaux@easynet.fr>
Sat, 27 Mar 1999 18:50:54 +0000 (18:50 +0000)
committerGuilhem Lavaux <lavaux@easynet.fr>
Sat, 27 Mar 1999 18:50:54 +0000 (18:50 +0000)
git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@1986 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775

14 files changed:
include/wx/event.h
include/wx/gtk/app.h
include/wx/gtk1/app.h
include/wx/motif/app.h
include/wx/msw/app.h
src/common/event.cpp
src/gtk/app.cpp
src/gtk/data.cpp
src/gtk1/app.cpp
src/gtk1/data.cpp
src/motif/app.cpp
src/motif/data.cpp
src/msw/app.cpp
src/msw/data.cpp

index 2ac0ea2fe04b646ae4533be5759cd07029b52a14..24a0d2b4f1a5ae1d78fbb6ddb0875866717d7113 100644 (file)
@@ -19,6 +19,9 @@
 #include "wx/defs.h"
 #include "wx/object.h"
 #include "wx/gdicmn.h"
+#if wxUSE_THREADS
+#include "wx/thread.h"
+#endif
 
 /*
  * Event types
@@ -347,7 +350,7 @@ public:
 
     // Set/Get listbox/choice selection string
     void SetString(const wxString& s) { m_commandString = s; }
-    const wxString& GetString() const { return m_commandString; }
+    wxString GetString() const { return m_commandString; }
 
     // Get checkbox value
     bool Checked() const { return (m_commandInt != 0); }
@@ -1170,6 +1173,10 @@ public:
     virtual bool OnClose();
 #endif
 
+#if wxUSE_THREADS
+    bool ProcessThreadEvent(wxEvent& event);
+    void ProcessPendingEvents();
+#endif
     virtual bool ProcessEvent(wxEvent& event);
     virtual bool SearchEventTable(wxEventTable& table, wxEvent& event);
 
@@ -1196,10 +1203,14 @@ protected:
     virtual const wxEventTable *GetEventTable() const;
 
 protected:
-    wxEvtHandler*     m_nextHandler;
-    wxEvtHandler*     m_previousHandler;
-    bool              m_enabled;           // Is event handler enabled?
-    wxList*           m_dynamicEvents;
+    wxEvtHandler*      m_nextHandler;
+    wxEvtHandler*      m_previousHandler;
+    bool               m_enabled;           // Is event handler enabled?
+    wxList*            m_dynamicEvents;
+    wxList*           m_pendingEvents;
+#if wxUSE_THREADS
+    wxCriticalSection* m_eventsLocker;
+#endif
 
     // optimization: instead of using costly IsKindOf() to decide whether we're
     // a window (which is true in 99% of cases), use this flag
index 365c08f90a29394176c0e1ab06acecded9fd3d87..ac36884cfe6c8302d6bbc9c4072b011d8fe7d5e3 100644 (file)
@@ -115,6 +115,9 @@ class wxApp: public wxEvtHandler
     static void CleanUp();
 
     bool ProcessIdle();
+#if wxUSE_THREADS
+    void ProcessPendingEvents();
+#endif
     void DeletePendingObjects();
 
     bool            m_initialized;
index 365c08f90a29394176c0e1ab06acecded9fd3d87..ac36884cfe6c8302d6bbc9c4072b011d8fe7d5e3 100644 (file)
@@ -115,6 +115,9 @@ class wxApp: public wxEvtHandler
     static void CleanUp();
 
     bool ProcessIdle();
+#if wxUSE_THREADS
+    void ProcessPendingEvents();
+#endif
     void DeletePendingObjects();
 
     bool            m_initialized;
index 5cbe5267fa9b515d15caaab63070456fc3e40228..2b24418913582f4604fcae6ad52e5b0b3cc14aa1 100644 (file)
@@ -141,6 +141,9 @@ public:
 
   void DeletePendingObjects();
   bool ProcessIdle();
+#if wxUSE_THREADS
+  void ProcessPendingEvents();
+#endif
 
   // Motif-specific
   inline WXAppContext   GetAppContext() const { return m_appContext; }
index f299a952ea6f0abc6da1c16d459b475f54d02be9..c5cbcfcd066a5747e5829d7fc4c045c4907a0f7f 100644 (file)
@@ -144,6 +144,9 @@ public:
   virtual bool ProcessMessage(WXMSG* pMsg);
   void DeletePendingObjects();
   bool ProcessIdle();
+#if wxUSE_THREADS
+  void ProcessPendingEvents();
+#endif
   int GetComCtl32Version() const;
 
 public:
index 713c0fdac6b0948d0bc557c97cc203f628c91af8..a1123fdf193887694192ec1095146411dc8ccc0e 100644 (file)
 
 #endif // !USE_SHARED_LIBRARY
 
+#if wxUSE_THREADS
+/* To put pending event handlers */
+extern wxList wxPendingEvents;
+extern wxCriticalSection wxPendingEventsLocker;
+#endif
+
 /*
  * General wxWindows events, covering
  * all interesting things that might happen (button clicking, resizing,
@@ -283,6 +289,10 @@ wxEvtHandler::wxEvtHandler()
     m_enabled = TRUE;
     m_dynamicEvents = (wxList *) NULL;
     m_isWindow = FALSE;
+#if wxUSE_THREADS
+    m_eventsLocker = new wxCriticalSection();
+#endif
+    m_pendingEvents = (wxList *) NULL;
 }
 
 wxEvtHandler::~wxEvtHandler()
@@ -306,8 +316,54 @@ wxEvtHandler::~wxEvtHandler()
         }
         delete m_dynamicEvents;
     };
+
+    if (m_pendingEvents)
+      delete m_pendingEvents;
+
+#if wxUSE_THREADS
+    delete m_eventsLocker;
+#endif
 }
 
+#if wxUSE_THREADS
+bool wxEvtHandler::ProcessThreadEvent(wxEvent& event)
+{
+    wxEvent *event_main;
+    wxCriticalSectionLocker locker(*m_eventsLocker);
+
+    // check that we are really in a child thread
+    wxASSERT( !wxThread::IsMain() );
+
+    if (m_pendingEvents == NULL)
+      m_pendingEvents = new wxList();
+
+    event_main = (wxEvent *)event.GetClassInfo()->CreateObject();
+    *event_main = event;
+
+    m_pendingEvents->Append(event_main);
+
+    wxPendingEventsLocker.Enter();
+    wxPendingEvents.Append(this);
+    wxPendingEventsLocker.Leave();
+
+    return TRUE;
+}
+
+void wxEvtHandler::ProcessPendingEvents()
+{
+    wxCriticalSectionLocker locker(*m_eventsLocker);
+    wxNode *node = m_pendingEvents->First();
+    wxEvent *event;
+
+    while (node != NULL) {
+      event = (wxEvent *)node->Data();
+      ProcessEvent(*event);
+      delete node;
+      node = m_pendingEvents->First();
+    }
+}
+#endif
+
 /*
  * Event table stuff
  */
@@ -320,6 +376,11 @@ bool wxEvtHandler::ProcessEvent(wxEvent& event)
     // An event handler can be enabled or disabled
     if ( GetEvtHandlerEnabled() )
     {
+#if wxUSE_THREADS
+       // Check whether we are in a child thread.
+        if (!wxThread::IsMain())
+          return ProcessThreadEvent(event);
+#endif
         // Handle per-instance dynamic event tables first
 
         if ( m_dynamicEvents && SearchDynamicEventTable(event) )
index afe49ce3c1552d12142a6abbfc9c7efffb2f421a..93459c373dd053f08384a0e8cb5d2e4e48f3b8a0 100644 (file)
@@ -46,6 +46,10 @@ wxApp *wxTheApp = (wxApp *)  NULL;
 wxAppInitializerFunction wxApp::m_appInitFn = (wxAppInitializerFunction) NULL;
 
 extern wxList wxPendingDelete;
+#if wxUSE_THREADS
+extern wxList wxPendingEvents;
+extern wxCriticalSection wxPendingEventsLocker;
+#endif
 extern wxResourceCache *wxTheResourceCache;
 
 unsigned char g_palette[64*3] =
@@ -283,6 +287,10 @@ void wxApp::OnIdle( wxIdleEvent &event )
 
     inOnIdle = TRUE;
 
+    /* Resend in the main thread events which have been prepared in other
+       threads */
+    ProcessPendingEvents();
+
     /* 'Garbage' collection of windows deleted with Close(). */
     DeletePendingObjects();
 
@@ -366,6 +374,25 @@ void wxApp::Dispatch()
 {
 }
 
+#if wxUSE_THREADS
+void wxApp::ProcessPendingEvents()
+{
+    wxNode *node = wxPendingEvents.First();
+    wxCriticalSectionLocker locker(wxPendingEventsLocker);
+
+    while (node)
+    {
+        wxEvtHandler *handler = (wxEvtHandler *)node->Data();
+
+        handler->ProcessPendingEvents();
+       
+        delete node;
+
+        node = wxPendingEvents.First();
+    }
+}
+#endif
+
 void wxApp::DeletePendingObjects()
 {
     wxNode *node = wxPendingDelete.First();
index 39b6114278adbf9bb23055133e919704121f5265..f8c868a24773503c618f2fea7efe10c92efdfdaf 100644 (file)
@@ -38,6 +38,12 @@ wxList wxTopLevelWindows;
 /* List of windows pending deletion */
 wxList wxPendingDelete;
 
+#if wxUSE_THREADS
+/* List of events pending processing */
+wxList wxPendingEvents;
+wxCriticalSection wxPendingEventsLocker;
+#endif
+
 /* Current cursor, in order to hang on to
  * cursor handle when setting the cursor globally */
 wxCursor *g_globalCursor = (wxCursor *) NULL;
index afe49ce3c1552d12142a6abbfc9c7efffb2f421a..93459c373dd053f08384a0e8cb5d2e4e48f3b8a0 100644 (file)
@@ -46,6 +46,10 @@ wxApp *wxTheApp = (wxApp *)  NULL;
 wxAppInitializerFunction wxApp::m_appInitFn = (wxAppInitializerFunction) NULL;
 
 extern wxList wxPendingDelete;
+#if wxUSE_THREADS
+extern wxList wxPendingEvents;
+extern wxCriticalSection wxPendingEventsLocker;
+#endif
 extern wxResourceCache *wxTheResourceCache;
 
 unsigned char g_palette[64*3] =
@@ -283,6 +287,10 @@ void wxApp::OnIdle( wxIdleEvent &event )
 
     inOnIdle = TRUE;
 
+    /* Resend in the main thread events which have been prepared in other
+       threads */
+    ProcessPendingEvents();
+
     /* 'Garbage' collection of windows deleted with Close(). */
     DeletePendingObjects();
 
@@ -366,6 +374,25 @@ void wxApp::Dispatch()
 {
 }
 
+#if wxUSE_THREADS
+void wxApp::ProcessPendingEvents()
+{
+    wxNode *node = wxPendingEvents.First();
+    wxCriticalSectionLocker locker(wxPendingEventsLocker);
+
+    while (node)
+    {
+        wxEvtHandler *handler = (wxEvtHandler *)node->Data();
+
+        handler->ProcessPendingEvents();
+       
+        delete node;
+
+        node = wxPendingEvents.First();
+    }
+}
+#endif
+
 void wxApp::DeletePendingObjects()
 {
     wxNode *node = wxPendingDelete.First();
index 39b6114278adbf9bb23055133e919704121f5265..f8c868a24773503c618f2fea7efe10c92efdfdaf 100644 (file)
@@ -38,6 +38,12 @@ wxList wxTopLevelWindows;
 /* List of windows pending deletion */
 wxList wxPendingDelete;
 
+#if wxUSE_THREADS
+/* List of events pending processing */
+wxList wxPendingEvents;
+wxCriticalSection wxPendingEventsLocker;
+#endif
+
 /* Current cursor, in order to hang on to
  * cursor handle when setting the cursor globally */
 wxCursor *g_globalCursor = (wxCursor *) NULL;
index ba8f0da0121f0f2e36e60a4c44a75db924c2f46f..65859d3f7b046ab1903f579bf5c7f2fe8475d42e 100644 (file)
 
 extern char *wxBuffer;
 extern wxList wxPendingDelete;
+#if wxUSE_THREADS
+extern wxList wxPendingEvents;
+extern wxList wxPendingEventsLocker;
+#endif
 
 wxApp *wxTheApp = NULL;
 
@@ -411,6 +415,11 @@ void wxApp::OnIdle(wxIdleEvent& event)
     // 'Garbage' collection of windows deleted with Close().
     DeletePendingObjects();
 
+#if wxUSE_THREADS
+    // Flush pending events.
+    ProcessPendingEvents();
+#endif
+
     // flush the logged messages if any
     wxLog *pLog = wxLog::GetActiveTarget();
     if ( pLog != NULL && pLog->HasPendingMessages() )
@@ -483,6 +492,24 @@ void wxApp::DeletePendingObjects()
     }
 }
 
+#if wxUSE_THREADS
+void wxApp::ProcessPendingEvents()
+
+    wxNode *node = wxPendingEvents.First();
+    wxCriticalSectionLocker locker(wxPendingEventsLocker);
+
+    while (node)
+    {
+        wxEvtHandler *handler = (wxEvtHandler *)node->Data();
+
+        handler->ProcessPendingEvents();
+
+        delete node;
+        node = wxPendingEvents.First();
+    }
+
+#endif
+
 wxLog* wxApp::CreateLogTarget()
 {
     return new wxLogGui;
index bbe4fe2ad76c133d786c80e5156eddd6c97199cf..4767438a1cfd15c5d5912d8a9fe3a22c51943e71 100644 (file)
@@ -27,6 +27,12 @@ wxList wxTopLevelWindows;
 // List of windows pending deletion
 wxList wxPendingDelete;
 
+#if wxUSE_THREADS
+// List of events pending propagation
+wxList wxPendingEvents;
+wxCriticalSection wxPendingEventsLocker;
+#endif
+
 int wxPageNumber;
 
 // GDI Object Lists
index 3ea5ea736221beac3710821946a0fb7ac9afe801..21dd1dbeccabee29bb34a3b16872716375efe8c7 100644 (file)
@@ -92,6 +92,10 @@ extern char *wxBuffer;
 extern char *wxOsVersion;
 extern wxList *wxWinHandleList;
 extern wxList WXDLLEXPORT wxPendingDelete;
+#if wxUSE_THREADS
+extern wxList wxPendingEvents;
+extern wxCriticalSection wxPendingEventsLocker;
+#endif
 extern void wxSetKeyboardHook(bool doIt);
 extern wxCursor *g_globalCursor;
 
@@ -893,7 +897,13 @@ int wxApp::MainLoop()
         {
         }
 
+
         DoMessage();
+
+       // If they are pending events, we must process them.
+#if wxUSE_THREADS
+       ProcessPendingEvents();
+#endif
     }
 
     return s_currentMsg.wParam;
@@ -909,6 +919,25 @@ bool wxApp::ProcessIdle()
     return event.MoreRequested();
 }
 
+#if wxUSE_THREADS
+void wxApp::ProcessPendingEvents()
+
+    wxNode *node = wxPendingEvents.First();
+    wxCriticalSectionLocker locker(wxPendingEventsLocker);
+
+    while (node)
+    {
+        wxEvtHandler *handler = (wxEvtHandler *)node->Data();
+
+        handler->ProcessPendingEvents();
+
+        delete node;
+        node = wxPendingEvents.First();
+    }
+}
+#endif
+
+
 void wxApp::ExitMainLoop()
 {
     m_keepGoing = FALSE;
index e7e0283111655d21a2c116aea01d210f81e52a60..439c73cd49712bf9efcd2801357b1d527a554430 100644 (file)
@@ -37,6 +37,12 @@ wxList wxTopLevelWindows;
 // List of windows pending deletion
 wxList WXDLLEXPORT wxPendingDelete;
 
+// List of events pending processing
+#if wxUSE_THREADS
+wxList wxPendingEvents;
+wxCriticalSection wxPendingEventsLocker;
+#endif
+
 // Current cursor, in order to hang on to
 // cursor handle when setting the cursor globally
 wxCursor *g_globalCursor = NULL;