// add an event to be processed later
void AddPendingEvent(wxEvent& event);
- // process all pending events
void ProcessPendingEvents();
#if wxUSE_THREADS
void SetClientData( void *data ) { DoSetClientData(data); }
void *GetClientData() const { return DoGetClientData(); }
+ // reentrance guard
+ void AllowReentrance( bool allow = true ) { m_reentranceAllowed = allow; }
+ bool IsReentranceAllowed() { return m_reentranceAllowed; }
+ bool IsEventHandlingInProgress() { return m_eventHandlingInProgress; }
+
// check if the given event table entry matches this event and call the
// handler if it does
//
# endif
#endif
+ bool m_reentranceAllowed; // Reentrance is allowed for this handler?
+ bool m_eventHandlingInProgress; // Eventhandling is in progress?
+
// Is event handler enabled?
bool m_enabled;
// iterate until the list becomes empty
wxList::compatibility_iterator node = wxPendingEvents->GetFirst();
+
+ while (node &&
+ ((wxEvtHandler *)node->GetData())->IsEventHandlingInProgress() &&
+ ((wxEvtHandler *)node->GetData())->IsReentranceAllowed() == false)
+ {
+ // skip over event
+ node = node->GetNext();
+ }
+
while (node)
{
wxEvtHandler *handler = (wxEvtHandler *)node->GetData();
wxENTER_CRIT_SECT( *wxPendingEventsLocker );
node = wxPendingEvents->GetFirst();
+
+ while (node &&
+ ((wxEvtHandler *)node->GetData())->IsEventHandlingInProgress() &&
+ ((wxEvtHandler *)node->GetData())->IsReentranceAllowed() == false)
+ {
+ // skip over event
+ node = node->GetNext();
+ }
}
wxLEAVE_CRIT_SECT( *wxPendingEventsLocker );
m_eventsLocker = new wxCriticalSection;
# endif
#endif
+ // reentrace not allowed by default
+ m_reentranceAllowed = false;
+ m_eventHandlingInProgress = false;
+
// no client data (yet)
m_clientData = NULL;
m_clientDataType = wxClientData_None;
void wxEvtHandler::ProcessPendingEvents()
{
- // this method is only called by wxApp if this handler does have pending
- // events
+ // this method is only called by wxApp if this handler does have
+ // pending events
wxCHECK_RET( m_pendingEvents,
wxT("Please call wxApp::ProcessPendingEvents() instead") );
+
+ // eventhandling is now in progess
+ m_eventHandlingInProgress = true;
wxENTER_CRIT_SECT( Lock() );
// It's importan we remove event from list before processing it.
// Else a nested event loop, for example from a modal dialog, might
// process the same event again.
+
m_pendingEvents->Erase(node);
wxLEAVE_CRIT_SECT( Lock() );
ProcessEvent(*event);
+
+ // eventhandling no longer in progess
+ m_eventHandlingInProgress = false;
+
delete event;
wxENTER_CRIT_SECT( Lock() );