Indeed, I was talking about case 3.
There is still another problem, beside tying a method directly to an
event, there are at least two places where you're indirectly tying it to
an event-like structure: LzTimer and LzIdle. (see "LzTimer#addTimer(..)"
and "LzIdle#removeCallIdleDelegates(..)" resp. "LzIdleKernel.__update()".)
So, what we actually need to do, is to change the LzDelegate-API.
New rule: every method for a delegate must accept at least one argument,
(also see "LzDelegate#execute(..)", so that's definitely necessary.)
What to do: move the argument-length checking from
"LzDelegate#register(..)" to the LzDelegate-constructor.
And as you said, the route 3a should be clearly discouraged, for
instance the public API for "LzDataset#doRequest()" or "LzState#apply()"
has been changed to get around swf9 warnings. A good example for what we
should do, is "LzLazyReplicationManager#__LZhandleUpdate(..)". This
method was added to be compatible to the event-system.
However, we really want to force people to update all their
applications?! So the step from 4.0.x (or even 3.x) to 4.2 will require
quite some work.
As an example, a call to "LzFocus#clearFocus()" needs to changed like
so, from:
new LzDelegate(LzFocus, "clearFocus", this, "onfoo");
to:
new LzDelegate(this, "_handleFoo", this, "onfoo");
+ private function _handleFoo (ignore:*) {LzFocus.clearFocus();}
or to (short-form):
new LzDelegate({_handle: function (ignore) {LzFocus.clearFocus();}},
"_handle", this, "onfoo");
On 5/3/2008 10:18 PM, P T Withington wrote:
Yes, I am not _really_ happy with the solution, but I think it is the
best compromise.
I think there are three cases to consider:
1) You are writing a method that you will use as an event handler, e.g.,
<handler name="onfoo" method="handleOnfoo" />
In this case, you have specifically declared your intent to handle a
sendEvent message, which by definition calls your handler method with
one value. You had better accept that value, even if you ignore it;
otherwise, your method is not eligible to be an event handler. So you
define your method:
<method name="handleOnfoo" args="value">
Debug.debug("onfoo sent: %w", value);
</method>
If your handler method does not accept the sendEvent value, you will
get a warning and you should fix it.
2) You have a method that you want called when an event happens, e.g.,
<... onfoo="eventHappens()" ...>
or
<handler name="onfoo">
eventHappens();
</handler>
In this case, you are using the open tag event syntax or the handler
tag to make the connection between an event and a method, which
automatically introduces an 'event handling wrapper' with the
requisite argument processing, so your method can take whatever form
you like. (Note: you can declare args in the handler tag if you want
the sendEvent value, but if you don't the tag compiler will
automatically declare one ignore arg for you.)
3) You are basically cheating. You are trying to use a method that
was not intended to be an event handler and tie it directly to an
event. You could get away with this in the past because the runtime
did not care if methods were called with the correct number and type
of arguments. You can't any more. You have two choices:
a) Add a nonsensical `ignore` parameter to your method to match the
sendEvent call (and repair all other calls of your method to pass a
`null` value).
b) Do the right thing: either use the <handler> tag, or if you are in
Javascript, your own wrapper, to mediate between the event and the
other method.
--
I think what you are complaining about is case 3, which was done
flagrantly throughout our system, probably as a premature
optimization. I think we just have to fix these cases. If we
_really_ think the event and handler are so central to the performance
of the system, then we will have to add that `ignore` parameter (3a).
But most likely, we can fix this cleanly by using the handler tag or a
javascript wrapper (3b), which should not be as objectionable.
I _do_ think it is important to discourage people from taking the 3a
route as much as possible. (Although I may have been lazy and done
this myself in a couple of places already.)
On 2008-05-03, at 10:12 EDT, André Bargull wrote:
We're adding an "ignore"-argument all over the place, so that our
event-system works in swf9.
This a really cumbersome work and some of these warnings don't really
help you:
WARNING @lz/gridcolumn.lzx#90: Invalid delegate: «LzCursorService
function(0)#0| kernel/swf/LzMouseKernel.as#59/21» (must accept one
argument to handle .resizer.onmouseout)
This warning was triggered by "LzSprite#setCursor(..)" (swf), because
there is this delegate:
this._muDel = new LzDelegate( LzMouseKernel , 'restoreCursor',
this.owner , 'onmouseout');
And as "LzMouseKernel#restoreCursor()" does expect an argument (why
should it!?), you get this warning.
If we followed our current practice, we would add an
"ignore"-argument to "LzMouseKernel#restoreCursor()". But that's not
really convincing, to change a semi-public API (see LzCursor) just to
get around this. Also think about user applications, which may have a
delegate to i.e. "LzFocus#clearFocus()". They'll get a warning,
because the LzFocus-API is not compatible to the event-API. So, do we
need to change the public "LzFocus#clearFocus()" API because of this?
Surely not!
Therefore, I'd like to propose:
- either do the function wrapping in "LzDelegate#register(..)" in
swf9 automatically, but without any warnings (but consider possible
performance disadvantages!)
- or add at compile to every function without any arguments a default
"ignore"-argument, so that it is compatible to our event-system.
Thoughts?