digitalmars.D.dwt - Event handling
- Frank Benoit (44/44) Mar 21 2008 I think about how to do the event handling more D like, but also to
- bobef (2/55) Mar 28 2008
- Bill Baxter (41/94) Apr 09 2008 Here's a spin on that idea that allows the delegate to take an Event
- Frank Benoit (5/11) Apr 13 2008 I added this for an jface example.
- Bjoern (26/129) Apr 13 2008 Is such a hack really nessesary ? ( ... Sorry ... )
- Frank Benoit (3/33) Apr 13 2008 I don't get what your example shall illustrate.
- Bill Baxter (21/55) Apr 13 2008 Bjoern, I don't really get what you're saying either, but it sounds
I think about how to do the event handling more D like, but also to avoid adding/changing code in the ported code. The dwt from Shawn made this possible: table.addListener( DWT.Selection, &myHandler, &myData ); + use of delegates + optionally add data that is passed to the delegate - data must an "Object" - adds code into the dwt Now i think about adding this new class template to dwt.widgets.Listener: /// start of addition to dwt.widgets.Listener class DgListenerT( T... ) : Listener { alias void delegate(Event, T) ADel; ADel dg; T t; public this( ADel dg, T t ){ this.dg = dg; this.t = t; } public void handleEvent( Event e ){ dg(e, t); } } alias DgListenerT!() DgListener; /// end of addition to dwt.widgets.Listener table.addListener( DWT.Selection, new DgListener( &myHandler ) ); table.addListener( DWT.Selection, new DgListenerT!( int )( &myHandler, 23 ) ); + use of delegates + optionally add data that is passed to the delegate + data count and types are not fix + adds only additional class outside existing classes + no dwt internals need to be changed and maintained - need heap allocate the DgListenerT instance Are there more arguments pro/cons? Would you prefer another solution?
Mar 21 2008
Maybe you could use opCall to make things shorter to write? Frank Benoit Wrote:I think about how to do the event handling more D like, but also to avoid adding/changing code in the ported code. The dwt from Shawn made this possible: table.addListener( DWT.Selection, &myHandler, &myData ); + use of delegates + optionally add data that is passed to the delegate - data must an "Object" - adds code into the dwt Now i think about adding this new class template to dwt.widgets.Listener: /// start of addition to dwt.widgets.Listener class DgListenerT( T... ) : Listener { alias void delegate(Event, T) ADel; ADel dg; T t; public this( ADel dg, T t ){ this.dg = dg; this.t = t; } public void handleEvent( Event e ){ dg(e, t); } } alias DgListenerT!() DgListener; /// end of addition to dwt.widgets.Listener table.addListener( DWT.Selection, new DgListener( &myHandler ) ); table.addListener( DWT.Selection, new DgListenerT!( int )( &myHandler, 23 ) ); + use of delegates + optionally add data that is passed to the delegate + data count and types are not fix + adds only additional class outside existing classes + no dwt internals need to be changed and maintained - need heap allocate the DgListenerT instance Are there more arguments pro/cons? Would you prefer another solution?
Mar 28 2008
Frank Benoit wrote:I think about how to do the event handling more D like, but also to avoid adding/changing code in the ported code. The dwt from Shawn made this possible: table.addListener( DWT.Selection, &myHandler, &myData ); + use of delegates + optionally add data that is passed to the delegate - data must an "Object" - adds code into the dwt Now i think about adding this new class template to dwt.widgets.Listener: /// start of addition to dwt.widgets.Listener class DgListenerT( T... ) : Listener { alias void delegate(Event, T) ADel; ADel dg; T t; public this( ADel dg, T t ){ this.dg = dg; this.t = t; } public void handleEvent( Event e ){ dg(e, t); } } alias DgListenerT!() DgListener; /// end of addition to dwt.widgets.Listener table.addListener( DWT.Selection, new DgListener( &myHandler ) ); table.addListener( DWT.Selection, new DgListenerT!( int )( &myHandler, 23 ) ); + use of delegates + optionally add data that is passed to the delegate + data count and types are not fix + adds only additional class outside existing classes + no dwt internals need to be changed and maintained - need heap allocate the DgListenerT instance Are there more arguments pro/cons? Would you prefer another solution?Here's a spin on that idea that allows the delegate to take an Event parameter, or not, as it wishes. This one uses a factory function, which I think is the way to go, because that enables IFTI for the parameter types. ---- import std.traits; template Tuple(T...) { alias T Tuple; } /// A listener that takes a delegate. The Event arg is optional class _DgListenerT(Dg, T... ) : Listener { alias ParameterTypeTuple!(Dg) DgArgs; static assert( is(DgArgs == T) || is(DgArgs == Tuple!(Event,T)), "Delegate args not correct" ); Dg dg; T t; this( Dg dg, T t ) { this.dg = dg; static if (T.length > 0) { this.t = t; } } void handleEvent( Event e ){ static if (is(typeof(dg(e,t)))) { dg(e, t); } else static if (is(typeof(dg(t)))) { dg(t); } else { static assert(false, "Delegate type is incorrect for arguments supplied"); } } } _DgListenerT!(Dg,T) DgListener(Dg, T...)(Dg dg, T args) { return new _DgListenerT!(Dg,T)(dg,args); }
Apr 09 2008
Bill Baxter schrieb:Here's a spin on that idea that allows the delegate to take an Event parameter, or not, as it wishes. This one uses a factory function, which I think is the way to go, because that enables IFTI for the parameter types. ....I added this for an jface example. See: http://www.dsource.org/projects/dwt-addons/browser/dwtx/jface/operation/IRunnableWithProgress.d?rev=57%3A89776a9bb8b2 http://www.dsource.org/projects/dwt-samples/changeset/72%3Afc7a8f537871
Apr 13 2008
Bill Baxter schrieb:Frank Benoit wrote:Is such a hack really nessesary ? ( ... Sorry ... ) I mean A look at old school Smalltalk's message handling should teach us that "code blocks" // in our D case : closures // enable us to find a smarter solution. So I vote for spending a reasonable amount of time to figure out either a good/better D-ish solution or give a smalltalk like solution a try. Just my unholy opinion / the current DWT event handling is a bit clumbsy. -> Well, Closures are a D2 feature . and implementing code blocks using closures is not very smart .. THough I'm conviced that a closure based solution is worth thinking twice... OT --------------------------------------- D blocks : Pseudo code ------------------------------------------ for_each = function (list, block) { for (i = 0; i < list.sizeof(); ++i) block(list[i]) } for_each(list) { |x| Print(x) } => 12 34 56I think about how to do the event handling more D like, but also to avoid adding/changing code in the ported code. The dwt from Shawn made this possible: table.addListener( DWT.Selection, &myHandler, &myData ); + use of delegates + optionally add data that is passed to the delegate - data must an "Object" - adds code into the dwt Now i think about adding this new class template to dwt.widgets.Listener: /// start of addition to dwt.widgets.Listener class DgListenerT( T... ) : Listener { alias void delegate(Event, T) ADel; ADel dg; T t; public this( ADel dg, T t ){ this.dg = dg; this.t = t; } public void handleEvent( Event e ){ dg(e, t); } } alias DgListenerT!() DgListener; /// end of addition to dwt.widgets.Listener table.addListener( DWT.Selection, new DgListener( &myHandler ) ); table.addListener( DWT.Selection, new DgListenerT!( int )( &myHandler, 23 ) ); + use of delegates + optionally add data that is passed to the delegate + data count and types are not fix + adds only additional class outside existing classes + no dwt internals need to be changed and maintained - need heap allocate the DgListenerT instance Are there more arguments pro/cons? Would you prefer another solution?Here's a spin on that idea that allows the delegate to take an Event parameter, or not, as it wishes. This one uses a factory function, which I think is the way to go, because that enables IFTI for the parameter types. ---- import std.traits; template Tuple(T...) { alias T Tuple; } /// A listener that takes a delegate. The Event arg is optional class _DgListenerT(Dg, T... ) : Listener { alias ParameterTypeTuple!(Dg) DgArgs; static assert( is(DgArgs == T) || is(DgArgs == Tuple!(Event,T)), "Delegate args not correct" ); Dg dg; T t; this( Dg dg, T t ) { this.dg = dg; static if (T.length > 0) { this.t = t; } } void handleEvent( Event e ){ static if (is(typeof(dg(e,t)))) { dg(e, t); } else static if (is(typeof(dg(t)))) { dg(t); } else { static assert(false, "Delegate type is incorrect for arguments supplied"); } } } _DgListenerT!(Dg,T) DgListener(Dg, T...)(Dg dg, T args) { return new _DgListenerT!(Dg,T)(dg,args); }
Apr 13 2008
Bjoern schrieb:Is such a hack really nessesary ? ( ... Sorry ... ) I mean A look at old school Smalltalk's message handling should teach us that "code blocks" // in our D case : closures // enable us to find a smarter solution. So I vote for spending a reasonable amount of time to figure out either a good/better D-ish solution or give a smalltalk like solution a try. Just my unholy opinion / the current DWT event handling is a bit clumbsy. -> Well, Closures are a D2 feature . and implementing code blocks using closures is not very smart .. THough I'm conviced that a closure based solution is worth thinking twice... OT --------------------------------------- D blocks : Pseudo code ------------------------------------------ for_each = function (list, block) { for (i = 0; i < list.sizeof(); ++i) block(list[i]) } for_each(list) { |x| Print(x) } => 12 34 56I don't get what your example shall illustrate. Can you explain a bit more verbose?
Apr 13 2008
Frank Benoit wrote:Bjoern schrieb:Bjoern, I don't really get what you're saying either, but it sounds vaguely like you're saying let's make delegates be usable as event handlers. That's basically what this adapter template does. It lets you say : setListener(dgWrapper( (Event ev) { Print(ev); } )); Instead of: setListener(new class Listener { void handleEvent(Event ev) { Print(ev); } }); The next step would be to add an override to the setListener method to take a delegate and create the _DgListenerWrapperT automatically under the hood. Then you could do: setListener( (Event ev) { Print(ev); } ) but that wouldn't allow passing the extra args. --bbIs such a hack really nessesary ? ( ... Sorry ... ) I mean A look at old school Smalltalk's message handling should teach us that "code blocks" // in our D case : closures // enable us to find a smarter solution. So I vote for spending a reasonable amount of time to figure out either a good/better D-ish solution or give a smalltalk like solution a try. Just my unholy opinion / the current DWT event handling is a bit clumbsy. -> Well, Closures are a D2 feature . and implementing code blocks using closures is not very smart .. THough I'm conviced that a closure based solution is worth thinking twice... OT --------------------------------------- D blocks : Pseudo code ------------------------------------------ for_each = function (list, block) { for (i = 0; i < list.sizeof(); ++i) block(list[i]) } for_each(list) { |x| Print(x) } => 12 34 56I don't get what your example shall illustrate. Can you explain a bit more verbose?
Apr 13 2008