Why does LzDelegate require its context to inherit from LzEventable?

View: New views
5 Messages — Rating Filter:   Alert me  

Why does LzDelegate require its context to inherit from LzEventable?

by Neil Mix :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

I understand why event senders would needs to be LzEventable, but why  
event receivers?  Related: is there any way to trick the AS3 runtime  
into accepting a dynamic POJSO as an LzEventable?

Thanks,
   -Neil

Re: Why does LzDelegate require its context to inherit from LzEventable?

by P T Withington :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

On 2009-10-29, at 16:40, Neil Mix wrote:

> I understand why event senders would needs to be LzEventable, but  
> why event receivers?

Mostly this was because we had to rationalize the way events were  
propagated when instances were created and constraints fired.  It  
turned out that a lot of that worked only 'by luck' in swf8 (with the  
helpful feature that swf8 graciously ignored any errors like calls to  
non-functions, evaluations of non-existent variables, etc.)  When we  
created the DHTML and swf9/10 back-ends, they were not so forgiving.  
LzEventable encompasses the protocols that allow an orderly evaluation  
of constraints.

It's not done yet, but this also was to reduce the need to manually  
manage delegates.  Delegates are a constant source of memory leaks  
because they get forgotten and can end up "resurrecting" objects that  
should have been collected.  So, in swf8 and DHTML, we now warn you,  
but in swf9/10 you will get a type error.  Eventually, we hope to be  
able to manage delegates completely internally to LZX.

>   Related: is there any way to trick the AS3 runtime into accepting  
> a dynamic POJSO as an LzEventable?


Usually when people run into this issue updating their code, they can  
either use a closure or add a method to the sender that trampolines to  
the non-LzEventable.

If you have a particular example, I can comment further.

Re: Why does LzDelegate require its context to inherit from LzEventable?

by Neil Mix :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

I do remember how the old LFC relied on silent errors.  It made my  
initial read of the source code unbelievably confusing until I  
realized that referencing non-existent objects was expected behavior.  
Kinda like nil in Objective-C, but not formalized.  But I digress.

When you say "either use a closure or add a method to the sender,"  
what does the closure option look like?  Let's say I want to listen  
for lz.Keys onkeydown events -- where would a closure fit into the  
event propagation scheme?  Do you just mean a dynamically created  
trampoline created in code versus a static trampoline defined in markup?

Also: is there a JavaScript syntax for creating a standard function/
class that extends an AS3 class such as Eventable?


On Oct 29, 2009, at 4:01 PM, P T Withington wrote:

> On 2009-10-29, at 16:40, Neil Mix wrote:
>
>> I understand why event senders would needs to be LzEventable, but  
>> why event receivers?
>
> Mostly this was because we had to rationalize the way events were  
> propagated when instances were created and constraints fired.  It  
> turned out that a lot of that worked only 'by luck' in swf8 (with  
> the helpful feature that swf8 graciously ignored any errors like  
> calls to non-functions, evaluations of non-existent variables,  
> etc.)  When we created the DHTML and swf9/10 back-ends, they were  
> not so forgiving.  LzEventable encompasses the protocols that allow  
> an orderly evaluation of constraints.
>
> It's not done yet, but this also was to reduce the need to manually  
> manage delegates.  Delegates are a constant source of memory leaks  
> because they get forgotten and can end up "resurrecting" objects  
> that should have been collected.  So, in swf8 and DHTML, we now warn  
> you, but in swf9/10 you will get a type error.  Eventually, we hope  
> to be able to manage delegates completely internally to LZX.
>
>>  Related: is there any way to trick the AS3 runtime into accepting  
>> a dynamic POJSO as an LzEventable?
>
>
> Usually when people run into this issue updating their code, they  
> can either use a closure or add a method to the sender that  
> trampolines to the non-LzEventable.
>
> If you have a particular example, I can comment further.


Re: Why does LzDelegate require its context to inherit from LzEventable?

by Henry Minsky :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

In answer to your second question, you can write straight javascript or as3 code that extends a class by using a <script when="immediate"> block, that will essentially compile the code as if it appeared at the top level  with all the other code that gets translated from LZX to javascript.

So for example look in the lps/components/extensions/drawview.lzx file, you'll see some
code which extends LzView. But you can extend any class this way, it doesn't have to be a subclass of LzNode. 



On Thu, Oct 29, 2009 at 5:48 PM, Neil Mix <nmix@...> wrote:
I do remember how the old LFC relied on silent errors.  It made my initial read of the source code unbelievably confusing until I realized that referencing non-existent objects was expected behavior.  Kinda like nil in Objective-C, but not formalized.  But I digress.

When you say "either use a closure or add a method to the sender," what does the closure option look like?  Let's say I want to listen for lz.Keys onkeydown events -- where would a closure fit into the event propagation scheme?  Do you just mean a dynamically created trampoline created in code versus a static trampoline defined in markup?

Also: is there a JavaScript syntax for creating a standard function/class that extends an AS3 class such as Eventable?



On Oct 29, 2009, at 4:01 PM, P T Withington wrote:

On 2009-10-29, at 16:40, Neil Mix wrote:

I understand why event senders would needs to be LzEventable, but why event receivers?

Mostly this was because we had to rationalize the way events were propagated when instances were created and constraints fired.  It turned out that a lot of that worked only 'by luck' in swf8 (with the helpful feature that swf8 graciously ignored any errors like calls to non-functions, evaluations of non-existent variables, etc.)  When we created the DHTML and swf9/10 back-ends, they were not so forgiving.  LzEventable encompasses the protocols that allow an orderly evaluation of constraints.

It's not done yet, but this also was to reduce the need to manually manage delegates.  Delegates are a constant source of memory leaks because they get forgotten and can end up "resurrecting" objects that should have been collected.  So, in swf8 and DHTML, we now warn you, but in swf9/10 you will get a type error.  Eventually, we hope to be able to manage delegates completely internally to LZX.

 Related: is there any way to trick the AS3 runtime into accepting a dynamic POJSO as an LzEventable?


Usually when people run into this issue updating their code, they can either use a closure or add a method to the sender that trampolines to the non-LzEventable.

If you have a particular example, I can comment further.




--
Henry Minsky
Software Architect
hminsky@...



Re: Why does LzDelegate require its context to inherit from LzEventable?

by P T Withington :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

[Sorry for the delay in replying -- deep in a project here.]

On 2009-10-29, at 17:48, Neil Mix wrote:

> I do remember how the old LFC relied on silent errors.  It made my  
> initial read of the source code unbelievably confusing until I  
> realized that referencing non-existent objects was expected  
> behavior.  Kinda like nil in Objective-C, but not formalized.  But I  
> digress.
>
> When you say "either use a closure or add a method to the sender,"  
> what does the closure option look like?

I was just pointing out that method closures actually work in AS3, so  
if you are talking to a native AS3 interface and need a callback, you  
can just pass the method, you do not need to build any complex  
mechanism to use a delegate for your callback.

> Let's say I want to listen for lz.Keys onkeydown events -- where  
> would a closure fit into the event propagation scheme?  Do you just  
> mean a dynamically created trampoline created in code versus a  
> static trampoline defined in markup?
>
> Also: is there a JavaScript syntax for creating a standard function/
> class that extends an AS3 class such as Eventable?

Henry has already pointed you in the right direction on this I think.  
The OpenLaszlo script compiler supports most of (what was to be) JS2  
syntax for classes.  So you could write (untested):

/* Class to trampoline OL events to closures/callbacks */
class EventListener extends LzEventable {
   var callback:Function;
   var delegate:LzDelegate;

   function KeyListener(callback:Function, eventSender:LzEventable,  
eventName:String) {
     this.callback = callback;
     this.delegate = new LzDelegate(this, 'onevent', eventSender,  
eventName);
   }

   function onevent(event):void { this.callback.call(event); }

   function destroy() {
     this.delegate.unregisterAll();
     super.destroy();
   }
}

/* Example callback */
function handleKey(key) { ... };

/* Install a listener that will call the callback */
var myListener = new EventListener(handleKey, lz.Keys, 'onkeydown');

[Note the destroy method, necessary to prevent leaks if you need to  
dynamically create and dispose of listener objects.  If you don't call  
destroy, the delegate will keep the closure alive as long as the  
sender is alive.]

Hm, maybe we should just add something like this to the LFC, to extend  
events to closures?  Seems like a generally useful feature.

But also, you can fairly cheaply write something similar in LZX.  A  
<node> is an LzEventable, and is fairly lightweight.  It doesn't  
create any graphical elements.  So you could also say:

<node>
   <handler name='onkeydown' reference="lz.Keys">
     ...
   </handler>
</node>

You could put any number of handlers into a single node.

> On Oct 29, 2009, at 4:01 PM, P T Withington wrote:
>
>> On 2009-10-29, at 16:40, Neil Mix wrote:
>>
>>> I understand why event senders would needs to be LzEventable, but  
>>> why event receivers?
>>
>> Mostly this was because we had to rationalize the way events were  
>> propagated when instances were created and constraints fired.  It  
>> turned out that a lot of that worked only 'by luck' in swf8 (with  
>> the helpful feature that swf8 graciously ignored any errors like  
>> calls to non-functions, evaluations of non-existent variables,  
>> etc.)  When we created the DHTML and swf9/10 back-ends, they were  
>> not so forgiving.  LzEventable encompasses the protocols that allow  
>> an orderly evaluation of constraints.
>>
>> It's not done yet, but this also was to reduce the need to manually  
>> manage delegates.  Delegates are a constant source of memory leaks  
>> because they get forgotten and can end up "resurrecting" objects  
>> that should have been collected.  So, in swf8 and DHTML, we now  
>> warn you, but in swf9/10 you will get a type error.  Eventually, we  
>> hope to be able to manage delegates completely internally to LZX.
>>
>>> Related: is there any way to trick the AS3 runtime into accepting  
>>> a dynamic POJSO as an LzEventable?
>>
>>
>> Usually when people run into this issue updating their code, they  
>> can either use a closure or add a method to the sender that  
>> trampolines to the non-LzEventable.
>>
>> If you have a particular example, I can comment further.
>