D - event handling: request for comments
- Pavel Minayev (37/37) Feb 23 2002 This is something I would really like to hear others' opinions
- Robert W. Cunningham (38/52) Feb 23 2002 I've often though about ways to merge event and exception handling. The...
- Pavel Minayev (3/3) Feb 23 2002 There are many ways to improve D in this area. However, since
- Ruslanas Abdrachimovas (2/8) Mar 04 2002 And how about... JAVA style of event handling?
- Pavel Minayev (3/4) Mar 04 2002 ... and it is?...
- Ruslanas Abdrachimovas (8/19) Mar 04 2002 Event dispatcher queue in separate thread... And who wants to listen to
- Pavel Minayev (4/8) Mar 04 2002 Doesn't this require creating a separate listener class for each
- Richard Krehbiel (8/16) Mar 04 2002 Though I don't think it's specifically necessary, that's what JBuilder m...
- Pavel Minayev (38/42) Mar 04 2002 Now I've read the specification, I understand... I'd thought of
- Richard Krehbiel (12/54) Mar 04 2002 Forgive me for being dense and/or naive, but I still don't see the
- Pavel Minayev (29/35) Mar 04 2002 No MI, so you can't subclass from many classes, only from one.
- Richard Krehbiel (13/13) Mar 05 2002 Hmmm.... Okay, I think I'm seeing the issue more correctly.
- Pavel Minayev (28/34) Mar 05 2002 classes,
- Richard Krehbiel (23/31) Mar 04 2002 Java SWING event handling is irritating in it's need/desire for weirdo
- Roland (24/61) Mar 04 2002 Warning:
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?
Feb 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
Feb 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).
Feb 23 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?
Mar 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?...
Mar 04 2002
Pavel Minayev wrote:"Ruslanas Abdrachimovas" <anubis 03bar.ktu.lt> wrote in message news:3C8388E2.8050703 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>); .... More abstract: observer pattern with some additions (queue in separate thread) =] .... RuslanasAnd how about... JAVA style of event handling?... and it is?...
Mar 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?
Mar 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...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)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?
Mar 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) { ... } }
Mar 04 2002
"Pavel Minayev" <evilone omen.ru> wrote in message news:a607ha$1psa$1 digitaldaemon.com..."Ruslanas Abdrachimovas" <anubis 03bar.ktu.lt> wrote in message news:3C839AA7.1090403 03bar.ktu.lt...Forgive me for being dense and/or naive, but I still don't see the difficulty with dispensing with intermediate event-receptor classes, but rather subclass all your GUI objects from supplied classes with predefined event-methods, and then implementing those methods you want. And if you think the difficulty is "too many potential callback methods leading to overly large vtbls" then see my other post regarding this issue: news://news.digitalmars.com/a6054t$1o03$1 digitaldaemon.com -- Richard Krehbiel, Arlington, VA, USA rich kastle.com (work) or krehbiel3 comcast.net (personal)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) { ... } }
Mar 04 2002
"Richard Krehbiel" <rich kastle.com> wrote in message news:a609d8$1rd6$1 digitaldaemon.com...Forgive me for being dense and/or naive, but I still don't see the difficulty with dispensing with intermediate event-receptor classes, but rather subclass all your GUI objects from supplied classes with predefined event-methods, and then implementing those methods you want.No MI, so you can't subclass from many classes, only from one. So you have to use interfaces. Now consider the following one: interface IButtonEvents { void onButtonClick(Event); } And a form: class MyForm: Form, IButtonEvents { Button cmdOk, cmdCancel; onButtonClick(Event e) { } } Now onButtonClick() will receive click messages from BOTH cmdOk and cmdCancel, and you have to use switch to provide separate implementation for each case - and what if there are 20 buttons on the form?.. this isn't far from your typical WindowProc style. What I want is the ability to bind a separate function for each event of each distinct _object_ (and not class). So if you have 10 buttons on your form, you should be able to have 10 onClick handlers, one for each button. I don't see how it can be done this way.And if you think the difficulty is "too many potential callback methods leading to overly large vtbls" then see my other post regarding thisissue: Not a problem, IMO. If you have 30-40 event handlers, it's just 120-160 additional bytes in the vtable per class - not something worthy even remembering about.
Mar 04 2002
Hmmm.... Okay, I think I'm seeing the issue more correctly. In VB, event handlers are located symbolically. If a control's name is "Button1" and it's trying to deliver a Click event, it looks for a method "Button1_Click" in the form. This is mighty convenient, but also very symbolic. Hmmm. I'm finding myself resorting to the Java style, with event handler classes, but not funky anonymous inner classes. And I'm not really liking it. If only D had *macros* this could be done rather conveniently. (I don't know why no one else can see the need for macros. Just you wait until I've written up the spec for the macro language; you'll see.) -- Richard Krehbiel, Arlington, VA, USA rich kastle.com (work) or krehbiel3 comcast.net (personal)
Mar 05 2002
"Richard Krehbiel" <rich kastle.com> wrote in message news:a62fdv$2ra5$1 digitaldaemon.com...In VB, event handlers are located symbolically. If a control's name is "Button1" and it's trying to deliver a Click event, it looks for a method "Button1_Click" in the form. This is mighty convenient, but also very symbolic. Hmmm. I'm finding myself resorting to the Java style, with event handlerclasses,but not funky anonymous inner classes. And I'm not really liking it.class Button { delegate void (*onClick)(Event); ... void clicked() { onClick(new Event); } } class MyForm: Form { Button cmdOk, cmdCancel; ... this() { cmdOk.onClick = &this.cmdOk_Click; cmdCancel.onClick = &this.cmdCancel_Click; } void cmdOk_Click(Event e) { ... } void cmdCancel_Click(Event e) { ... } } Unfortunately, delegates are very unlikely to be seen in D 1.0, from what I've heard...
Mar 05 2002
"Ruslanas Abdrachimovas" <anubis 03bar.ktu.lt> wrote in message news:3C8388E2.8050703 03bar.ktu.lt...Pavel Minayev wrote:Java SWING event handling is irritating in it's need/desire for weirdo 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)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?
Mar 04 2002
Pavel Minayev a écrit :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?Warning: This post is very theorical and not pactical at all. I'm not very aware of how D is now. I don't use it yet. I hope this post will not lower my already poor signal/noise ratio. Lets go: A system that generate events, is like an electronic chip, witch pins change of state to signal something. It you want your own chip to react to the event, there is no other way than to connect an input pin of your chip to the proper output signal. In HDL (Hardware Description Langage), to connect an input pin to an output pin, you use the '=' operator. In my opinion, it would be nice if interfaces and signal handling in D takes inspiration from HDL langages. (may be it is already the case for interfaces) You defines 'chips' (classes) with input and output and you connect them programmaticaly, at compile time or at run time (multiplexers). Note that an output pin can be connected to many input pins, and all input pins recieve the information at the same time. A compiler should emulate that. (carefull with race conditions ! the compiler should detect them) Roland
Mar 04 2002