|
Boost : |
From: Edward Diener (eddielee_at_[hidden])
Date: 2004-08-22 18:54:40
Mathew Robertson wrote:
>>>>> Why not use boost::signals for your event interface. It is much
>>>>> better than hand-coded actions and listeners, since any type of
>>>>> function can handle an event. The technology is already in Boost
>>>>> so why re-invent the wheel.
>>>>
>>>> The signals library looks very good, but it solves half the
>>>> problem. You need to work out what types of signals are raised:
>>>> MouseUp
>>>> MouseDown
>>>> MouseDoubleClick
>>>> MouseMove
>>>> and have a signal for each. This would mean that you could have
>>>> hundreds of signals!
>>>
>>> What makes this worse is that you often want to synthesise other
>>> events eg:
>>>
>>> - MouseClick+LeftAlt
>>> - MouseMove-Left-Down (think 'mouse gestures')
>>> - etc
>>
>> Just create a boost::signal<> for the mouse click and pass along all
>> the information about the keyboard with it to the handler.
>
> Possibly - except that the keyboard event will have generated its own
> event, which would have been passed to the widget in a previous
> signal. You could pass the key event in the same wrapper as the
> mouse event (or vice-versa), but then you are saying something about
> how the dispatcher handles events, which would limit you ability to
> do some things (eg for drag'n'drop situations, keyboard/mouse
> handling gets 'interesting' as you need to forward the events to the
> correct target window).
I do not see how any of this is impacted by boost::signal<>. If you are
saying that events must be created on-the-fly at run-time, with the
parameters unknown until run-time, rather than at compile time, I agree with
you that boost::signal<> is a compile time mechanism since every signal has
its parameters and return value. Still creating events at run-time implies
that some handler knows what the parameters of those events must be, so
there is no problem creating a signal for them at compile time to which a
handler can attach itself.
>
> In this case, you would want your 'gesture capable widget sub-class'
> (or something similar), to synthesise a MouseGesture event (or
> LeftAltClick event), so that your child widget implementations need
> only handle the single MouseGesture event, rather than, MouseMove,
> MouseMoveLeft, MouseMoveDown, etc.
Whatever you synthesize as an event can be represented as a boost::signal<>.
In your subclass just add your MouseGesture, and document it as an event
which combines some of the functionality of the other mouse events. It is
then up to the programmer whether they want to handle the MouseGesture or
the individual mouse events.
>
>> Let the handler
>> decide what should then be done with it. The handler could also be
>> you, internally, ready to trigger a new event for some special
>> situation. The point being that if you decide to have X number of
>> events for a particular class, and you decide that some subset of X
>> can be handled by the user, you are going to have to trigger those
>> events anyway, so having subset-X boost::signals to do it by is no
>> less of a cost than any other way. Remember also that
>> boost::signal<> are just variabales like anything else and can be
>> inherited like anything else by a specific derived class over a
>> broader base class. There is no reason, if you have a particular
>> mouse event as a boost::signal<> for a base class type of "window"
>> to have to create another mouse event of the exact same type, as a
>> boost::signal<>, for the derived class.
>
> Certainly... I dont have a specific aversion to using
> boost::signal<>... just that most of the examples / suggestions that
> have been preented so far, have some specific limitations. All I am
> trying to do is to highlight those limitations, specifically a) N+M
> event-to-action handling, b) bi-directional event information, c)
> run-time unknown-event dispatch capability
a) I do not undersatand what the problem with boost::signal<> is in this
case. A signal can have any number of slots to handle an event, and can
produce any number of signals itself in response to an event.
b) I have answered this above.
c) I agree if the event is completely unknown then boost::signal<> can not
be used. But in that case I don't see how any handler can handle it. If the
event is vague enough to require void * types of parameters ( or boost::any
or boost::variant as alternatives ) the handler still must have some way to
know, through other means which usually means other parameters, what the
events is generating. In that case a broader boost::signal<> can be
specified at compile time, such as boost::signal<void (void * /* or
boost::any, boost::variant */,int whattype info)> etc.
I do not doubt that there may be an event mechanism which specifies that
events must be created at run-time on the fly, as it were, but I still do
not see how handlers can handle them without parameters being passed to the
handler which tells what the event is about. I do understand that there is a
run-time memory cost with specify boost::signal<> within a class at compile
time as an object. If you are creating a huge number of signals at run-time
then you may not want to pay the cost. But I personally have never worked
with an event mechanism which didn't make it reasonable to specify the
signals one wants for a class at compile-time, and still easily work within
the memory constraints of the system. Remember also that it is possible to
create boost::signal<> at run-time in just the same way one creates any C++
variable at run-time, through dynamic memory and 'new', or better by using
boost::shared_ptr<> ( or std::auto_ptr<> ).
Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk