replace templae Connect() overloads with separate Bind() method to improve compatibility (see #10000, closes #10477)

git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@59134 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775
This commit is contained in:
Vadim Zeitlin
2009-02-25 17:43:22 +00:00
parent ec38d07d03
commit 5293e4b710
3 changed files with 118 additions and 322 deletions

View File

@@ -126,10 +126,6 @@ extern WXDLLIMPEXP_BASE wxEventType wxNewEventType();
#define wxDECLARE_EVENT( name, type ) \ #define wxDECLARE_EVENT( name, type ) \
wxDECLARE_EXPORTED_EVENT( wxEMPTY_PARAMETER_VALUE, name, type ); wxDECLARE_EXPORTED_EVENT( wxEMPTY_PARAMETER_VALUE, name, type );
// Try to cast the given event handler to the correct handler type:
#define wxEVENT_HANDLER_CAST( functype, func ) \
( wxObjectEventFunction )( wxEventFunction )wxStaticCastEvent( functype, &func )
#else #else
// Define/Declare a templatized event type with the corresponding event as // Define/Declare a templatized event type with the corresponding event as
// a nested typedef: // a nested typedef:
@@ -155,12 +151,12 @@ extern WXDLLIMPEXP_BASE wxEventType wxNewEventType();
#define wxDECLARE_EVENT( name, type ) \ #define wxDECLARE_EVENT( name, type ) \
wxDECLARE_EXPORTED_EVENT( wxEMPTY_PARAMETER_VALUE, name, type ); wxDECLARE_EXPORTED_EVENT( wxEMPTY_PARAMETER_VALUE, name, type );
// Don't cast the given event handler so that wxEvtHandler::Connect() sees #endif
// the actual type:
// Try to cast the given event handler to the correct handler type:
#define wxEVENT_HANDLER_CAST( functype, func ) \ #define wxEVENT_HANDLER_CAST( functype, func ) \
( &func ) ( wxObjectEventFunction )( wxEventFunction )wxStaticCastEvent( functype, &func )
#endif
// Template which associates the correct event object with the event type // Template which associates the correct event object with the event type
@@ -2977,121 +2973,44 @@ public:
{ return Disconnect(wxID_ANY, eventType, func, userData, eventSink); } { return Disconnect(wxID_ANY, eventType, func, userData, eventSink); }
#if !wxEVENTS_COMPATIBILITY_2_8 #if !wxEVENTS_COMPATIBILITY_2_8
// Event handling in functions (including generalized functors): // Bind arbitrary functor (including just a function) to an event:
template <typename EventTag, typename Functor> template <typename EventTag, typename Functor>
void Connect(int winid, void Bind(const EventTag& eventType,
int lastId, Functor func,
const EventTag& eventType, int winid = wxID_ANY,
Functor func) int lastId = wxID_ANY,
{
DoConnect(winid, lastId, eventType,
wxNewEventFunctor(eventType, func));
}
template <typename EventTag, typename Functor>
void Connect(int winid, const EventTag& eventType, Functor func)
{ Connect(winid, wxID_ANY, eventType, func); }
template <typename EventTag, typename Functor>
void Connect(const EventTag& eventType, Functor func)
{ Connect(wxID_ANY, eventType, func); }
template <typename EventTag, typename Functor>
bool Disconnect(int winid,
int lastId,
const EventTag& eventType,
Functor func)
{
return DoDisconnect(winid, lastId, eventType,
wxMakeEventFunctor(eventType, func));
}
template <typename EventTag, typename Functor>
bool Disconnect(int winid, const EventTag& eventType, Functor func)
{ return Disconnect(winid, wxID_ANY, eventType, func); }
template <typename EventTag, typename Functor>
bool Disconnect(const EventTag& eventType, Functor func)
{ return Disconnect(wxID_ANY, eventType, func); }
// Event handling in class methods: the object handling the event (i.e.
// this object itself by default or eventSink if specified) must be
// convertible to this class.
//
// Notice that we need to have separate overloads for the versions with and
// without eventSink because in the latter case we must check that this
// object itself derives from Class while in the former this is not
// necessarily true
// Methods connecting/disconnecting event to this object itself
template <typename EventTag, typename Class, typename EventArg>
void Connect(int winid,
int lastId,
const EventTag& eventType,
void (Class::*func)(EventArg&),
wxObject *userData = NULL) wxObject *userData = NULL)
{ {
DoConnect(winid, lastId, eventType, DoConnect(winid, lastId, eventType,
wxNewEventFunctor(eventType, func, static_cast<Class *>(this)), wxNewEventFunctor(eventType, func),
userData); userData);
} }
template <typename EventTag, typename Class, typename EventArg>
void Connect(int winid,
const EventTag& eventType,
void (Class::*func)(EventArg&),
wxObject *userData = NULL)
{ Connect(winid, wxID_ANY, eventType, func, userData); }
template <typename EventTag, typename Class, typename EventArg> template <typename EventTag, typename Functor>
void Connect(const EventTag& eventType, bool Unbind(const EventTag& eventType,
void (Class::*func)(EventArg&), Functor func,
wxObject *userData = NULL) int winid = wxID_ANY,
{ Connect(wxID_ANY, eventType, func, userData); } int lastId = wxID_ANY,
template <typename EventTag, typename Class, typename EventArg>
bool Disconnect(int winid,
int lastId,
const EventTag& eventType,
void (Class::*func)(EventArg&),
wxObject *userData = NULL) wxObject *userData = NULL)
{ {
return DoDisconnect(winid, lastId, eventType, return DoDisconnect(winid, lastId, eventType,
wxMakeEventFunctor(eventType, func, wxMakeEventFunctor(eventType, func),
static_cast<Class *>(this)),
userData); userData);
} }
template <typename EventTag, typename Class, typename EventArg>
bool Disconnect(int winid,
const EventTag& eventType,
void (Class::*func)(EventArg&),
wxObject *userData = NULL)
{ return Disconnect(winid, wxID_ANY, eventType, func, userData); }
template <typename EventTag, typename Class, typename EventArg> // Bind a method of a class (called on the specified eventSink which must
bool Disconnect(const EventTag& eventType, // be convertible to this class) object to an event:
void (Class::*func)(EventArg&),
wxObject *userData = NULL)
{ return Disconnect(wxID_ANY, eventType, func, userData); }
// Methods connecting/disconnecting event to another object
template template
<typename EventTag, typename Class, typename EventArg, typename ObjClass> <typename EventTag, typename Class, typename EventArg, typename ObjClass>
void Connect(int winid, void Bind(const EventTag &eventType,
int lastId,
const EventTag& eventType,
void (Class::*func)(EventArg &), void (Class::*func)(EventArg &),
wxObject *userData, ObjClass *eventSink,
ObjClass *eventSink) int winid = wxID_ANY,
int lastId = wxID_ANY,
wxObject *userData = NULL)
{ {
DoConnect(winid, lastId, eventType, DoConnect(winid, lastId, eventType,
wxNewEventFunctor(eventType, func, eventSink), wxNewEventFunctor(eventType, func, eventSink),
@@ -3100,136 +3019,19 @@ public:
template template
<typename EventTag, typename Class, typename EventArg, typename ObjClass> <typename EventTag, typename Class, typename EventArg, typename ObjClass>
void Connect(int winid, bool Unbind(const EventTag &eventType,
const EventTag& eventType,
void (Class::*func)(EventArg&), void (Class::*func)(EventArg&),
wxObject *userData, ObjClass *eventSink,
ObjClass *eventSink) int winid = wxID_ANY,
{ Connect(winid, wxID_ANY, eventType, func, userData, eventSink); } int lastId = wxID_ANY,
wxObject *userData = NULL )
template
<typename EventTag, typename Class, typename EventArg, typename ObjClass>
void Connect(const EventTag& eventType,
void (Class::*func)(EventArg&),
wxObject *userData,
ObjClass *eventSink)
{ Connect(wxID_ANY, eventType, func, userData, eventSink); }
template
<typename EventTag, typename Class, typename EventArg, typename ObjClass>
bool Disconnect(int winid,
int lastId,
const EventTag& eventType,
void (Class::*func)(EventArg&),
wxObject *userData,
ObjClass *eventSink)
{ {
return DoDisconnect(winid, lastId, eventType, return DoDisconnect(winid, lastId, eventType,
wxMakeEventFunctor(eventType, func, eventSink), wxMakeEventFunctor(eventType, func, eventSink),
userData); userData);
} }
template
<typename EventTag, typename Class, typename EventArg, typename ObjClass>
bool Disconnect(int winid,
const EventTag& eventType,
void (Class::*func)(EventArg&),
wxObject *userData,
ObjClass *eventSink)
{ return Disconnect(winid, wxID_ANY, eventType, func,
userData, eventSink); }
template
<typename EventTag, typename Class, typename EventArg, typename ObjClass>
bool Disconnect(const EventTag& eventType,
void (Class::*func)(EventArg&),
wxObject *userData,
ObjClass *eventSink)
{ return Disconnect(wxID_ANY, eventType, func, userData, eventSink); }
// Static version of Connect() which allows to specify the event source and
// event handler in a more symmetric way
template <typename ObjSource, typename EventTag,
typename Class, typename EventArg, typename ObjClass>
static void Connect(ObjSource *eventSrc,
int winid,
int lastId,
const EventTag& eventType,
void (Class::*func)(EventArg&),
wxObject *userData = NULL,
ObjClass *eventSink = NULL)
{
eventSrc->Connect(winid, lastId, eventType, func, userData, eventSink);
}
template <typename ObjSource, typename EventTag,
typename Class, typename EventArg, typename ObjClass>
static void Connect(ObjSource *eventSrc,
int winid,
const EventTag& eventType,
void (Class::*func)(EventArg&),
wxObject *userData = NULL,
ObjClass *eventSink = NULL)
{
Connect(eventSrc, winid, wxID_ANY, eventType, func, userData, eventSink);
}
template <typename ObjSource, typename EventTag,
typename Class, typename EventArg, typename ObjClass>
static void Connect(ObjSource *eventSrc,
const EventTag& eventType,
void (Class::*func)(EventArg&),
wxObject *userData = NULL,
ObjClass *eventSink = NULL)
{
Connect(eventSrc, wxID_ANY, eventType, func, userData, eventSink);
}
template <typename ObjSource, typename EventTag,
typename Class, typename EventArg, typename ObjClass>
static bool Disconnect(ObjSource *eventSrc,
int winid,
int lastId,
const EventTag& eventType,
void (Class::*func)(EventArg&),
wxObject *userData = NULL,
ObjClass *eventSink = NULL)
{
return eventSrc->Disconnect(winid, lastId, eventType, func,
userData, eventSink);
}
template <typename ObjSource, typename EventTag,
typename Class, typename EventArg, typename ObjClass>
static bool Disconnect(ObjSource *eventSrc,
int winid,
const EventTag& eventType,
void (Class::*func)(EventArg&),
wxObject *userData = NULL,
ObjClass *eventSink = NULL)
{
return Disconnect(eventSrc, winid, wxID_ANY, eventType, func,
userData, eventSink);
}
template <typename ObjSource, typename EventTag,
typename Class, typename EventArg, typename ObjClass>
static bool Disconnect(ObjSource *eventSrc,
const EventTag& eventType,
void (Class::*func)(EventArg&),
wxObject *userData = NULL,
ObjClass *eventSink = NULL)
{
return Disconnect(eventSrc, wxID_ANY, eventType, func,
userData, eventSink);
}
#endif // !wxEVENTS_COMPATIBILITY_2_8 #endif // !wxEVENTS_COMPATIBILITY_2_8
wxList* GetDynamicEventTable() const { return m_dynamicEvents ; } wxList* GetDynamicEventTable() const { return m_dynamicEvents ; }
// User data can be associated with each wxEvtHandler // User data can be associated with each wxEvtHandler

View File

@@ -34,6 +34,7 @@ public:
wxPersistentWindowBase(wxWindow *win) wxPersistentWindowBase(wxWindow *win)
: wxPersistentObject(win) : wxPersistentObject(win)
{ {
#if wxEVENTS_COMPATIBILITY_2_8
win->Connect win->Connect
( (
wxEVT_DESTROY, wxEVT_DESTROY,
@@ -42,6 +43,9 @@ public:
NULL, NULL,
this this
); );
#else // !wxEVENTS_COMPATIBILITY_2_8
win->Bind(wxEVT_DESTROY, &wxPersistentWindowBase::HandleDestroy, this);
#endif // wxEVENTS_COMPATIBILITY_2_8/!wxEVENTS_COMPATIBILITY_2_8
} }
virtual wxString GetName() const virtual wxString GetName() const

View File

@@ -37,7 +37,11 @@ public:
}; };
typedef void (wxEvtHandler::*MyEventFunction)(MyEvent&); typedef void (wxEvtHandler::*MyEventFunction)(MyEvent&);
#if wxEVENTS_COMPATIBILITY_2_8
#define MyEventHandler(func) wxEVENT_HANDLER_CAST(MyEventFunction, func) #define MyEventHandler(func) wxEVENT_HANDLER_CAST(MyEventFunction, func)
#else
#define MyEventHandler(func) &func
#endif
#define EVT_MYEVENT(func) \ #define EVT_MYEVENT(func) \
wx__DECLARE_EVT0(MyEventType, MyEventHandler(func)) wx__DECLARE_EVT0(MyEventType, MyEventHandler(func))
@@ -152,30 +156,26 @@ private:
CPPUNIT_TEST( BuiltinConnect ); CPPUNIT_TEST( BuiltinConnect );
CPPUNIT_TEST( LegacyConnect ); CPPUNIT_TEST( LegacyConnect );
#if !wxEVENTS_COMPATIBILITY_2_8 #if !wxEVENTS_COMPATIBILITY_2_8
CPPUNIT_TEST( ConnectFunction ); CPPUNIT_TEST( BindFunction );
CPPUNIT_TEST( ConnectStaticMethod ); CPPUNIT_TEST( BindStaticMethod );
CPPUNIT_TEST( ConnectFunctor ); CPPUNIT_TEST( BindFunctor );
CPPUNIT_TEST( ConnectMethod ); CPPUNIT_TEST( BindMethod );
CPPUNIT_TEST( ConnectMethodUsingBaseEvent ); CPPUNIT_TEST( BindMethodUsingBaseEvent );
CPPUNIT_TEST( ConnectMethodWithSink ); CPPUNIT_TEST( BindNonHandler );
CPPUNIT_TEST( ConnectNonHandler ); CPPUNIT_TEST( InvalidBind );
CPPUNIT_TEST( StaticConnect );
CPPUNIT_TEST( InvalidConnect );
#endif // !wxEVENTS_COMPATIBILITY_2_8 #endif // !wxEVENTS_COMPATIBILITY_2_8
CPPUNIT_TEST_SUITE_END(); CPPUNIT_TEST_SUITE_END();
void BuiltinConnect(); void BuiltinConnect();
void LegacyConnect(); void LegacyConnect();
#if !wxEVENTS_COMPATIBILITY_2_8 #if !wxEVENTS_COMPATIBILITY_2_8
void ConnectFunction(); void BindFunction();
void ConnectStaticMethod(); void BindStaticMethod();
void ConnectFunctor(); void BindFunctor();
void ConnectMethod(); void BindMethod();
void ConnectMethodUsingBaseEvent(); void BindMethodUsingBaseEvent();
void ConnectMethodWithSink(); void BindNonHandler();
void ConnectNonHandler(); void InvalidBind();
void StaticConnect();
void InvalidConnect();
#endif // !wxEVENTS_COMPATIBILITY_2_8 #endif // !wxEVENTS_COMPATIBILITY_2_8
@@ -207,18 +207,18 @@ void EvtHandlerTestCase::BuiltinConnect()
handler.Disconnect(wxEVT_IDLE, (wxObjectEventFunction)(wxEventFunction)&MyHandler::OnIdle); handler.Disconnect(wxEVT_IDLE, (wxObjectEventFunction)(wxEventFunction)&MyHandler::OnIdle);
#if !wxEVENTS_COMPATIBILITY_2_8 #if !wxEVENTS_COMPATIBILITY_2_8
handler.Connect(wxEVT_IDLE, GlobalOnIdle); handler.Bind(wxEVT_IDLE, GlobalOnIdle);
handler.Disconnect(wxEVT_IDLE, GlobalOnIdle); handler.Unbind(wxEVT_IDLE, GlobalOnIdle);
IdleFunctor f; IdleFunctor f;
handler.Connect(wxEVT_IDLE, f); handler.Bind(wxEVT_IDLE, f);
handler.Disconnect(wxEVT_IDLE, f); handler.Unbind(wxEVT_IDLE, f);
handler.Connect(wxEVT_IDLE, &MyHandler::OnIdle); handler.Bind(wxEVT_IDLE, &MyHandler::OnIdle, &handler);
handler.Disconnect(wxEVT_IDLE, &MyHandler::OnIdle); handler.Unbind(wxEVT_IDLE, &MyHandler::OnIdle, &handler);
handler.Connect(wxEVT_IDLE, &MyHandler::StaticOnIdle); handler.Bind(wxEVT_IDLE, &MyHandler::StaticOnIdle);
handler.Disconnect(wxEVT_IDLE, &MyHandler::StaticOnIdle); handler.Unbind(wxEVT_IDLE, &MyHandler::StaticOnIdle);
#endif // !wxEVENTS_COMPATIBILITY_2_8 #endif // !wxEVENTS_COMPATIBILITY_2_8
} }
@@ -244,152 +244,142 @@ void EvtHandlerTestCase::LegacyConnect()
#if !wxEVENTS_COMPATIBILITY_2_8 #if !wxEVENTS_COMPATIBILITY_2_8
void EvtHandlerTestCase::ConnectFunction() void EvtHandlerTestCase::BindFunction()
{ {
// function tests // function tests
handler.Connect( MyEventType, GlobalOnMyEvent ); handler.Bind( MyEventType, GlobalOnMyEvent );
g_called.Reset(); g_called.Reset();
handler.ProcessEvent(e); handler.ProcessEvent(e);
CPPUNIT_ASSERT( g_called.function ); CPPUNIT_ASSERT( g_called.function );
handler.Disconnect( MyEventType, GlobalOnMyEvent ); handler.Unbind( MyEventType, GlobalOnMyEvent );
g_called.Reset(); g_called.Reset();
handler.ProcessEvent(e); handler.ProcessEvent(e);
CPPUNIT_ASSERT( !g_called.function ); // check that it was disconnected CPPUNIT_ASSERT( !g_called.function ); // check that it was disconnected
handler.Connect( 0, MyEventType, GlobalOnMyEvent ); handler.Bind( MyEventType, GlobalOnMyEvent, 0 );
handler.Disconnect( 0, MyEventType, GlobalOnMyEvent ); handler.Unbind( MyEventType, GlobalOnMyEvent, 0 );
handler.Connect( 0, 0, MyEventType, GlobalOnMyEvent ); handler.Bind( MyEventType, GlobalOnMyEvent, 0, 0 );
handler.Disconnect( 0, 0, MyEventType, GlobalOnMyEvent ); handler.Unbind( MyEventType, GlobalOnMyEvent, 0, 0 );
} }
void EvtHandlerTestCase::ConnectStaticMethod() void EvtHandlerTestCase::BindStaticMethod()
{ {
// static method tests (this is same as functions but still test it just in // static method tests (this is same as functions but still test it just in
// case we hit some strange compiler bugs) // case we hit some strange compiler bugs)
handler.Connect( MyEventType, &MyHandler::StaticOnMyEvent ); handler.Bind( MyEventType, &MyHandler::StaticOnMyEvent );
g_called.Reset(); g_called.Reset();
handler.ProcessEvent(e); handler.ProcessEvent(e);
CPPUNIT_ASSERT( g_called.smethod ); CPPUNIT_ASSERT( g_called.smethod );
handler.Disconnect( MyEventType, &MyHandler::StaticOnMyEvent ); handler.Unbind( MyEventType, &MyHandler::StaticOnMyEvent );
g_called.Reset(); g_called.Reset();
handler.ProcessEvent(e); handler.ProcessEvent(e);
CPPUNIT_ASSERT( !g_called.smethod ); CPPUNIT_ASSERT( !g_called.smethod );
handler.Connect( 0, MyEventType, &MyHandler::StaticOnMyEvent ); handler.Bind( MyEventType, &MyHandler::StaticOnMyEvent, 0 );
handler.Disconnect( 0, MyEventType, &MyHandler::StaticOnMyEvent ); handler.Unbind( MyEventType, &MyHandler::StaticOnMyEvent, 0 );
handler.Connect( 0, 0, MyEventType, &MyHandler::StaticOnMyEvent ); handler.Bind( MyEventType, &MyHandler::StaticOnMyEvent, 0, 0 );
handler.Disconnect( 0, 0, MyEventType, &MyHandler::StaticOnMyEvent ); handler.Unbind( MyEventType, &MyHandler::StaticOnMyEvent, 0, 0 );
} }
void EvtHandlerTestCase::ConnectFunctor() void EvtHandlerTestCase::BindFunctor()
{ {
// generalized functor tests // generalized functor tests
MyFunctor functor; MyFunctor functor;
handler.Connect( MyEventType, functor ); handler.Bind( MyEventType, functor );
g_called.Reset(); g_called.Reset();
handler.ProcessEvent(e); handler.ProcessEvent(e);
CPPUNIT_ASSERT( g_called.functor ); CPPUNIT_ASSERT( g_called.functor );
handler.Disconnect( MyEventType, functor ); handler.Unbind( MyEventType, functor );
g_called.Reset(); g_called.Reset();
handler.ProcessEvent(e); handler.ProcessEvent(e);
CPPUNIT_ASSERT( !g_called.functor ); CPPUNIT_ASSERT( !g_called.functor );
handler.Connect( 0, MyEventType, functor ); handler.Bind( MyEventType, functor, 0 );
handler.Disconnect( 0, MyEventType, functor ); handler.Unbind( MyEventType, functor, 0 );
handler.Connect( 0, 0, MyEventType, functor ); handler.Bind( MyEventType, functor, 0, 0 );
handler.Disconnect( 0, 0, MyEventType, functor ); handler.Unbind( MyEventType, functor, 0, 0 );
} }
void EvtHandlerTestCase::ConnectMethod() void EvtHandlerTestCase::BindMethod()
{ {
// class method tests // class method tests
handler.Connect( MyEventType, &MyHandler::OnMyEvent ); handler.Bind( MyEventType, &MyHandler::OnMyEvent, &handler );
g_called.Reset(); g_called.Reset();
handler.ProcessEvent(e); handler.ProcessEvent(e);
CPPUNIT_ASSERT( g_called.method ); CPPUNIT_ASSERT( g_called.method );
handler.Disconnect( MyEventType, &MyHandler::OnMyEvent ); handler.Unbind( MyEventType, &MyHandler::OnMyEvent, &handler );
g_called.Reset(); g_called.Reset();
handler.ProcessEvent(e); handler.ProcessEvent(e);
CPPUNIT_ASSERT( !g_called.method ); CPPUNIT_ASSERT( !g_called.method );
handler.Connect( 0, MyEventType, &MyHandler::OnMyEvent ); handler.Bind( MyEventType, &MyHandler::OnMyEvent, &handler, 0 );
handler.Disconnect( 0, MyEventType, &MyHandler::OnMyEvent ); handler.Unbind( MyEventType, &MyHandler::OnMyEvent, &handler, 0 );
handler.Connect( 0, 0, MyEventType, &MyHandler::OnMyEvent ); handler.Bind( MyEventType, &MyHandler::OnMyEvent, &handler, 0, 0 );
handler.Disconnect( 0, 0, MyEventType, &MyHandler::OnMyEvent ); handler.Unbind( MyEventType, &MyHandler::OnMyEvent, &handler, 0, 0 );
} }
void EvtHandlerTestCase::ConnectMethodUsingBaseEvent() void EvtHandlerTestCase::BindMethodUsingBaseEvent()
{ {
// test connecting a method taking just wxEvent and not MyEvent: this // test connecting a method taking just wxEvent and not MyEvent: this
// should work too if we don't need any MyEvent-specific information in the // should work too if we don't need any MyEvent-specific information in the
// handler // handler
handler.Connect( MyEventType, &MyHandler::OnEvent ); handler.Bind( MyEventType, &MyHandler::OnEvent, &handler );
g_called.Reset(); g_called.Reset();
handler.ProcessEvent(e); handler.ProcessEvent(e);
CPPUNIT_ASSERT( g_called.method ); CPPUNIT_ASSERT( g_called.method );
handler.Disconnect( MyEventType, &MyHandler::OnEvent ); handler.Unbind( MyEventType, &MyHandler::OnEvent, &handler );
g_called.Reset(); g_called.Reset();
handler.ProcessEvent(e); handler.ProcessEvent(e);
CPPUNIT_ASSERT( !g_called.method ); CPPUNIT_ASSERT( !g_called.method );
handler.Connect( 0, MyEventType, &MyHandler::OnEvent ); handler.Bind( MyEventType, &MyHandler::OnEvent, &handler, 0 );
handler.Disconnect( 0, MyEventType, &MyHandler::OnEvent ); handler.Unbind( MyEventType, &MyHandler::OnEvent, &handler, 0 );
handler.Connect( 0, 0, MyEventType, &MyHandler::OnEvent ); handler.Bind( MyEventType, &MyHandler::OnEvent, &handler, 0, 0 );
handler.Disconnect( 0, 0, MyEventType, &MyHandler::OnEvent ); handler.Unbind( MyEventType, &MyHandler::OnEvent, &handler, 0, 0 );
} }
void EvtHandlerTestCase::ConnectMethodWithSink()
{
handler.Connect( MyEventType, &MyHandler::OnMyEvent, NULL, &handler );
handler.Connect( 0, MyEventType, &MyHandler::OnMyEvent, NULL, &handler );
handler.Connect( 0, 0, MyEventType, &MyHandler::OnMyEvent, NULL, &handler );
handler.Disconnect( MyEventType, &MyHandler::OnMyEvent, NULL, &handler ); void EvtHandlerTestCase::BindNonHandler()
handler.Disconnect( 0, MyEventType, &MyHandler::OnMyEvent, NULL, &handler );
handler.Disconnect( 0, 0, MyEventType, &MyHandler::OnMyEvent, NULL, &handler );
}
void EvtHandlerTestCase::ConnectNonHandler()
{ {
// class method tests for class not derived from wxEvtHandler // class method tests for class not derived from wxEvtHandler
MySink sink; MySink sink;
handler.Connect( MyEventType, &MySink::OnMyEvent, NULL, &sink ); handler.Bind( MyEventType, &MySink::OnMyEvent, &sink );
g_called.Reset(); g_called.Reset();
handler.ProcessEvent(e); handler.ProcessEvent(e);
CPPUNIT_ASSERT( g_called.method ); CPPUNIT_ASSERT( g_called.method );
handler.Disconnect( MyEventType, &MySink::OnMyEvent, NULL, &sink ); handler.Unbind( MyEventType, &MySink::OnMyEvent, &sink );
g_called.Reset(); g_called.Reset();
handler.ProcessEvent(e); handler.ProcessEvent(e);
CPPUNIT_ASSERT( !g_called.method ); CPPUNIT_ASSERT( !g_called.method );
} }
void EvtHandlerTestCase::StaticConnect() void EvtHandlerTestCase::InvalidBind()
{
wxEvtHandler::Connect( &handler, MyEventType, &MyHandler::OnMyEvent, NULL, &handler );
wxEvtHandler::Connect( &handler, 0, MyEventType, &MyHandler::OnMyEvent, NULL, &handler );
wxEvtHandler::Connect( &handler, 0, 0, MyEventType, &MyHandler::OnMyEvent, NULL, &handler );
wxEvtHandler::Disconnect( &handler, MyEventType, &MyHandler::OnMyEvent, NULL, &handler );
wxEvtHandler::Disconnect( &handler, 0, MyEventType, &MyHandler::OnMyEvent, NULL, &handler );
wxEvtHandler::Disconnect( &handler, 0, 0, MyEventType, &MyHandler::OnMyEvent, NULL, &handler );
}
void EvtHandlerTestCase::InvalidConnect()
{ {
// these calls shouldn't compile but we unfortunately can't check this // these calls shouldn't compile but we unfortunately can't check this
// automatically, you need to uncomment them manually and test that // automatically, you need to uncomment them manually and test that
// compilation does indeed fail // compilation does indeed fail
//handler.Connect(MyEventType, GlobalOnAnotherEvent);
//IdleFunctor f; handler.Connect(MyEventType, f); //handler.Bind(MyEventType, GlobalOnAnotherEvent);
//handler.Connect(MyEventType, &MyHandler::StaticOnAnotherEvent); //IdleFunctor f; handler.Bind(MyEventType, f);
//handler.Connect(MyEventType, &MyHandler::OnAnotherEvent); //handler.Bind(MyEventType, &MyHandler::StaticOnAnotherEvent);
//handler.Bind(MyEventType, &MyHandler::OnAnotherEvent, &handler);
// 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
//MySink mySink;
//MyHandler myHandler;
//myHandler.Bind( MyEventType, &MyHandler::OnMyEvent, &mySink );
} }
#endif // !wxEVENTS_COMPATIBILITY_2_8 #endif // !wxEVENTS_COMPATIBILITY_2_8