| |
| Posted by Shawn Liu in reply to Kyle Furlong | PermalinkReply |
|
Shawn Liu
Posted in reply to Kyle Furlong
| It's not a bug. It is a tradeoff.
I spent some time to integrate D delegate to DWT. And eventually made it
possible to support both D Delegate and Java like Listener to handle an
event;
Coexistence of delegate and listener can benefit port exists java project
which
use listener. And new app can use either as suitable; The passed arguments
makes it possible to use anonymous delegate.
But anonymous delegate can not access stack object or event part of an enclosing class/struct. This is because the install of delegate and invoke the delegate occurs in different stack.
Anonymous listener can access variable of the enclosing class, but seems can't access the enclosing class this pointer ( not sure )
assumed we have the class with Label and Menu variable
# class SomeClass {
# Label label;
# Menu menu;
# .....
# }
1) use delegate
a) pass args as Kyle expressed, which is anonymous delegate
b) use named delegate
# void foo(MouseEvent e) {
# // Do things with Label and Menu
# }
# label.handleMouseDown(null, &foo);
2) use listener
a) implement the listener interface by the class
# class SomeClass : SelectionListener {
# // implement the interface
# public void widgetSelected(SelectionEvent e){
# // Do things with Label and Menu
# }
# // install the listener
# label.addSelectionListener(this);
# }
b) create separated Listener class
Can be a separated class or inner class of the outer,
but still need pass the arguments in.
I am not sure whether inner class can access outer
class's member as Java does.
# class MyListener : SelectionListener {
# MenuArgs args;
# public this(MenuArgs args) { this.args = args; }
# public void widgetSelected(SelectionEvent e){
# // do things with args
# }
c) anonymous listener
zwang gives an example in "sortindicator.d"
http://trac.dsource.org/projects/dwt/browser/trunk/current/win32/packages/dwt/examples/sortindicator/sortindicator.d?rev=96#L80
"Kyle Furlong" <kylefurlong@gmail.com> says:dsb732$44v$1@digitaldaemon.com...
> Currently, one has to write code like this:
>
> private class MenuArgs
> {
> Menu menu;
> Label label;
> this(Menu m, Label l)
> {
> menu = m;
> label = l;
> }
> }
>
> MenuArgs args = new MenuArgs(Menu, Label);
>
> Label.handleMouseDown(args, delegate void(MouseEvent e)
> {
> MenuArgs args = cast(MenuArgs)e.cData;
> // Do things with args.
> });
>
> But NOT like this:
>
> Label.handleMouseDown(null, delegate void(MouseEvent e)
> {
> // Do things with Label and Menu, and any other objects outside this
> scope.
> });
>
> Doing anything with objects outside of the scope of the delegate will cause AccessViolations inside of the DWT eventable.d, unless they are passed as cData.
>
> This seems to be an onerous restriction, and also counterintuitive. Also, all the examples use objects outside the scope of the delegate as well, so that it would seem to be The Right Way, except that it doesnt work.
>
>
> Is this a bug? Or a feature?
|