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