if (!m_dynamicEvents)
return false;
- // Remove connection from tracker node (wxEventConnectionRef)
- wxEvtHandler *eventSink = func.GetEvtHandler();
- if ( eventSink && eventSink != this )
- {
- wxEventConnectionRef *evtConnRef = FindRefInTrackerList(eventSink);
- if ( evtConnRef )
- evtConnRef->DecRef();
- }
-
wxList::compatibility_iterator node = m_dynamicEvents->GetFirst();
while (node)
{
entry->m_fn->IsMatching(func) &&
((entry->m_callbackUserData == userData) || !userData))
{
+ // Remove connection from tracker node (wxEventConnectionRef)
+ wxEvtHandler *eventSink = entry->m_fn->GetEvtHandler();
+ if ( eventSink && eventSink != this )
+ {
+ wxEventConnectionRef *evtConnRef = FindRefInTrackerList(eventSink);
+ if ( evtConnRef )
+ evtConnRef->DecRef();
+ }
+
delete entry->m_callbackUserData;
m_dynamicEvents->Erase( node );
delete entry;
CPPUNIT_TEST_SUITE( EvtHandlerTestCase );
CPPUNIT_TEST( BuiltinConnect );
CPPUNIT_TEST( LegacyConnect );
+ CPPUNIT_TEST( DisconnectWildcard );
+ CPPUNIT_TEST( AutoDisconnect );
#ifdef wxHAS_EVENT_BIND
CPPUNIT_TEST( BindFunction );
CPPUNIT_TEST( BindStaticMethod );
void BuiltinConnect();
void LegacyConnect();
+ void DisconnectWildcard();
+ void AutoDisconnect();
#ifdef wxHAS_EVENT_BIND
void BindFunction();
void BindStaticMethod();
handler.Disconnect( 0, 0, LegacyEventType, (wxObjectEventFunction)&MyHandler::OnEvent, NULL, &handler );
}
+void EvtHandlerTestCase::DisconnectWildcard()
+{
+ // should be able to disconnect a different handler using "wildcard search"
+ MyHandler sink;
+ wxEvtHandler source;
+ source.Connect(wxEVT_IDLE, wxIdleEventHandler(MyHandler::OnIdle), NULL, &sink);
+ CPPUNIT_ASSERT(source.Disconnect(wxID_ANY, wxEVT_IDLE));
+ // destruction of source and sink here should properly clean up the
+ // wxEventConnectionRef without crashing
+}
+
+void EvtHandlerTestCase::AutoDisconnect()
+{
+ wxEvtHandler source;
+ {
+ MyHandler sink;
+ source.Connect(wxEVT_IDLE, wxIdleEventHandler(MyHandler::OnIdle), NULL, &sink);
+ // mismatched event type, so nothing should be disconnected
+ CPPUNIT_ASSERT(!source.Disconnect(wxEVT_THREAD, wxIdleEventHandler(MyHandler::OnIdle), NULL, &sink));
+ }
+ // destruction of sink should have automatically disconnected it, so
+ // there should be nothing to disconnect anymore
+ CPPUNIT_ASSERT(!source.Disconnect(wxID_ANY, wxEVT_IDLE));
+}
+
#ifdef wxHAS_EVENT_BIND
void EvtHandlerTestCase::BindFunction()