↑ ↓ ← → Frank Benoit <keinfarbton googlemail.com> writes:
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?
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
↑ ↓ ←→ Bill Baxter <dnewsgroup billbaxter.com> writes:
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
↑ ↓← → Frank Benoit <keinfarbton googlemail.com> writes:
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 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
Apr 13 2008
↑ ↓ ←→ Frank Benoit <keinfarbton googlemail.com> writes:
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])
}
list = #(12, 34, 56) // tuple
for_each(list)
{ |x| Print(x) }
=> 12
34
56
I don't get what your example shall illustrate.
Can you explain a bit more verbose?
Apr 13 2008
↑ ↓ ← → Bill Baxter <dnewsgroup billbaxter.com> writes:
Frank Benoit wrote:
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])
}
list = #(12, 34, 56) // tuple
for_each(list)
{ |x| Print(x) }
=> 12
34
56
I don't get what your example shall illustrate.
Can you explain a bit more verbose?
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.
--bb