Event handling

Bill Baxter dnewsgroup at billbaxter.com
Wed Apr 9 09:21:35 PDT 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);
}


More information about the Digitalmars-d-dwt mailing list