[wx-dev] Template based wxEvtHandler::Connect
feature request/suggestion
Brian Vanderburg II
BrianVanderburg2 at aim.com
Fri Jul 25 04:12:19 PDT 2008
Vadim Zeitlin wrote:
> On Wed, 23 Jul 2008 22:18:02 -0400 Brian Vanderburg II <BrianVanderburg2 at aim.com> wrote:
>
> BVI> > BVI> Then it would be connected in user code as:
> BVI> > BVI>
> BVI> > BVI> ConnectMember<wxEVT_PAINT>(id, &MyClass::OnPaint);
> BVI> >
> BVI> > This still requires an object, doesn't it? I don't see the difference with
> BVI> > the above version to be honest.
> BVI> >
> BVI> Changing wxEVT_PAINT to a class, the version above required an instance
> BVI> of wxEVT_PAINT since it was receiving it as an argument:
> BVI>
> BVI> Connect(int id, E type, ...) -> Connect(myobj->GetId(), wxEVT_PAINT(), ...)
> BVI>
> BVI> You have to pass wxEVT_PAINT() instead of just wxEVT_PAINT
> BVI>
> BVI> The second version does not receive E as an argument so it doesn't need
> BVI> an instance of wxEVT_PAINT, it only needs to be told the type:
> BVI>
> BVI> Connect<wxEVT_PAINT>(myobj->GetId(), ...)
>
> Ok, this syntax might be better (although opinions could vary and
> explicitly selecting the template function specialization like this is
> definitely not supported by VC6).
>
> There is still the problem of how to do anything like this without
> breaking all the existing code defining the custom events. My idea with
> specializing some wxEventHandlerType template for the wxEVT_XXX values
> assumed that we'd be able to rely on default template definition (using
> unsafe wxEvent) for the user-defined types. But with your version I really
> don't see what are we going to do about it...
>
I was trying to figure some way that, for instance
wxEventHandlerType<1>::EventObjectType would match somehow for whatever
event 1, then wxEventHandlerType<wxEVT_PAINT>::EventObjectType woudl be
wxPaintEvent, etc is, etc. But, since the type value is not known at
compile time but is generated at runtime with wxNewEventType, can it
still be specialized? I did some extra reading on templates but I don't
know if it could be since the definition of the class is dependent on
the value.
I'm sure a way could be found that could keep the existing syntax but
somehow provide type checking, I'm just not sure what it would be.
> BVI> class EventHandler
> BVI> {
> BVI> public:
> BVI> EventHandler() { }
> BVI> ~EventHandler() { }
> BVI>
> BVI> template <typename E>
> BVI> void ConnectFunction(void (*fn)(typename E::EventObjectType&))
> BVI> {
> BVI> Functor* f = new FunctionFunctor<typename E::EventObjectType>(fn);
> BVI> EventEntry e;
> BVI> e.type = E::GetEventTypeValue();
> BVI> e.func = f;
> BVI> m_connections.push_back(e);
> BVI> }
> BVI>
> BVI> template <typename E, typename C>
> BVI> void ConnectMember(void (C::*fn)(typename E::EventObjectType&), C* obj)
> BVI> {
> BVI> Functor* f = new MemberFunctor<typename E::EventObjectType, C>(fn, obj);
> BVI> EventEntry e;
> BVI> e.type = E::GetEventTypeValue();
> BVI> e.func = f;
> BVI> m_connections.push_back(e);
> BVI> }
>
> We should just call them both Connect() IMO.
>
> BVI> // Note when connecting to a base member using a deived object
> BVI> // you must cast to the object pointer to a base as well:
> BVI> Derived d("d");
> ...
> BVI> handler.ConnectMember<EVT_MOTION>(&Object::fn1, static_cast<Object*>(&d));
>
> I believe boost::signal manages to do without the case, doesn't it? So it
> should be possible to avoid it, casting like this is totally impractical.
>
> Besides, of course, if this is completely incompatible with the existing
> code anyhow one could legitimately wonder why shouldn't we simply use
> boost::signal instead of reinventing it.
>
I agree, I didn't know if it would be desired to use another external
dependency or not Possible problems:
Boost::signal is not thread safe. Probably not much of a problem since
all event processing and connecting/disconnecting should occur in the
main thread anyway.
This would probably require all objects connected to derive from
boost::signals::trackable
Brian Vanderburg II
More information about the wx-dev
mailing list