Boost logo

Boost :

Subject: Re: [boost] Thoughts for a GUI (Primitives) Library
From: Yakov Galka (ybungalobill_at_[hidden])
Date: 2010-10-16 06:52:14


On Sun, Sep 26, 2010 at 18:08, Gwenio <urulokiurae_at_[hidden]> wrote:

> [...]
> Regarding extensibility, the handler is meant to deal with system messages;
> therefore at best for custom messages there would be a way to install
> translators that would convert unknown messages into generic events such as
> command and notify (message flow: system -> standard or custom translator
> ->
> event handler -> application). This is because the code processing the
> system messages would need to know how to format the data for the event
> handler, and if it cannot then the ability to add custom events to the
> handler would be useless. Furthermore it seems redundant to me to have both
> custom translations and custom event types.
>
We want to implement event handling. If so it doesn't matter what events we
pass, system events or custom events. A general solution will handle them
both.

 The reason behide dynamically creating the handler is because other than
> having the handler be a virtual class no method of creating it at compile
> time comes to mind, and I was trying to find a better way because it seems
> that many feel that is not good enough (or at least with some
> implementations of it like in MFC). Would you care to suggest a way?
>
There is nothing bad with virtual class.

You can use this approach to create event handlers at compile time:

    class MyEventHandler
    {
    public:
        typedef tuple<
            all_mouse_events, // this is a group of different mouse events.
we can (?) use SFINAE to call only those that are overridden. or perhaps
default to a do nothing handler if there is no override for e.g.
mouse_down_event, which is simpler to implement.
            // mouse_move_event, // or specify them one by one
            system_native_event // native events, untranslated
> handled_events;

        void on_event(const mouse_move_event& e) { ... }
        void on_event(const system_native_event& e) { ... }
    };

    class MyEventHandler2 { /* .. */ };

And then you can compose all these:

    typedef compose_handlers<tuple<MyEventHandler, MyEventHandler2>>
MySuperHandlers;

Or something like that. compose_handlers derives from all the handlers
passed and from event_handler. event_handler is a virtual class with
dispatch_event function. compose_handlers implements dispatch_event:

    template<class EventList...> class compose_handler : public
event_handler, public EventList...
    {
    public:
        virtual void dispatch_event( ??? )
        {
            for each event type/group in linearized EventList:
                if type matches, cast to it and
                    on_event(casted_event_reference);
        }
    };

Some variations are possible, mainly inheritance vs typedefed lists, static
vs non-static on_event.

Note: Without compile time reflection or ugly preprocessor macros we can't
avoid specifying handled events twice in *any* approach. We have to specify
them once for the handler function and once for what events we actually
handle. However using grouping like above we can simplify this a bit.

One question is how to dynamically dispatch the event to the right handler
function type. Possible ways:
    * Use dynamic_cast. Pros: grouping of event types is possible.
mouse_move can inherit mouse_event so on_event(mouse_event) can handle
mouse_move events too. User doesn't need to maintain event ids. Cons: Slow.
events are virtual classes.
    * Use typeid: Pros: User doesn't need to maintain event ids. Faster (?)
than dynamic_cast. Can be done without virtual classes: the one who
dispatched the event knows the exact type. Cons: No grouping of events. I
don't know what implementations do when dynamic linking is used but I guess
it still may be slow on some implementations.
    * Use address of global object as Id: Will this even work with dynamic
linking?
    * Use statically generated event ids. Pros: as fast as possible. Cons:
The burden of ensuring uniqueness falls on the user.

On Fri, Oct 15, 2010 at 21:27, Gwenio <urulokiurae_at_[hidden]> wrote:

> [...]
> Also, if handlers are derived for an abstract class, should controls be
> associated with both a handler and some object that stores date or should
> those two things be one and the same?
>
Why do you think that there must be a single answer for this question? I
think that depends on the control. Some controls may not be C++ objects at
all, e.g. native button may send command events. We may want to handle
events from grid cells which are defined implicitly, etc...

Once these questions are answered, it will be time to focus on specific
> requirements and the implementation of the library.

There are more questions to answer. Also someone here said that he is up to
implementing a prototype of his ideas, it would be nice to know what his
progress is and what his ideas are.

CLARIFICATION: everything I said is provided "as is" and without any
warranty. It's just brainstorming and isn't guaranteed to be logical or make
any sense.


Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk