};
typedef void (wxEvtHandler::*MyEventFunction)(MyEvent&);
-#if wxEVENTS_COMPATIBILITY_2_8
+#ifndef wxHAS_EVENT_BIND
#define MyEventHandler(func) wxEVENT_HANDLER_CAST(MyEventFunction, func)
#else
#define MyEventHandler(func) &func
g_called.function = true;
}
+void GlobalOnEvent(wxEvent&)
+{
+ g_called.function = true;
+}
+
void GlobalOnAnotherEvent(AnotherEvent&);
void GlobalOnIdle(wxIdleEvent&)
EVT_IDLE(MyClassWithEventTable::OnIdle)
EVT_MYEVENT(MyClassWithEventTable::OnMyEvent)
-#if !wxEVENTS_COMPATIBILITY_2_8
+#ifdef wxHAS_EVENT_BIND
EVT_MYEVENT(MyClassWithEventTable::OnEvent)
#endif
CPPUNIT_TEST_SUITE( EvtHandlerTestCase );
CPPUNIT_TEST( BuiltinConnect );
CPPUNIT_TEST( LegacyConnect );
-#if !wxEVENTS_COMPATIBILITY_2_8
+ CPPUNIT_TEST( DisconnectWildcard );
+ CPPUNIT_TEST( AutoDisconnect );
+#ifdef wxHAS_EVENT_BIND
CPPUNIT_TEST( BindFunction );
CPPUNIT_TEST( BindStaticMethod );
CPPUNIT_TEST( BindFunctor );
CPPUNIT_TEST( BindMethod );
CPPUNIT_TEST( BindMethodUsingBaseEvent );
+ CPPUNIT_TEST( BindFunctionUsingBaseEvent );
CPPUNIT_TEST( BindNonHandler );
CPPUNIT_TEST( InvalidBind );
-#endif // !wxEVENTS_COMPATIBILITY_2_8
+#endif // wxHAS_EVENT_BIND
CPPUNIT_TEST_SUITE_END();
void BuiltinConnect();
void LegacyConnect();
-#if !wxEVENTS_COMPATIBILITY_2_8
+ void DisconnectWildcard();
+ void AutoDisconnect();
+#ifdef wxHAS_EVENT_BIND
void BindFunction();
void BindStaticMethod();
void BindFunctor();
void BindMethod();
void BindMethodUsingBaseEvent();
+ void BindFunctionUsingBaseEvent();
void BindNonHandler();
void InvalidBind();
-#endif // !wxEVENTS_COMPATIBILITY_2_8
+#endif // wxHAS_EVENT_BIND
// these member variables exceptionally don't use "m_" prefix because
// register in the unnamed registry so that these tests are run by default
CPPUNIT_TEST_SUITE_REGISTRATION( EvtHandlerTestCase );
-// also include in it's own registry so that these tests can be run alone
+// also include in its own registry so that these tests can be run alone
CPPUNIT_TEST_SUITE_NAMED_REGISTRATION( EvtHandlerTestCase, "EvtHandlerTestCase" );
void EvtHandlerTestCase::BuiltinConnect()
handler.Connect(wxEVT_IDLE, (wxObjectEventFunction)(wxEventFunction)&MyHandler::OnIdle);
handler.Disconnect(wxEVT_IDLE, (wxObjectEventFunction)(wxEventFunction)&MyHandler::OnIdle);
-#if !wxEVENTS_COMPATIBILITY_2_8
+#ifdef wxHAS_EVENT_BIND
handler.Bind(wxEVT_IDLE, GlobalOnIdle);
handler.Unbind(wxEVT_IDLE, GlobalOnIdle);
handler.Bind(wxEVT_IDLE, &MyHandler::StaticOnIdle);
handler.Unbind(wxEVT_IDLE, &MyHandler::StaticOnIdle);
-#endif // !wxEVENTS_COMPATIBILITY_2_8
+#endif // wxHAS_EVENT_BIND
}
void EvtHandlerTestCase::LegacyConnect()
handler.Disconnect( 0, 0, LegacyEventType, (wxObjectEventFunction)&MyHandler::OnEvent, NULL, &handler );
}
-#if !wxEVENTS_COMPATIBILITY_2_8
+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()
{
handler.Bind( MyEventType, functor, 0, 0 );
handler.Unbind( MyEventType, functor, 0, 0 );
+
+ // test that a temporary functor is working as well and also test that
+ // unbinding a different (though equal) instance of the same functor does
+ // not work
+ MyFunctor func;
+ handler.Bind( MyEventType, MyFunctor() );
+ CPPUNIT_ASSERT( !handler.Unbind( MyEventType, func ));
+
+ handler.Bind( MyEventType, MyFunctor(), 0 );
+ CPPUNIT_ASSERT( !handler.Unbind( MyEventType, func, 0 ));
+
+ handler.Bind( MyEventType, MyFunctor(), 0, 0 );
+ CPPUNIT_ASSERT( !handler.Unbind( MyEventType, func, 0, 0 ));
}
void EvtHandlerTestCase::BindMethod()
}
+void EvtHandlerTestCase::BindFunctionUsingBaseEvent()
+{
+ // test connecting a function taking just wxEvent and not MyEvent: this
+ // should work too if we don't need any MyEvent-specific information in the
+ // handler
+ handler.Bind( MyEventType, GlobalOnEvent );
+ g_called.Reset();
+ handler.ProcessEvent(e);
+ CPPUNIT_ASSERT( g_called.function );
+ handler.Unbind( MyEventType, GlobalOnEvent );
+ g_called.Reset();
+ handler.ProcessEvent(e);
+ CPPUNIT_ASSERT( !g_called.function );
+
+ handler.Bind( MyEventType, GlobalOnEvent, 0 );
+ handler.Unbind( MyEventType, GlobalOnEvent, 0 );
+
+ handler.Bind( MyEventType, GlobalOnEvent, 0, 0 );
+ handler.Unbind( MyEventType, GlobalOnEvent, 0, 0 );
+}
+
+
+
void EvtHandlerTestCase::BindNonHandler()
{
// class method tests for class not derived from wxEvtHandler
// automatically, you need to uncomment them manually and test that
// compilation does indeed fail
- //handler.Bind(MyEventType, GlobalOnAnotherEvent);
- //IdleFunctor f; handler.Bind(MyEventType, f);
- //handler.Bind(MyEventType, &MyHandler::StaticOnAnotherEvent);
- //handler.Bind(MyEventType, &MyHandler::OnAnotherEvent, &handler);
+ // connecting a handler with incompatible signature shouldn't work
+#ifdef TEST_INVALID_BIND_GLOBAL
+ handler.Bind(MyEventType, GlobalOnAnotherEvent);
+#endif
+#ifdef TEST_INVALID_BIND_STATIC
+ handler.Bind(MyEventType, &MyHandler::StaticOnAnotherEvent);
+#endif
+#ifdef TEST_INVALID_BIND_METHOD
+ handler.Bind(MyEventType, &MyHandler::OnAnotherEvent, &handler);
+#endif
+#ifdef TEST_INVALID_BIND_FUNCTOR
+ IdleFunctor f;
+ handler.Bind(MyEventType, f);
+#endif
- // Test that this sample (discussed on the mailing list) doesn't compile:
- // >struct C1 : wxEvtHandler { };
- // >struct C2 : wxEvtHandler { void OnWhatever(wxEvent&) };
- // >C1 c1;
- // >c1.Connect(&C2::OnWhatever); // BOOM
+ // the handler can't be omitted when calling Bind()
+#ifdef TEST_INVALID_BIND_NO_HANDLER
+ handler.Bind(MyEventType, &MyHandler::OnMyEvent);
+#endif
+
+ // calling a derived class method with a base class pointer must not work
+#ifdef TEST_INVALID_BIND_DERIVED
+ struct C1 : wxEvtHandler { };
+ struct C2 : wxEvtHandler { void OnWhatever(wxEvent&); };
+ C1 c1;
+ c1.Bind(&C2::OnWhatever);
+#endif
- //MySink mySink;
- //MyHandler myHandler;
- //myHandler.Bind( MyEventType, &MyHandler::OnMyEvent, &mySink );
+ // using object pointer incompatible with the method must not work
+#ifdef TEST_INVALID_BIND_WRONG_CLASS
+ MySink mySink;
+ MyHandler myHandler;
+ myHandler.Bind(MyEventType, &MyHandler::OnMyEvent, &mySink);
+#endif
}
-#endif // !wxEVENTS_COMPATIBILITY_2_8
+#endif // wxHAS_EVENT_BIND