Event handling
Bjoern
nanali at nospam-wanadoo.fr
Sun Apr 13 10:12:02 PDT 2008
Bill Baxter schrieb:
> 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);
> }
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])
}
list = #(12, 34, 56) // tuple
for_each(list)
{ |x| Print(x) }
=> 12
34
56
More information about the Digitalmars-d-dwt
mailing list