digitalmars.D.dwt - Events
- Kyle Furlong (28/28) Feb 07 2006 Currently, one has to write code like this:
- Kris (11/12) Feb 07 2006 I suspect what's happening is that your out-of-scope MenuArgs are actual...
- Kyle Furlong (3/20) Feb 07 2006 I guess I am just searching for best practices. If someone can come up w...
- Shawn Liu (52/82) Feb 08 2006 It's not a bug. It is a tradeoff.
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?
Feb 07 2006
"Kyle Furlong" <kylefurlong gmail.com> wrote .. [snip]Is this a bug? Or a feature?I suspect what's happening is that your out-of-scope MenuArgs are actually on the stack when you call handleMouseDown(), which is not the case when the delegate is invoked. Java handles such things by encapsulating the stack state, but D does not (for a variety of reasons). One way to resolve it is to change the approach such that MenuArgs becomes part of an enclosing class or struct around the handler, or otherwise becomes reachable from the handler (such as a static MenuArgs would be). Which examples are you referring to, Kyle? I ask because there's a couple of subtle concerns here.
Feb 07 2006
Kris wrote:"Kyle Furlong" <kylefurlong gmail.com> wrote .. [snip]I guess I am just searching for best practices. If someone can come up with The Right Way to handle events in DWT I would be happy. The examples I was referring to are the ones in the DWT distribution.Is this a bug? Or a feature?I suspect what's happening is that your out-of-scope MenuArgs are actually on the stack when you call handleMouseDown(), which is not the case when the delegate is invoked. Java handles such things by encapsulating the stack state, but D does not (for a variety of reasons). One way to resolve it is to change the approach such that MenuArgs becomes part of an enclosing class or struct around the handler, or otherwise becomes reachable from the handler (such as a static MenuArgs would be). Which examples are you referring to, Kyle? I ask because there's a couple of subtle concerns here.
Feb 07 2006
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 1) use delegate a) pass args as Kyle expressed, which is anonymous delegate b) use named delegate 2) use listener a) implement the listener interface by the class 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. 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?
Feb 08 2006