This sounds like mostly confusion in the meaning of the `callOnIdle` API and 
perhaps subtle differences in the contract of setTimeout and setInterval in 
DHTML vs. Flash runtimes:

The idle kernel tries to simulate the Flash concept of code that would run 
during the "vertical blanking interval", i.e., at the frame rate of the 
"movie".  To that end, it is trying to generate an "idle" event based on a 
nominal "framerate" (even though there is no such thing in DHTML).  This idle 
event stream is probably important for animators, but even the animator code 
admits to knowing that the idle event is not precise -- they calculate their 
motion based on actual elapsed time.

The name `callOnIdle` makes it sound like "call this function back when there 
is nothing else happening"; but the implementation is "call this function back 
on the next 'idle' event", where the idle event is just a ticker that goes off 
every 1/framerate seconds.

What we are trying to do with these measurement callbacks is really "let the 
runtime layout and update the display and then, once that display is updated, 
call us back so we can measure things".

What's the difference?  I think it is the following:

With callOnIdle (as currently implemented):

1. Some event triggers debugger output
2. Debugger queues the callOnIdle
3. (sometimes) the idle interval is already up, while the debugger code is 
still running
4. Hence, rather than update the display, the idle callback is run immediately
5. You get the wrong values

With setTimeout(0) [Which is the DHTML idiom for "call me back when synchronous 
code is done"]

1. Some event triggers debugger output
2. Debugger queues setTimeout
3. Debugger code finishes running
4. Display updates
5. Now you are really done with synchronous code and you get your callback

It may be that this _is_ a bug in the DHTML implementation of callOnIdle, since 
it appears the contract from SWF days was "call me during the vertical blanking 
interval".  It may be that the SWF implementation of setInterval is such that 
display updates run _before_ both setTimeout and setInterval callbacks, whereas 
in DHTML only setTimeout guarantees that the display update will happen.  I'm 
intuiting that the difference lies in setInterval noticing that the event is 
passed and hence skips the display update in an attempt to signal the event as 
accurately as possible, whereas setTimeout(0) is, by convention, call me back 
only when there's nothing else happening.  SWF, OTOH, being movie-oriented, 
always does the display update before the callbacks.

Bottom line:  Someone needs to do some low-level testing of setInterval and 
setTimeout.  And we might need to adjust the DHTML implementation of callOnIdle 
to use setTimeout rather than the simulated idle event to maintain 
compatibility.


On 2010-03-29, at 23:59, Henry Minsky wrote:

> I noticed a bug in the debugger scrolling in DHTML,  after Max's change to
> text measurement callbacks. See LPP-8862. It looked like
> a race condition where the code was not getting an updated scroll height
> after it adds text to
> the debugger's output text window.
> 
> The weird thing is that there is already code in the debugger to  wait a
> frame to defer looking at the text  scrollheight. In DHTML.  It uses the
> lz.Idle.callOnIdle to wait a frame and then look at the scrollheight.
> 
> When I changed it to use lz.Timer.addTimer() to call itself back, instead of
> callOnIdle(), then the
> bug went away.
> 
> The difference, I think, is in the kernel implentation, callOnIdle uses
> setInterval(), whereas addTimer uses
> setTimeout().
> 
> I'm not sure what implications this has for us, but maybe it means we
> should  be careful to use setTimeout in the
> DHTML runtime when we want these layout callbacks to work properly, rather
> relying on anything that uses setInterval.
> 
> -- 
> Henry Minsky
> Software Architect
> [email protected]


Reply via email to