* Added threads event propagation. Should compile on GTK (tested).

git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@1986 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775
This commit is contained in:
Guilhem Lavaux
1999-03-27 18:50:54 +00:00
parent eedcfe5eb9
commit 7214297d16
14 changed files with 223 additions and 5 deletions

View File

@@ -19,6 +19,9 @@
#include "wx/defs.h" #include "wx/defs.h"
#include "wx/object.h" #include "wx/object.h"
#include "wx/gdicmn.h" #include "wx/gdicmn.h"
#if wxUSE_THREADS
#include "wx/thread.h"
#endif
/* /*
* Event types * Event types
@@ -347,7 +350,7 @@ public:
// Set/Get listbox/choice selection string // Set/Get listbox/choice selection string
void SetString(const wxString& s) { m_commandString = s; } void SetString(const wxString& s) { m_commandString = s; }
const wxString& GetString() const { return m_commandString; } wxString GetString() const { return m_commandString; }
// Get checkbox value // Get checkbox value
bool Checked() const { return (m_commandInt != 0); } bool Checked() const { return (m_commandInt != 0); }
@@ -1170,6 +1173,10 @@ public:
virtual bool OnClose(); virtual bool OnClose();
#endif #endif
#if wxUSE_THREADS
bool ProcessThreadEvent(wxEvent& event);
void ProcessPendingEvents();
#endif
virtual bool ProcessEvent(wxEvent& event); virtual bool ProcessEvent(wxEvent& event);
virtual bool SearchEventTable(wxEventTable& table, wxEvent& event); virtual bool SearchEventTable(wxEventTable& table, wxEvent& event);
@@ -1196,10 +1203,14 @@ protected:
virtual const wxEventTable *GetEventTable() const; virtual const wxEventTable *GetEventTable() const;
protected: protected:
wxEvtHandler* m_nextHandler; wxEvtHandler* m_nextHandler;
wxEvtHandler* m_previousHandler; wxEvtHandler* m_previousHandler;
bool m_enabled; // Is event handler enabled? bool m_enabled; // Is event handler enabled?
wxList* m_dynamicEvents; wxList* m_dynamicEvents;
wxList* m_pendingEvents;
#if wxUSE_THREADS
wxCriticalSection* m_eventsLocker;
#endif
// optimization: instead of using costly IsKindOf() to decide whether we're // optimization: instead of using costly IsKindOf() to decide whether we're
// a window (which is true in 99% of cases), use this flag // a window (which is true in 99% of cases), use this flag

View File

@@ -115,6 +115,9 @@ class wxApp: public wxEvtHandler
static void CleanUp(); static void CleanUp();
bool ProcessIdle(); bool ProcessIdle();
#if wxUSE_THREADS
void ProcessPendingEvents();
#endif
void DeletePendingObjects(); void DeletePendingObjects();
bool m_initialized; bool m_initialized;

View File

@@ -115,6 +115,9 @@ class wxApp: public wxEvtHandler
static void CleanUp(); static void CleanUp();
bool ProcessIdle(); bool ProcessIdle();
#if wxUSE_THREADS
void ProcessPendingEvents();
#endif
void DeletePendingObjects(); void DeletePendingObjects();
bool m_initialized; bool m_initialized;

View File

@@ -141,6 +141,9 @@ public:
void DeletePendingObjects(); void DeletePendingObjects();
bool ProcessIdle(); bool ProcessIdle();
#if wxUSE_THREADS
void ProcessPendingEvents();
#endif
// Motif-specific // Motif-specific
inline WXAppContext GetAppContext() const { return m_appContext; } inline WXAppContext GetAppContext() const { return m_appContext; }

View File

@@ -144,6 +144,9 @@ public:
virtual bool ProcessMessage(WXMSG* pMsg); virtual bool ProcessMessage(WXMSG* pMsg);
void DeletePendingObjects(); void DeletePendingObjects();
bool ProcessIdle(); bool ProcessIdle();
#if wxUSE_THREADS
void ProcessPendingEvents();
#endif
int GetComCtl32Version() const; int GetComCtl32Version() const;
public: public:

View File

@@ -78,6 +78,12 @@
#endif // !USE_SHARED_LIBRARY #endif // !USE_SHARED_LIBRARY
#if wxUSE_THREADS
/* To put pending event handlers */
extern wxList wxPendingEvents;
extern wxCriticalSection wxPendingEventsLocker;
#endif
/* /*
* General wxWindows events, covering * General wxWindows events, covering
* all interesting things that might happen (button clicking, resizing, * all interesting things that might happen (button clicking, resizing,
@@ -283,6 +289,10 @@ wxEvtHandler::wxEvtHandler()
m_enabled = TRUE; m_enabled = TRUE;
m_dynamicEvents = (wxList *) NULL; m_dynamicEvents = (wxList *) NULL;
m_isWindow = FALSE; m_isWindow = FALSE;
#if wxUSE_THREADS
m_eventsLocker = new wxCriticalSection();
#endif
m_pendingEvents = (wxList *) NULL;
} }
wxEvtHandler::~wxEvtHandler() wxEvtHandler::~wxEvtHandler()
@@ -306,8 +316,54 @@ wxEvtHandler::~wxEvtHandler()
} }
delete m_dynamicEvents; 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 * Event table stuff
*/ */
@@ -320,6 +376,11 @@ bool wxEvtHandler::ProcessEvent(wxEvent& event)
// An event handler can be enabled or disabled // An event handler can be enabled or disabled
if ( GetEvtHandlerEnabled() ) 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 // Handle per-instance dynamic event tables first
if ( m_dynamicEvents && SearchDynamicEventTable(event) ) if ( m_dynamicEvents && SearchDynamicEventTable(event) )

View File

@@ -46,6 +46,10 @@ wxApp *wxTheApp = (wxApp *) NULL;
wxAppInitializerFunction wxApp::m_appInitFn = (wxAppInitializerFunction) NULL; wxAppInitializerFunction wxApp::m_appInitFn = (wxAppInitializerFunction) NULL;
extern wxList wxPendingDelete; extern wxList wxPendingDelete;
#if wxUSE_THREADS
extern wxList wxPendingEvents;
extern wxCriticalSection wxPendingEventsLocker;
#endif
extern wxResourceCache *wxTheResourceCache; extern wxResourceCache *wxTheResourceCache;
unsigned char g_palette[64*3] = unsigned char g_palette[64*3] =
@@ -283,6 +287,10 @@ void wxApp::OnIdle( wxIdleEvent &event )
inOnIdle = TRUE; inOnIdle = TRUE;
/* Resend in the main thread events which have been prepared in other
threads */
ProcessPendingEvents();
/* 'Garbage' collection of windows deleted with Close(). */ /* 'Garbage' collection of windows deleted with Close(). */
DeletePendingObjects(); 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() void wxApp::DeletePendingObjects()
{ {
wxNode *node = wxPendingDelete.First(); wxNode *node = wxPendingDelete.First();

View File

@@ -38,6 +38,12 @@ wxList wxTopLevelWindows;
/* List of windows pending deletion */ /* List of windows pending deletion */
wxList wxPendingDelete; wxList wxPendingDelete;
#if wxUSE_THREADS
/* List of events pending processing */
wxList wxPendingEvents;
wxCriticalSection wxPendingEventsLocker;
#endif
/* Current cursor, in order to hang on to /* Current cursor, in order to hang on to
* cursor handle when setting the cursor globally */ * cursor handle when setting the cursor globally */
wxCursor *g_globalCursor = (wxCursor *) NULL; wxCursor *g_globalCursor = (wxCursor *) NULL;

View File

@@ -46,6 +46,10 @@ wxApp *wxTheApp = (wxApp *) NULL;
wxAppInitializerFunction wxApp::m_appInitFn = (wxAppInitializerFunction) NULL; wxAppInitializerFunction wxApp::m_appInitFn = (wxAppInitializerFunction) NULL;
extern wxList wxPendingDelete; extern wxList wxPendingDelete;
#if wxUSE_THREADS
extern wxList wxPendingEvents;
extern wxCriticalSection wxPendingEventsLocker;
#endif
extern wxResourceCache *wxTheResourceCache; extern wxResourceCache *wxTheResourceCache;
unsigned char g_palette[64*3] = unsigned char g_palette[64*3] =
@@ -283,6 +287,10 @@ void wxApp::OnIdle( wxIdleEvent &event )
inOnIdle = TRUE; inOnIdle = TRUE;
/* Resend in the main thread events which have been prepared in other
threads */
ProcessPendingEvents();
/* 'Garbage' collection of windows deleted with Close(). */ /* 'Garbage' collection of windows deleted with Close(). */
DeletePendingObjects(); 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() void wxApp::DeletePendingObjects()
{ {
wxNode *node = wxPendingDelete.First(); wxNode *node = wxPendingDelete.First();

View File

@@ -38,6 +38,12 @@ wxList wxTopLevelWindows;
/* List of windows pending deletion */ /* List of windows pending deletion */
wxList wxPendingDelete; wxList wxPendingDelete;
#if wxUSE_THREADS
/* List of events pending processing */
wxList wxPendingEvents;
wxCriticalSection wxPendingEventsLocker;
#endif
/* Current cursor, in order to hang on to /* Current cursor, in order to hang on to
* cursor handle when setting the cursor globally */ * cursor handle when setting the cursor globally */
wxCursor *g_globalCursor = (wxCursor *) NULL; wxCursor *g_globalCursor = (wxCursor *) NULL;

View File

@@ -49,6 +49,10 @@
extern char *wxBuffer; extern char *wxBuffer;
extern wxList wxPendingDelete; extern wxList wxPendingDelete;
#if wxUSE_THREADS
extern wxList wxPendingEvents;
extern wxList wxPendingEventsLocker;
#endif
wxApp *wxTheApp = NULL; wxApp *wxTheApp = NULL;
@@ -411,6 +415,11 @@ void wxApp::OnIdle(wxIdleEvent& event)
// 'Garbage' collection of windows deleted with Close(). // 'Garbage' collection of windows deleted with Close().
DeletePendingObjects(); DeletePendingObjects();
#if wxUSE_THREADS
// Flush pending events.
ProcessPendingEvents();
#endif
// flush the logged messages if any // flush the logged messages if any
wxLog *pLog = wxLog::GetActiveTarget(); wxLog *pLog = wxLog::GetActiveTarget();
if ( pLog != NULL && pLog->HasPendingMessages() ) 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() wxLog* wxApp::CreateLogTarget()
{ {
return new wxLogGui; return new wxLogGui;

View File

@@ -27,6 +27,12 @@ wxList wxTopLevelWindows;
// List of windows pending deletion // List of windows pending deletion
wxList wxPendingDelete; wxList wxPendingDelete;
#if wxUSE_THREADS
// List of events pending propagation
wxList wxPendingEvents;
wxCriticalSection wxPendingEventsLocker;
#endif
int wxPageNumber; int wxPageNumber;
// GDI Object Lists // GDI Object Lists

View File

@@ -92,6 +92,10 @@ extern char *wxBuffer;
extern char *wxOsVersion; extern char *wxOsVersion;
extern wxList *wxWinHandleList; extern wxList *wxWinHandleList;
extern wxList WXDLLEXPORT wxPendingDelete; extern wxList WXDLLEXPORT wxPendingDelete;
#if wxUSE_THREADS
extern wxList wxPendingEvents;
extern wxCriticalSection wxPendingEventsLocker;
#endif
extern void wxSetKeyboardHook(bool doIt); extern void wxSetKeyboardHook(bool doIt);
extern wxCursor *g_globalCursor; extern wxCursor *g_globalCursor;
@@ -893,7 +897,13 @@ int wxApp::MainLoop()
{ {
} }
DoMessage(); DoMessage();
// If they are pending events, we must process them.
#if wxUSE_THREADS
ProcessPendingEvents();
#endif
} }
return s_currentMsg.wParam; return s_currentMsg.wParam;
@@ -909,6 +919,25 @@ bool wxApp::ProcessIdle()
return event.MoreRequested(); 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() void wxApp::ExitMainLoop()
{ {
m_keepGoing = FALSE; m_keepGoing = FALSE;

View File

@@ -37,6 +37,12 @@ wxList wxTopLevelWindows;
// List of windows pending deletion // List of windows pending deletion
wxList WXDLLEXPORT wxPendingDelete; wxList WXDLLEXPORT wxPendingDelete;
// List of events pending processing
#if wxUSE_THREADS
wxList wxPendingEvents;
wxCriticalSection wxPendingEventsLocker;
#endif
// Current cursor, in order to hang on to // Current cursor, in order to hang on to
// cursor handle when setting the cursor globally // cursor handle when setting the cursor globally
wxCursor *g_globalCursor = NULL; wxCursor *g_globalCursor = NULL;