From 890d70ebeaf39ee13012d22751d64d8de070275c Mon Sep 17 00:00:00 2001 From: Vadim Zeitlin Date: Sat, 2 May 2009 12:52:54 +0000 Subject: [PATCH] improvements to wxEventFunctor classes; use wxHAS_EVENT_BIND instead of wxEVENTS_COMPATIBILITY_2_8 (see #10653) git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@60470 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775 --- configure.in | 7 - include/wx/event.h | 372 ++++++++++++++++++++++++----------- include/wx/features.h | 8 + include/wx/motif/setup0.h | 13 -- include/wx/msw/chkconf.h | 5 +- include/wx/msw/setup0.h | 13 -- include/wx/msw/wince/setup.h | 13 -- include/wx/os2/setup0.h | 13 -- include/wx/osx/setup0.h | 13 -- include/wx/palmos/setup0.h | 13 -- include/wx/setup_inc.h | 13 -- include/wx/univ/setup0.h | 13 -- samples/event/event.cpp | 16 +- setup.h.in | 2 - src/common/appbase.cpp | 2 +- src/common/event.cpp | 22 +-- tests/events/evthandler.cpp | 50 ++++- 17 files changed, 322 insertions(+), 266 deletions(-) diff --git a/configure.in b/configure.in index 7cffd8152f..61cf02e185 100644 --- a/configure.in +++ b/configure.in @@ -682,13 +682,6 @@ WX_ARG_ENABLE_PARAM(universal_binary, [[ --enable-universal_binary create Mac WX_ARG_ENABLE(compat26, [ --enable-compat26 enable wxWidgets 2.6 compatibility], WXWIN_COMPATIBILITY_2_6) WX_ARG_DISABLE(compat28, [ --disable-compat28 disable wxWidgets 2.8 compatibility], WXWIN_COMPATIBILITY_2_8) -dnl currently we don't provide a switch for disabling it as it shouldn't be -dnl necessary to do it unless the compiler doesn't support the new events and -dnl this should be tested for by configure itself (but also isn't done yet -dnl because there are no known examples of such compilers among the currently -dnl supported ones) -AC_DEFINE(wxEVENTS_COMPATIBILITY_2_8, 0) - WX_ARG_DISABLE(rpath, [ --disable-rpath disable use of rpath for uninstalled builds], wxUSE_RPATH) WX_ARG_ENABLE(objc_uniquifying,[ --enable-objc_uniquifying enable Objective-C class name uniquifying], wxUSE_OBJC_UNIQUIFYING) diff --git a/include/wx/event.h b/include/wx/event.h index d3bcc5b275..b116e3e8c6 100644 --- a/include/wx/event.h +++ b/include/wx/event.h @@ -27,7 +27,7 @@ #include "wx/thread.h" #include "wx/tracker.h" -#if !wxEVENTS_COMPATIBILITY_2_8 +#ifdef wxHAS_EVENT_BIND #include "wx/meta/convertible.h" #endif @@ -101,7 +101,7 @@ extern WXDLLIMPEXP_BASE wxEventType wxNewEventType(); // New macros to create templatized event types: -#if wxEVENTS_COMPATIBILITY_2_8 +#ifndef wxHAS_EVENT_BIND // Define/Declare a wxEventType-based event type: @@ -126,7 +126,8 @@ extern WXDLLIMPEXP_BASE wxEventType wxNewEventType(); #define wxDECLARE_EVENT( name, type ) \ wxDECLARE_EXPORTED_EVENT( wxEMPTY_PARAMETER_VALUE, name, type ) -#else +#else // wxHAS_EVENT_BIND + // Define/Declare a templatized event type with the corresponding event as // a nested typedef: @@ -151,16 +152,15 @@ extern WXDLLIMPEXP_BASE wxEventType wxNewEventType(); #define wxDECLARE_EVENT( name, type ) \ wxDECLARE_EXPORTED_EVENT( wxEMPTY_PARAMETER_VALUE, name, type ) -#endif +#endif // wxHAS_EVENT_BIND // Try to cast the given event handler to the correct handler type: #define wxEVENT_HANDLER_CAST( functype, func ) \ ( wxObjectEventFunction )( wxEventFunction )wxStaticCastEvent( functype, &func ) -// Template which associates the correct event object with the event type -#if !wxEVENTS_COMPATIBILITY_2_8 +#ifdef wxHAS_EVENT_BIND // The tag is a type associated to the event type (which is an integer itself, // in spite of its name) value. It exists in order to be used as a template @@ -184,7 +184,7 @@ private: wxEventType m_type; }; -#endif // !wxEVENTS_COMPATIBILITY_2_8 +#endif // wxHAS_EVENT_BIND // These are needed for the functor definitions typedef void (wxEvtHandler::*wxEventFunction)(wxEvent&); @@ -199,6 +199,15 @@ typedef void (wxEvtHandler::*wxEventFunction)(wxEvent&); typedef wxEventFunction wxObjectEventFunction; +// wxEventFunctorClassInfo is used as a unique identifier for wxEventFunctor- +// derived classes; it is more light weight than wxClassInfo and can be used in +// template classes +typedef void (*wxEventFunctorClassInfo)(); + +// this macro must be used in wxEventFunctor-derived classes +#define wxDEFINE_EVENT_FUNCTOR_CLASS_INFO( classInfoName ) \ + static void classInfoName() {} + // The event functor which is stored in the static and dynamic event tables: class WXDLLIMPEXP_BASE wxEventFunctor { @@ -209,54 +218,74 @@ public: virtual void operator()(wxEvtHandler *, wxEvent&) = 0; // this function tests whether this functor is matched, for the purpose of - // finding it in an event table in Disconnect(), by the given func - virtual bool Matches(const wxEventFunctor& func) const = 0; + // finding it in an event table in Unbind(), by the given functor: + virtual bool IsMatching(const wxEventFunctor& functor) const = 0; - // these functions are used for functors comparison in Matches() - virtual void *GetHandler() const { return GetEvtHandler(); } - virtual wxEventFunction GetMethod() const { return NULL; } + // Test whether the given class info is the same as from this functor. This + // allows us in IsMatching to safely downcast the given wxEventFunctor without + // the usage of dynamic_cast<>(). + virtual bool IsSameClass(wxEventFunctorClassInfo classInfo) const = 0; - // this one is also used elsewhere in the code and should be overridden to - // return non-NULL if we are indeed associated with an wxEvtHandler - virtual wxEvtHandler *GetEvtHandler() const { return NULL; } + // If the functor holds an wxEvtHandler, then get access to it and track + // its lifetime with wxEventConnectionRef: + virtual wxEvtHandler *GetEvtHandler() const + { return NULL; } + + // This is only used to maintain backward compatibility in + // wxAppConsoleBase::CallEventHandler and ensures that an overwritten + // wxAppConsoleBase::HandleEvent is still called for functors which hold an + // wxEventFunction: + virtual wxEventFunction GetEvtMethod() const + { return NULL; } }; -// A plain method functor: notice that it is used even with the new events as -// it is reused as a specialization of wxEventFunctorMethod for legacy untyped -// event types +// A plain method functor for the untyped legacy event types: class WXDLLIMPEXP_BASE wxObjectEventFunctor : public wxEventFunctor { public: wxObjectEventFunctor(wxObjectEventFunction method, wxEvtHandler *handler) + : m_handler( handler ), m_method( method ) + { } + + virtual void operator()(wxEvtHandler *handler, wxEvent& event) { - m_handler = handler; - m_method = method; - } + wxEvtHandler * const realHandler = m_handler ? m_handler : handler; - virtual void operator()(wxEvtHandler *handler, wxEvent& event); + (realHandler->*m_method)(event); + } - virtual bool Matches(const wxEventFunctor& func) const + virtual bool IsMatching(const wxEventFunctor& functor) const { - void * const handler = func.GetHandler(); - if ( handler && GetHandler() != handler ) - return false; + if ( functor.IsSameClass( sm_classInfo )) + { + const wxObjectEventFunctor &other = + static_cast< const wxObjectEventFunctor & >( functor ); - const wxEventFunction method = GetMethod(); + // FIXME-VC6: amazing but true: replacing "method == NULL" here + // with "!method" makes VC6 crash with an ICE in DLL build (only!) - // FIXME-VC6: amazing but true: replacing "method == NULL" here with - // "!method" makes VC6 crash with an ICE in DLL build (only!) - return method == NULL || GetMethod() == method; + return ( m_method == other.m_method || other.m_method == NULL ) && + ( m_handler == other.m_handler || other.m_handler == NULL ); + } + else + return false; } - virtual wxEvtHandler *GetEvtHandler() const { return m_handler; } - virtual wxEventFunction GetMethod() const { return m_method; } + virtual bool IsSameClass( wxEventFunctorClassInfo otherClassInfo ) const + { return sm_classInfo == otherClassInfo; } + + virtual wxEvtHandler *GetEvtHandler() const + { return m_handler; } + + virtual wxEventFunction GetEvtMethod() const + { return m_method; } private: wxEvtHandler *m_handler; wxEventFunction m_method; -}; -#if wxEVENTS_COMPATIBILITY_2_8 + wxDEFINE_EVENT_FUNCTOR_CLASS_INFO( sm_classInfo ); +}; // Create a functor for the legacy events: used by Connect() inline wxObjectEventFunctor * @@ -283,40 +312,7 @@ wxMakeEventFunctor(const wxEventType& WXUNUSED(evtType), return wxObjectEventFunctor(method, handler); } -#else // !wxEVENTS_COMPATIBILITY_2_8 - -// functor forwarding the event to anything callable (function, static method, -// generalized functor...) -template -class wxEventFunctorFunction : public wxEventFunctor -{ -public: - typedef typename EventTag::EventClass EventArg; - - wxEventFunctorFunction(Functor handler) - { - m_handler = handler; - } - - virtual void operator()(wxEvtHandler *WXUNUSED(handler), wxEvent& event) - { - m_handler(static_cast(event)); - } - - virtual bool Matches(const wxEventFunctor& WXUNUSED(func)) const - { - // we have no way to compare arbitrary functors so just consider them - // to be equal: this means that disconnecting a functor will always - // find the last functor connected which in turn implies that it's - // probably a bad idea to connect more than one functor if you plan to - // disconnect them but this limitation doesn't seem very important in - // practice - return true; - } - -private: - Functor m_handler; -}; +#ifdef wxHAS_EVENT_BIND namespace wxPrivate { @@ -356,7 +352,7 @@ struct HandlerImpl { return static_cast(p); } static wxEvtHandler *ConvertToEvtHandler(T *p) { return p; } - static wxEventFunction ConvertToEvtFunction(void (T::*f)(A&)) + static wxEventFunction ConvertToEvtMethod(void (T::*f)(A&)) { return static_cast( reinterpret_cast(f)); } }; @@ -371,7 +367,7 @@ struct HandlerImpl { return NULL; } static wxEvtHandler *ConvertToEvtHandler(T *) { return NULL; } - static wxEventFunction ConvertToEvtFunction(void (T::*)(A&)) + static wxEventFunction ConvertToEvtMethod(void (T::*)(A&)) { return NULL; } }; @@ -406,6 +402,7 @@ public: wxEventFunctorMethod(void (Class::*method)(EventArg&), EventHandler *handler) + : m_handler( handler ), m_method( method ) { wxASSERT_MSG( handler || this->IsEvtHandler(), "handlers defined in non-wxEvtHandler-derived classes " @@ -415,9 +412,6 @@ public: // you're trying to use is not compatible with (i.e. is not the same as // or a base class of) the real event class used for this event type CheckHandlerArgument(static_cast(NULL)); - - m_handler = handler; - m_method = method; } virtual void operator()(wxEvtHandler *handler, wxEvent& event) @@ -437,60 +431,179 @@ public: (realHandler->*m_method)(static_cast(event)); } - virtual bool Matches(const wxEventFunctor& func) const + virtual bool IsMatching(const wxEventFunctor& functor) const { - void * const handler = func.GetHandler(); - if ( handler && GetHandler() != handler ) + if ( !functor.IsSameClass(sm_classInfo) ) return false; - const wxEventFunction method = GetMethod(); - return !method || GetMethod() == method; + typedef wxEventFunctorMethod + ThisFunctor; + + // the cast is valid because IsSameClass() returned true above + const ThisFunctor& other = static_cast(functor); + + return (m_method == other.m_method || other.m_method == NULL) && + (m_handler == other.m_handler || other.m_handler == NULL); } - virtual void *GetHandler() const + virtual bool IsSameClass( wxEventFunctorClassInfo otherClassInfo ) const + { return sm_classInfo == otherClassInfo; } + + virtual wxEvtHandler *GetEvtHandler() const + { return this->ConvertToEvtHandler(m_handler); } + + virtual wxEventFunction GetEvtMethod() const + { return this->ConvertToEvtMethod(m_method); } + +private: + EventHandler *m_handler; + void (Class::*m_method)(EventArg&); + + wxDEFINE_EVENT_FUNCTOR_CLASS_INFO( sm_classInfo ); +}; + + +// functor forwarding the event to function (function, static method) +template +class wxEventFunctorFunction : public wxEventFunctor +{ +private: + static void CheckHandlerArgument(EventArg *) { } + +public: + // the event class associated with the given event tag + typedef typename wxPrivate::EventClassOf::type EventClass; + + wxEventFunctorFunction( void ( *handler )( EventArg & )) + : m_handler( handler ) { - return m_handler; + // if you get an error here it means that the signature of the handler + // you're trying to use is not compatible with (i.e. is not the same as + // or a base class of) the real event class used for this event type + CheckHandlerArgument(static_cast(NULL)); } - virtual wxEventFunction GetMethod() const + virtual void operator()(wxEvtHandler *WXUNUSED(handler), wxEvent& event) { - return this->ConvertToEvtFunction(m_method); + // If you get an error here like "must use .* or ->* to call + // pointer-to-member function" then you probably tried to call + // Bind/Unbind with a method pointer but without a handler pointer or + // NULL as a handler e.g.: + // Unbind( wxEVT_XXX, &EventHandler::method ); + // or + // Unbind( wxEVT_XXX, &EventHandler::method, NULL ) + m_handler(static_cast(event)); } - virtual wxEvtHandler *GetEvtHandler() const + virtual bool IsMatching(const wxEventFunctor &functor) const { - return this->ConvertToEvtHandler(m_handler); + if ( !functor.IsSameClass(sm_classInfo) ) + return false; + + typedef wxEventFunctorFunction ThisFunctor; + + const ThisFunctor& other = static_cast( functor ); + + return m_handler == other.m_handler; } + virtual bool IsSameClass( wxEventFunctorClassInfo otherClassInfo ) const + { return sm_classInfo == otherClassInfo; } + private: - EventHandler *m_handler; - void (Class::*m_method)(EventArg&); + void (*m_handler)(EventArg&); + + wxDEFINE_EVENT_FUNCTOR_CLASS_INFO( sm_classInfo ); }; +template +class wxEventFunctorFunctor : public wxEventFunctor +{ +public: + typedef typename EventTag::EventClass EventArg; + + wxEventFunctorFunctor(Functor& handler) + : m_handler(handler), m_handlerAddr(&handler) + { } + + virtual void operator()(wxEvtHandler *WXUNUSED(handler), wxEvent& event) + { + // If you get an error here like "must use '.*' or '->*' to call + // pointer-to-member function" then you probably tried to call + // Bind/Unbind with a method pointer but without a handler pointer or + // NULL as a handler e.g.: + // Unbind( wxEVT_XXX, &EventHandler::method ); + // or + // Unbind( wxEVT_XXX, &EventHandler::method, NULL ) + m_handler(static_cast(event)); + } + + virtual bool IsMatching(const wxEventFunctor &functor) const + { + if ( !functor.IsSameClass(sm_classInfo) ) + return false; + + typedef wxEventFunctorFunctor FunctorThis; + + const FunctorThis& other = static_cast(functor); + + // The only reliable/portable way to compare two functors is by + // identity: + return m_handlerAddr == other.m_handlerAddr; + } + + virtual bool IsSameClass( wxEventFunctorClassInfo otherClassInfo ) const + { return sm_classInfo == otherClassInfo; } + +private: + // Store a copy of the functor to prevent using/calling an already + // destroyed instance: + Functor m_handler; + + // Use the address of the original functor for comparison in IsMatching: + const void *m_handlerAddr; + + wxDEFINE_EVENT_FUNCTOR_CLASS_INFO( sm_classInfo ); +}; + // Create functors for the templatized events, either allocated on the heap for // wxNewXXX() variants (this is needed in wxEvtHandler::Bind<>() to store them -// in dynamic event table) or just by returning them as temporary objects (this +// in dynamic event table) or just by returning them as a temporary objects (this // is enough for Unbind<>() and we avoid unnecessary heap allocation like this). -// Create functors wrapping other functors (including functions): -template -inline wxEventFunctorFunction * -wxNewEventFunctor(const EventTag&, Functor func) +// Create functors wrapping functions: +template +inline wxEventFunctorFunction * +wxNewEventFunctor(const EventTag&, void (*func)(EventArg &)) { - return new wxEventFunctorFunction(func); + return new wxEventFunctorFunction(func); } +template +inline wxEventFunctorFunction +wxMakeEventFunctor(const EventTag&, void (*func)(EventArg &)) +{ + return wxEventFunctorFunction(func); +} + +// Create functors wrapping other functors: template -inline wxEventFunctorFunction -wxMakeEventFunctor(const EventTag&, Functor func) +inline wxEventFunctorFunctor * +wxNewEventFunctor(const EventTag&, Functor &func) { - return wxEventFunctorFunction(func); + return new wxEventFunctorFunctor(func); } +template +inline wxEventFunctorFunctor +wxMakeEventFunctor(const EventTag&, Functor &func) +{ + return wxEventFunctorFunctor(func); +} -// Create functors for methods: +// Create functors wrapping methods: template inline wxEventFunctorMethod * @@ -524,7 +637,7 @@ wxNewEventTableFunctor(const EventTag&, void (Class::*method)(EventArg&)) method, NULL); } -#endif // !wxEVENTS_COMPATIBILITY_2_8 +#endif // wxHAS_EVENT_BIND // many, but not all, standard event types @@ -2871,7 +2984,7 @@ public: wxObject *userData = NULL, wxEvtHandler *eventSink = NULL) { - DoConnect(winid, lastId, eventType, + DoBind(winid, lastId, eventType, wxNewEventFunctor(eventType, func, eventSink), userData); } @@ -2898,7 +3011,7 @@ public: wxObject *userData = NULL, wxEvtHandler *eventSink = NULL) { - return DoDisconnect(winid, lastId, eventType, + return DoUnbind(winid, lastId, eventType, wxMakeEventFunctor(eventType, func, eventSink), userData ); } @@ -2916,16 +3029,42 @@ public: wxEvtHandler *eventSink = NULL) { return Disconnect(wxID_ANY, eventType, func, userData, eventSink); } -#if !wxEVENTS_COMPATIBILITY_2_8 - // Bind arbitrary functor (including just a function) to an event: +#ifdef wxHAS_EVENT_BIND + // Bind functions to an event: + template + void Bind(const EventTag& eventType, + void (*function)(EventArg &), + int winid = wxID_ANY, + int lastId = wxID_ANY, + wxObject *userData = NULL) + { + DoBind(winid, lastId, eventType, + wxNewEventFunctor(eventType, function), + userData); + } + + + template + bool Unbind(const EventTag& eventType, + void (*function)(EventArg &), + int winid = wxID_ANY, + int lastId = wxID_ANY, + wxObject *userData = NULL) + { + return DoUnbind(winid, lastId, eventType, + wxMakeEventFunctor(eventType, function), + userData); + } + + // Bind functors to an event: template void Bind(const EventTag& eventType, - Functor functor, + Functor &functor, int winid = wxID_ANY, int lastId = wxID_ANY, wxObject *userData = NULL) { - DoConnect(winid, lastId, eventType, + DoBind(winid, lastId, eventType, wxNewEventFunctor(eventType, functor), userData); } @@ -2933,12 +3072,12 @@ public: template bool Unbind(const EventTag& eventType, - Functor functor, + Functor &functor, int winid = wxID_ANY, int lastId = wxID_ANY, wxObject *userData = NULL) { - return DoDisconnect(winid, lastId, eventType, + return DoUnbind(winid, lastId, eventType, wxMakeEventFunctor(eventType, functor), userData); } @@ -2955,7 +3094,7 @@ public: int lastId = wxID_ANY, wxObject *userData = NULL) { - DoConnect(winid, lastId, eventType, + DoBind(winid, lastId, eventType, wxNewEventFunctor(eventType, method, handler), userData); } @@ -2968,11 +3107,11 @@ public: int lastId = wxID_ANY, wxObject *userData = NULL ) { - return DoDisconnect(winid, lastId, eventType, + return DoUnbind(winid, lastId, eventType, wxMakeEventFunctor(eventType, method, handler), userData); } -#endif // !wxEVENTS_COMPATIBILITY_2_8 +#endif // wxHAS_EVENT_BIND wxList* GetDynamicEventTable() const { return m_dynamicEvents ; } @@ -3014,13 +3153,13 @@ public: private: - void DoConnect(int winid, + void DoBind(int winid, int lastId, wxEventType eventType, wxEventFunctor *func, wxObject* userData = NULL); - bool DoDisconnect(int winid, + bool DoUnbind(int winid, int lastId, wxEventType eventType, const wxEventFunctor& func, @@ -3155,13 +3294,6 @@ private: wxDECLARE_NO_ASSIGN_CLASS(wxEventConnectionRef); }; -inline void wxObjectEventFunctor::operator()(wxEvtHandler *handler, wxEvent& event) -{ - wxEvtHandler * const realHandler = m_handler ? m_handler : handler; - - (realHandler->*m_method)(event); -} - // Post a message to the given event handler which will be processed during the // next event loop iteration. // @@ -3771,17 +3903,17 @@ typedef void (wxEvtHandler::*wxClipboardTextEventFunction)(wxClipboardTextEvent& // (and not in a private header) because the base class must be visible from // other public headers, please do NOT use this in your code, it will be // removed from future wx versions without warning. -#if wxEVENTS_COMPATIBILITY_2_8 +#ifndef wxHAS_EVENT_BIND #define wxBIND_OR_CONNECT_HACK_BASE_CLASS public wxEvtHandler, #define wxBIND_OR_CONNECT_HACK_ONLY_BASE_CLASS : public wxEvtHandler #define wxBIND_OR_CONNECT_HACK(w, evt, handler, func, obj) \ win->Connect(evt, handler(func), NULL, obj) -#else // wxEVENTS_COMPATIBILITY_2_8 +#else // wxHAS_EVENT_BIND #define wxBIND_OR_CONNECT_HACK_BASE_CLASS #define wxBIND_OR_CONNECT_HACK_ONLY_BASE_CLASS #define wxBIND_OR_CONNECT_HACK(w, evt, handler, func, obj) \ win->Bind(evt, &func, obj) -#endif // wxEVENTS_COMPATIBILITY_2_8/!wxEVENTS_COMPATIBILITY_2_8 +#endif // wxHAS_EVENT_BIND #if wxUSE_GUI diff --git a/include/wx/features.h b/include/wx/features.h index 22276fae0e..ed27473c6f 100644 --- a/include/wx/features.h +++ b/include/wx/features.h @@ -99,5 +99,13 @@ #define wxHAVE_RAW_BITMAP #endif +/* + If this is defined, wxEvtHandler::Bind<>() is available (not all compilers + have the required template support for this and in particular under Windows + where only g++ and MSVC >= 7 currently support it, for the others it will be + undefined in wx/chkconf.h). + */ +#define wxHAS_EVENT_BIND + #endif /* _WX_FEATURES_H_ */ diff --git a/include/wx/motif/setup0.h b/include/wx/motif/setup0.h index f8ec92283a..451b18c538 100644 --- a/include/wx/motif/setup0.h +++ b/include/wx/motif/setup0.h @@ -47,19 +47,6 @@ // Recommended setting: 0 (please update your code) #define WXWIN_COMPATIBILITY_2_8 1 -// Use the 2.8-compatible events and Connect(): this is set to 0 by default as -// the new events bring significant benefits in compile-time safety and -// flexibility but can be disabled to somewhat reduce the compilation time and, -// especially, to still allow building if the compiler template support is too -// bad to compile the new code. -// -// Default is 0 but this is set to 1 automatically in wx/chkconf.h for the -// compilers which can't build the new code (currently only g++ and MSVC >= 8 -// can) -// -// Recommended setting: 0 -#define wxEVENTS_COMPATIBILITY_2_8 0 - // MSW-only: Set to 0 for accurate dialog units, else 1 for old behaviour when // default system font is used for wxWindow::GetCharWidth/Height() instead of // the current font. diff --git a/include/wx/msw/chkconf.h b/include/wx/msw/chkconf.h index f855d59ab5..db029d3d0e 100644 --- a/include/wx/msw/chkconf.h +++ b/include/wx/msw/chkconf.h @@ -415,10 +415,9 @@ Currently only recent MSVC compilers can build the new events code under Windows. */ -#if !wxEVENTS_COMPATIBILITY_2_8 +#ifdef wxHAS_EVENT_BIND # if !wxCHECK_VISUALC_VERSION(7) -# undef wxEVENTS_COMPATIBILITY_2_8 -# define wxEVENTS_COMPATIBILITY_2_8 1 +# undef wxHAS_EVENT_BIND # endif #endif diff --git a/include/wx/msw/setup0.h b/include/wx/msw/setup0.h index a598891110..a3471b7dc3 100644 --- a/include/wx/msw/setup0.h +++ b/include/wx/msw/setup0.h @@ -47,19 +47,6 @@ // Recommended setting: 0 (please update your code) #define WXWIN_COMPATIBILITY_2_8 1 -// Use the 2.8-compatible events and Connect(): this is set to 0 by default as -// the new events bring significant benefits in compile-time safety and -// flexibility but can be disabled to somewhat reduce the compilation time and, -// especially, to still allow building if the compiler template support is too -// bad to compile the new code. -// -// Default is 0 but this is set to 1 automatically in wx/chkconf.h for the -// compilers which can't build the new code (currently only g++ and MSVC >= 8 -// can) -// -// Recommended setting: 0 -#define wxEVENTS_COMPATIBILITY_2_8 0 - // MSW-only: Set to 0 for accurate dialog units, else 1 for old behaviour when // default system font is used for wxWindow::GetCharWidth/Height() instead of // the current font. diff --git a/include/wx/msw/wince/setup.h b/include/wx/msw/wince/setup.h index 9ff4a0dccf..300eecc4e9 100644 --- a/include/wx/msw/wince/setup.h +++ b/include/wx/msw/wince/setup.h @@ -47,19 +47,6 @@ // Recommended setting: 0 (please update your code) #define WXWIN_COMPATIBILITY_2_8 1 -// Use the 2.8-compatible events and Connect(): this is set to 0 by default as -// the new events bring significant benefits in compile-time safety and -// flexibility but can be disabled to somewhat reduce the compilation time and, -// especially, to still allow building if the compiler template support is too -// bad to compile the new code. -// -// Default is 0 but this is set to 1 automatically in wx/chkconf.h for the -// compilers which can't build the new code (currently only g++ and MSVC >= 8 -// can) -// -// Recommended setting: 0 -#define wxEVENTS_COMPATIBILITY_2_8 0 - // MSW-only: Set to 0 for accurate dialog units, else 1 for old behaviour when // default system font is used for wxWindow::GetCharWidth/Height() instead of // the current font. diff --git a/include/wx/os2/setup0.h b/include/wx/os2/setup0.h index 2eebe1a1bb..04b27f059d 100644 --- a/include/wx/os2/setup0.h +++ b/include/wx/os2/setup0.h @@ -47,19 +47,6 @@ // Recommended setting: 0 (please update your code) #define WXWIN_COMPATIBILITY_2_8 1 -// Use the 2.8-compatible events and Connect(): this is set to 0 by default as -// the new events bring significant benefits in compile-time safety and -// flexibility but can be disabled to somewhat reduce the compilation time and, -// especially, to still allow building if the compiler template support is too -// bad to compile the new code. -// -// Default is 0 but this is set to 1 automatically in wx/chkconf.h for the -// compilers which can't build the new code (currently only g++ and MSVC >= 8 -// can) -// -// Recommended setting: 0 -#define wxEVENTS_COMPATIBILITY_2_8 0 - // MSW-only: Set to 0 for accurate dialog units, else 1 for old behaviour when // default system font is used for wxWindow::GetCharWidth/Height() instead of // the current font. diff --git a/include/wx/osx/setup0.h b/include/wx/osx/setup0.h index d1a4b07b59..ccf753d9fd 100644 --- a/include/wx/osx/setup0.h +++ b/include/wx/osx/setup0.h @@ -48,19 +48,6 @@ // Recommended setting: 0 (please update your code) #define WXWIN_COMPATIBILITY_2_8 1 -// Use the 2.8-compatible events and Connect(): this is set to 0 by default as -// the new events bring significant benefits in compile-time safety and -// flexibility but can be disabled to somewhat reduce the compilation time and, -// especially, to still allow building if the compiler template support is too -// bad to compile the new code. -// -// Default is 0 but this is set to 1 automatically in wx/chkconf.h for the -// compilers which can't build the new code (currently only g++ and MSVC >= 8 -// can) -// -// Recommended setting: 0 -#define wxEVENTS_COMPATIBILITY_2_8 0 - // MSW-only: Set to 0 for accurate dialog units, else 1 for old behaviour when // default system font is used for wxWindow::GetCharWidth/Height() instead of // the current font. diff --git a/include/wx/palmos/setup0.h b/include/wx/palmos/setup0.h index f63d06e9df..04917f436f 100644 --- a/include/wx/palmos/setup0.h +++ b/include/wx/palmos/setup0.h @@ -47,19 +47,6 @@ // Recommended setting: 0 (please update your code) #define WXWIN_COMPATIBILITY_2_8 1 -// Use the 2.8-compatible events and Connect(): this is set to 0 by default as -// the new events bring significant benefits in compile-time safety and -// flexibility but can be disabled to somewhat reduce the compilation time and, -// especially, to still allow building if the compiler template support is too -// bad to compile the new code. -// -// Default is 0 but this is set to 1 automatically in wx/chkconf.h for the -// compilers which can't build the new code (currently only g++ and MSVC >= 8 -// can) -// -// Recommended setting: 0 -#define wxEVENTS_COMPATIBILITY_2_8 0 - // MSW-only: Set to 0 for accurate dialog units, else 1 for old behaviour when // default system font is used for wxWindow::GetCharWidth/Height() instead of // the current font. diff --git a/include/wx/setup_inc.h b/include/wx/setup_inc.h index 1112262abc..4f21e8a492 100644 --- a/include/wx/setup_inc.h +++ b/include/wx/setup_inc.h @@ -43,19 +43,6 @@ // Recommended setting: 0 (please update your code) #define WXWIN_COMPATIBILITY_2_8 1 -// Use the 2.8-compatible events and Connect(): this is set to 0 by default as -// the new events bring significant benefits in compile-time safety and -// flexibility but can be disabled to somewhat reduce the compilation time and, -// especially, to still allow building if the compiler template support is too -// bad to compile the new code. -// -// Default is 0 but this is set to 1 automatically in wx/chkconf.h for the -// compilers which can't build the new code (currently only g++ and MSVC >= 8 -// can) -// -// Recommended setting: 0 -#define wxEVENTS_COMPATIBILITY_2_8 0 - // MSW-only: Set to 0 for accurate dialog units, else 1 for old behaviour when // default system font is used for wxWindow::GetCharWidth/Height() instead of // the current font. diff --git a/include/wx/univ/setup0.h b/include/wx/univ/setup0.h index e82d8e4c04..3e8f5754a2 100644 --- a/include/wx/univ/setup0.h +++ b/include/wx/univ/setup0.h @@ -46,19 +46,6 @@ // Recommended setting: 0 (please update your code) #define WXWIN_COMPATIBILITY_2_8 1 -// Use the 2.8-compatible events and Connect(): this is set to 0 by default as -// the new events bring significant benefits in compile-time safety and -// flexibility but can be disabled to somewhat reduce the compilation time and, -// especially, to still allow building if the compiler template support is too -// bad to compile the new code. -// -// Default is 0 but this is set to 1 automatically in wx/chkconf.h for the -// compilers which can't build the new code (currently only g++ and MSVC >= 8 -// can) -// -// Recommended setting: 0 -#define wxEVENTS_COMPATIBILITY_2_8 0 - // MSW-only: Set to 0 for accurate dialog units, else 1 for old behaviour when // default system font is used for wxWindow::GetCharWidth/Height() instead of // the current font. diff --git a/samples/event/event.cpp b/samples/event/event.cpp index 9c89885231..3cc8c01e55 100644 --- a/samples/event/event.cpp +++ b/samples/event/event.cpp @@ -77,9 +77,9 @@ public: void OnQuit(wxCommandEvent& event); void OnAbout(wxCommandEvent& event); -#if !wxEVENTS_COMPATIBILITY_2_8 +#ifdef wxHAS_EVENT_BIND void OnBind(wxCommandEvent& event); -#endif // !wxEVENTS_COMPATIBILITY_2_8 +#endif // wxHAS_EVENT_BIND void OnConnect(wxCommandEvent& event); void OnDynamic(wxCommandEvent& event); void OnPushEventHandler(wxCommandEvent& event); @@ -177,9 +177,9 @@ BEGIN_EVENT_TABLE(MyFrame, wxFrame) EVT_MENU(Event_Quit, MyFrame::OnQuit) EVT_MENU(Event_About, MyFrame::OnAbout) -#if !wxEVENTS_COMPATIBILITY_2_8 +#ifdef wxHAS_EVENT_BIND EVT_MENU(Event_Bind, MyFrame::OnBind) -#endif // !wxEVENTS_COMPATIBILITY_2_8 +#endif // wxHAS_EVENT_BIND EVT_MENU(Event_Connect, MyFrame::OnConnect) EVT_MENU(Event_Custom, MyFrame::OnFireCustom) @@ -257,10 +257,10 @@ MyFrame::MyFrame(const wxString& title, const wxPoint& pos, const wxSize& size) menuFile->Append(Event_Quit, _T("E&xit\tAlt-X"), _T("Quit this program")); wxMenu *menuEvent = new wxMenu; -#if !wxEVENTS_COMPATIBILITY_2_8 +#ifdef wxHAS_EVENT_BIND menuEvent->AppendCheckItem(Event_Bind, "&Bind\tCtrl-B", "Bind or unbind a dynamic event handler"); -#endif // !wxEVENTS_COMPATIBILITY_2_8 +#endif // wxHAS_EVENT_BIND menuEvent->AppendCheckItem(Event_Connect, _T("&Connect\tCtrl-C"), _T("Connect or disconnect the dynamic event handler")); menuEvent->Append(Event_Dynamic, _T("&Dynamic event\tCtrl-D"), @@ -352,7 +352,7 @@ void MyFrame::OnDynamic(wxCommandEvent& event) ); } -#if !wxEVENTS_COMPATIBILITY_2_8 +#ifdef wxHAS_EVENT_BIND void MyFrame::OnBind(wxCommandEvent& event) { @@ -379,7 +379,7 @@ void MyFrame::OnBind(wxCommandEvent& event) UpdateDynamicStatus(event.IsChecked()); } -#endif // !wxEVENTS_COMPATIBILITY_2_8 +#endif // wxHAS_EVENT_BIND void MyFrame::OnConnect(wxCommandEvent& event) { diff --git a/setup.h.in b/setup.h.in index 2d7250e6a1..d9e18f346d 100644 --- a/setup.h.in +++ b/setup.h.in @@ -152,8 +152,6 @@ #define WXWIN_COMPATIBILITY_2_8 0 -#define wxEVENTS_COMPATIBILITY_2_8 0 - #define wxDIALOG_UNIT_COMPATIBILITY 0 diff --git a/src/common/appbase.cpp b/src/common/appbase.cpp index a3caf25a2b..269be5b575 100644 --- a/src/common/appbase.cpp +++ b/src/common/appbase.cpp @@ -503,7 +503,7 @@ void wxAppConsoleBase::CallEventHandler(wxEvtHandler *handler, { // If the functor holds a method then, for backward compatibility, call // HandleEvent(): - wxEventFunction eventFunction = functor.GetMethod(); + wxEventFunction eventFunction = functor.GetEvtMethod(); if ( eventFunction ) HandleEvent(handler, eventFunction, event); diff --git a/src/common/event.cpp b/src/common/event.cpp index e093e352d4..34ec269af1 100644 --- a/src/common/event.cpp +++ b/src/common/event.cpp @@ -1415,11 +1415,11 @@ bool wxEvtHandler::SearchEventTable(wxEventTable& table, wxEvent& event) return false; } -void wxEvtHandler::DoConnect(int id, - int lastId, - wxEventType eventType, - wxEventFunctor *func, - wxObject *userData) +void wxEvtHandler::DoBind(int id, + int lastId, + wxEventType eventType, + wxEventFunctor *func, + wxObject *userData) { wxDynamicEventTableEntry *entry = new wxDynamicEventTableEntry(eventType, id, lastId, func, userData); @@ -1443,11 +1443,11 @@ void wxEvtHandler::DoConnect(int id, } bool -wxEvtHandler::DoDisconnect(int id, - int lastId, - wxEventType eventType, - const wxEventFunctor& func, - wxObject *userData) +wxEvtHandler::DoUnbind(int id, + int lastId, + wxEventType eventType, + const wxEventFunctor& func, + wxObject *userData) { if (!m_dynamicEvents) return false; @@ -1469,7 +1469,7 @@ wxEvtHandler::DoDisconnect(int id, if ((entry->m_id == id) && ((entry->m_lastId == lastId) || (lastId == wxID_ANY)) && ((entry->m_eventType == eventType) || (eventType == wxEVT_NULL)) && - entry->m_fn->Matches(func) && + entry->m_fn->IsMatching(func) && ((entry->m_callbackUserData == userData) || !userData)) { delete entry->m_callbackUserData; diff --git a/tests/events/evthandler.cpp b/tests/events/evthandler.cpp index f51360a202..0f49b1a179 100644 --- a/tests/events/evthandler.cpp +++ b/tests/events/evthandler.cpp @@ -37,7 +37,7 @@ public: }; 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 @@ -75,6 +75,11 @@ void GlobalOnMyEvent(MyEvent&) g_called.function = true; } +void GlobalOnEvent(wxEvent&) +{ + g_called.function = true; +} + void GlobalOnAnotherEvent(AnotherEvent&); void GlobalOnIdle(wxIdleEvent&) @@ -130,7 +135,7 @@ BEGIN_EVENT_TABLE(MyClassWithEventTable, wxEvtHandler) EVT_IDLE(MyClassWithEventTable::OnIdle) EVT_MYEVENT(MyClassWithEventTable::OnMyEvent) -#if !wxEVENTS_COMPATIBILITY_2_8 +#ifdef wxHAS_EVENT_BIND EVT_MYEVENT(MyClassWithEventTable::OnEvent) #endif @@ -155,28 +160,30 @@ private: CPPUNIT_TEST_SUITE( EvtHandlerTestCase ); CPPUNIT_TEST( BuiltinConnect ); CPPUNIT_TEST( LegacyConnect ); -#if !wxEVENTS_COMPATIBILITY_2_8 +#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 +#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 @@ -206,7 +213,7 @@ 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); @@ -219,7 +226,7 @@ void EvtHandlerTestCase::BuiltinConnect() handler.Bind(wxEVT_IDLE, &MyHandler::StaticOnIdle); handler.Unbind(wxEVT_IDLE, &MyHandler::StaticOnIdle); -#endif // !wxEVENTS_COMPATIBILITY_2_8 +#endif // wxHAS_EVENT_BIND } void EvtHandlerTestCase::LegacyConnect() @@ -242,7 +249,7 @@ void EvtHandlerTestCase::LegacyConnect() handler.Disconnect( 0, 0, LegacyEventType, (wxObjectEventFunction)&MyHandler::OnEvent, NULL, &handler ); } -#if !wxEVENTS_COMPATIBILITY_2_8 +#ifdef wxHAS_EVENT_BIND void EvtHandlerTestCase::BindFunction() { @@ -345,6 +352,29 @@ void EvtHandlerTestCase::BindMethodUsingBaseEvent() } +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 @@ -402,4 +432,4 @@ void EvtHandlerTestCase::InvalidBind() #endif } -#endif // !wxEVENTS_COMPATIBILITY_2_8 +#endif // wxHAS_EVENT_BIND -- 2.45.2