Jump to page: 1 2
Thread overview
event handling: request for comments
Feb 23, 2002
Pavel Minayev
Feb 23, 2002
Pavel Minayev
Mar 04, 2002
Pavel Minayev
Mar 04, 2002
Pavel Minayev
Mar 04, 2002
Richard Krehbiel
Mar 04, 2002
Pavel Minayev
Mar 04, 2002
Richard Krehbiel
Mar 04, 2002
Pavel Minayev
Mar 05, 2002
Richard Krehbiel
Mar 05, 2002
Pavel Minayev
Mar 04, 2002
Richard Krehbiel
Mar 04, 2002
Roland
February 23, 2002
This is something I would really like to hear others' opinions
about: event handling in my GUI library, WinD. Currently, it
tries to mimic the Borland's approach (pointers to methods),
and does it by some rather dirty hacks, like modifying the
vtable at run-time, besides, it's highly error-prone... Needless
to say, I'm not very satisfied with this solution. Should it
be dropped in favor of other method, and if so, which? I only
have one idea: a single handler for ALL events from this and
child controls:

    class MyForm: Form
    {
        TextBox txtName;
        Button cmdOk;

        ...

        void eventHandler(Event e)
        {
            switch (e.sender)
            {
            case txtName:
                switch (e.type)
                {
                case Event.Click:
                    ...
                case Event.Change:
                    ...
                }
                break;
            case cmdOk:
                if (e.type == Event.Click)
                    ...
            }
        }
    }

This method is very simple to implement, but it results in code hard to write, read and understand, and limits the enchancement capabilities (adding new events could be a problem).


Other ideas?


February 23, 2002
Pavel Minayev wrote:

> This is something I would really like to hear others' opinions
> about: event handling in my GUI library, WinD. Currently, it
> tries to mimic the Borland's approach (pointers to methods),
> and does it by some rather dirty hacks, like modifying the
> vtable at run-time, besides, it's highly error-prone... Needless
> to say, I'm not very satisfied with this solution. Should it
> be dropped in favor of other method, and if so, which? I only
> have one idea: a single handler for ALL events from this and
> child controls:
> ...
> This method is very simple to implement, but it results in code hard to
> write, read and understand, and limits the enchancement capabilities
> (adding new events could be a problem).
>
> Other ideas?

I've often though about ways to merge event and exception handling.  There are two fundamental types of each:  1) Ones you expect, and ones you don't, and 2) Ones you want to handle locally, and ones you want to handle globally.

The "local" context is generally where "expected" events and exceptions are handled, and if there is no local handler, we "fall through" to a global context, which then falls through to the language or OS for default handling of events and exceptions we haven't explicitly handled at either the local or global levels.

We also want to locally override the global handling when and where it suits our needs, and be able to do this both for exceptions and events.

I believe it would be useful to have both contexts available for each. Fundamentally, I'd like to have the ability to make "events" look like traditional exceptions, and I'd also like to be able to make "exceptions" look like traditional events.  Many high-level ORBs merge the two into the event system, but at the language level it may be useful to also be able to use something like the exception system for some events.

There are also cases where events may need to be handled partially in the "event" domain, and the remainder handled in the "exception" domain.  That is, do some of the handling as an event, then throw an exception for the rest.  The inverse may be true for some exceptions (handle the exception partially, then generate an event), but I have no specific examples in mind.  Things like local repair followed by global cleanup or state restoration/resetting come to mind.

In real-time and embedded systems, most operational conditions are handled by the main path through the application code.  Obvious failures are handled as such.  But conditions at the edges of the performance envelope often demand processing outside the normal flow, and using events and exceptions are useful ways to gain access to this code without cluttering up the main execution path.  In mose languages you have to choose one or the other.  I'd like to have both.

For D, would it be useful or possible to extend the exception system to handle general event handling?

I haven't thought this all the way through yet, so I have no specific architecture, design or implementation recommendations.  It's just my $0.02 at this point...


-BobC


February 23, 2002
There are many ways to improve D in this area. However, since Walter is busy with other things =| I guess a solution has to be found which uses whatever is already there (in D).


March 04, 2002
Pavel Minayev wrote:
> There are many ways to improve D in this area. However, since
> Walter is busy with other things =| I guess a solution has
> to be found which uses whatever is already there (in D).
> 
> 
> 

And how about... JAVA style of event handling?

March 04, 2002
"Ruslanas Abdrachimovas" <anubis@03bar.ktu.lt> wrote in message news:3C8388E2.8050703@03bar.ktu.lt...

> And how about... JAVA style of event handling?

... and it is?...


March 04, 2002
"Ruslanas Abdrachimovas" <anubis@03bar.ktu.lt> wrote in message news:3C8388E2.8050703@03bar.ktu.lt...
> Pavel Minayev wrote:
> > There are many ways to improve D in this area. However, since Walter is busy with other things =| I guess a solution has to be found which uses whatever is already there (in D).
> >
> >
> >
>
> And how about... JAVA style of event handling?

Java SWING event handling is irritating in it's need/desire for weirdo anonymous intermediate classes.  C# builds event handling in, but (also IMHO) the distinction between an event and a method is too subtle.

I personally have always thought that event handling should be a simple matter of virtual methods used as callbacks.

The drawback is the need for large vtables for lots of potential callbacks, most of which aren't used.  But I think that, in these days of cheap and plentiful memory, the simplicity of the approach outweighs the memory savings.

Perhaps if you *really* want to talk about saving vtable space, then consider building "sparse vtable" support into the language; have the compiler/linker automatically (or by hint) realize that overrides from a particular class are rare, and instead of a plain vtable, make a "sparse" vtable that's sorted by method ID (which would be equal to the offset in the regular vtable format), and where method dispatches do a binary search for the method, and if not found, automatically reroute to the superclass.

But in the end, I don't see a great need for any special "event handling" facility.

--
Richard Krehbiel, Arlington, VA, USA
rich@kastle.com (work) or krehbiel3@comcast.net  (personal)



March 04, 2002
Pavel Minayev wrote:
> "Ruslanas Abdrachimovas" <anubis@03bar.ktu.lt> wrote in message
> news:3C8388E2.8050703@03bar.ktu.lt...
> 
> 
>>And how about... JAVA style of event handling?
>>
> 
> ... and it is?...
> 
> 
> 

Event dispatcher queue in separate thread... And who wants to listen to say JButton instance just does
button.addActionListener(<ref to object implementing action listener interface>);

.... More abstract: observer pattern with some additions (queue in separate thread) =] ....

Ruslanas

March 04, 2002
"Ruslanas Abdrachimovas" <anubis@03bar.ktu.lt> wrote in message news:3C839AA7.1090403@03bar.ktu.lt...

> Event dispatcher queue in separate thread... And who wants to listen to
> say JButton instance just does
> button.addActionListener(<ref to object implementing action listener
> interface>);

Doesn't this require creating a separate listener class for each control?


March 04, 2002
"Pavel Minayev" <evilone@omen.ru> wrote in message news:a606fb$1p8f$1@digitaldaemon.com...
> "Ruslanas Abdrachimovas" <anubis@03bar.ktu.lt> wrote in message news:3C839AA7.1090403@03bar.ktu.lt...
>
> > Event dispatcher queue in separate thread... And who wants to listen to
> > say JButton instance just does
> > button.addActionListener(<ref to object implementing action listener
> > interface>);
>
> Doesn't this require creating a separate listener class for each control?

Though I don't think it's specifically necessary, that's what JBuilder makes for you, an anonymous inner class (not just class instance, but a whole distinct class) for each event.

--
Richard Krehbiel, Arlington, VA, USA
rich@kastle.com (work) or krehbiel3@comcast.net  (personal)



March 04, 2002
"Ruslanas Abdrachimovas" <anubis@03bar.ktu.lt> wrote in message news:3C839AA7.1090403@03bar.ktu.lt...

> Event dispatcher queue in separate thread... And who wants to listen to
> say JButton instance just does
> button.addActionListener(<ref to object implementing action listener
> interface>);

Now I've read the specification, I understand... I'd thought of
something like this already, but it requires tons of classes
and objects to be created to handle all events in a more or
less complex window... also listener objects will have to store
pointer to their owner, and won't get access to privates - bad!
Java provides a workaround in the form of anonymous inner classes,
unfortunately there isn't anything like that in D.

I've been thinking of another, not very safe, but (IMO) better
alternative. Here's a sample snippet:

    /* library code */
    interface Handler { }  // just a dummy, to provide some typechecking
    private interface _Handler: Handler { void handle(Event); }

    class Button
    {
        Handler onClick;
        ...

        void clicked()
        {
            (cast(_Handler) onClick).handle(new ClickEvent);
        }
    }


    /* user code */
    interface cmdOk_Click: Handler { void cmdOk_Click(Event); }
    interface cmdCancel_Click: Handler { void cmdCancel_Click(Event); }

    class MyForm: Form, cmdOk_Click, cmdCancel_Click
    {
        Button cmdOk, cmdCancel;

        this()
        {
            ...
            cmdOk.onClick = cast(cmdOk_Click) this;
            cmdCancel.onClick = cast(cmdCancel_Click) this;
        }

        void cmdOk_Click(Event e) { ... }
        void cmdCancel_Click(Event e) { ... }
    }




« First   ‹ Prev
1 2