Okay, here's a strawman for a new-and-improved proposal. All these would be
in core.
// "Deferred command" = on the other side of the event loop
interface DeferredCommands {
  public static DeferredCommands get();

  public void add(Command cmd);
  public void add(Command cmd, boolean asap);  // asap = faster than
setTimeout(0)
  public void addPause();
}

// "Finally command" = before you end the current stack trace
interface FinallyCommands {
  public static FinallyCommands get();

  public void add(Command cmd);
}

// "Incremental command" = call repeatedly quickly to avoid SSWs
interface IncrementalCommands {
  public static IncrementalCommands get();

  public void add(Command cmd);
  public void add(Command cmd, boolean asap);
}

// "Timed command" = call based clock time (aka regular old timers)
interface TimedCommands {
  public static TimedCommand get();

  public TimerController scheduleOnce(Command cmd, int millis);
  public TimerController scheduleRecurring(Command cmd, int millis);
}

// Allows optional control over a timer after it's created.
// If the return values in scheduleOnce, etc. aren't used, extra code can
maybe optimize away.
interface TimerController {
  public void pause();
  public void resume();
  public void cancel();
}

I think that maybe consolidating timers into this mix might be a bit much,
but, then again, if we're graduating "Command" to core, then it seems like
it would be nice to make it the uniform callback interface.

-- Bruce

On Thu, Sep 3, 2009 at 9:28 PM, Bruce Johnson <[email protected]> wrote:

> I like it a lot Ray. (To be completely honest, I knew you were going to say
> all that, so I decided to sandbag and let you do the typing :-)
>
> I question if it's really appropriate to explicitly say "PreEventLoop" and
> "PostEventLoop" considering that...sometimes...the event loop can actually
> run re-entrantly. Those names sound like a very strong guarantee that I
> don't think we can reliably guarantee. It's more like
> "PreCurrentJavaScriptStackFullyUnwinding" and "PostEventLoop".
>
> Actually, to take a step back (which is my very favorite thing to do),
> there are several kinds of things that could be consolidated:
>
> 1) Single-shot timers
> 2) Recurring timers
> 3) Incremental commands that run as soon as possible after the event loop
> (faster than setTimeout(0))
> 4) Incremental commands that run after the event loop via setTimeout(0)
> 5) Deferred commands that run as soon as possible after the event loop
> (faster than setTimeout(0))
> 6) Deferred commands that run after the event loop via setTimeout(0)
> 7) Execute-this-before-you-unwind-the-JS-stack-in-which-it-was-enqueued
> (aka BatchedCommand)
> 8) Arguably, runAsync (although it's purpose is so functionally different
> it would probalby be a mistake to munge it in)
>
> #3 and #5 might look funny, but it is generally possible to run code
> *after* the event loop but *much* sooner than setTimeout(0), which is
> usually clamped to some pretty long duration such as 10ms. The reason you
> wouldn't want to do #3 and #5 as the default for deferred commands is that
> it would keep the CPU overly busy if you did it a bunch in a row. It would
> very likely drain mobile batteries quickly, even.
>
> @Ray (or anyone): Can you think of an awesome way to reconcile those behind
> a consistent API?
>
>
>
>
>
>
>
> On Thu, Sep 3, 2009 at 4:52 PM, Joel Webber <[email protected]> wrote:
>
>> ++(++Ray)
>> Anything we can do to sensibly get this crap out of .user and into .core
>> (or some other common location) would be very, very good.
>> If, as a side-effect, we could get DeferredCommand to *not* use
>> IncrementalCommand (the latter brings in fairly significant dependencies
>> that are enough to matter for small apps), that would be even better.
>>
>>
>> On Thu, Sep 3, 2009 at 4:46 PM, Scott Blum <[email protected]> wrote:
>>
>>> ++Ray.
>>>
>>>
>>> On Thu, Sep 3, 2009 at 4:38 PM, Ray Ryan <[email protected]> wrote:
>>>
>>>>   The mechanism is just brilliant. I have reservations about the api.
>>>>
>>>> <bikeshed>
>>>> "it seemed kinda nice to have one less type"
>>>>
>>>> Except that we have one more type, BatchedCommand, which looks exactly
>>>> like Command, except with a different name, and you have to subclass it
>>>> rather than implement it...
>>>>
>>>> A simple thing we could do is:
>>>>
>>>>    - create com.google.gwt.core.client,
>>>>    - change com.google.gwt.user.client.Command to extend the new one
>>>>    - deprecate com.google.gwt.user.client.Command
>>>>    - And have BatchedCommand accept com.google.gwt.core.client
>>>>
>>>> And the two names, "DeferredComand" and "BatchedCommand", don't give
>>>> much clue as to which does what. And of course BatchedCommand doesn't
>>>> actually provide any batching service.
>>>>
>>>> If we were doing all this from scratch, I suspect we would wind up with
>>>> something like this in core (presuming we're happy with IncrementalCommand
>>>> and addPause):
>>>>
>>>>     package com.google.gwt.core.dispatch
>>>>
>>>>     public interface Command {
>>>>       void execute();
>>>>     }
>>>>
>>>>     public interface IncrementalCommand {
>>>>       boolean execute();
>>>>     }
>>>>
>>>>     public class PreEventLoopDispatcher {
>>>>       public static PreEventLoopDispatcher get(); { ... }
>>>>
>>>>       public void addCommand(Command c);
>>>>     }
>>>>
>>>>     public class PostEventLoopDispatcher {
>>>>       public static PostEventLoopDispatcher get(); { ... }
>>>>
>>>>       public void addCommand(Command c);
>>>>       public void addCommand(IncrementalCommand c);
>>>>       public void addPause();
>>>>     }
>>>>
>>>> Note the avoidance of statics to make commands more testable, a
>>>> recurring subject.
>>>>
>>>> Seems like we could do this, deprecate the existing classes, and make
>>>> them wrappers around the new.
>>>>
>>>> </bikeshed>
>>>>
>>>> On Wed, Sep 2, 2009 at 11:36 PM, Ray Cromwell <[email protected]>wrote:
>>>>
>>>>>
>>>>> Could this also be used as a general pattern to batch DOM updates from
>>>>> multiple Widgets performing updates? e.g. a current approach to avoid the
>>>>> overhead, of say, installing a dozen widgets, is to concatenate all the 
>>>>> HTML
>>>>> together, slam it into innerHTML, and then wrap the widgets around the 
>>>>> HTML.
>>>>> But this rather breaks the nice OO design people are used to with widgets.
>>>>> Templating is an alternative, but I'm wondering, why can't we make all of
>>>>> the attachment stuff happen via a batch queue. A special optimizer on the
>>>>> queue could even recognize instances of when DOM updates can be coalesced
>>>>> and leverage documentFragment or innerHTML.
>>>>> e.g.
>>>>>
>>>>> VerticalPanel vp = ...
>>>>> vp.add(new Label())
>>>>> vp.add(new Label())
>>>>>
>>>>> The objects are constructed, but the HTML mutations are
>>>>> deferred/queued. When adding a DOM mutation to the queue, you could check 
>>>>> if
>>>>> existing queue data isOrHasChild the new DOM mutation element, and if so,
>>>>> just modify the queue element (coalesce) rather than appending another 
>>>>> queue
>>>>> item. Then, when processing the queue, you only need to add the roots to 
>>>>> the
>>>>> DOM, attaching/modifying enmasse.
>>>>>
>>>>> This would preserve the OO-ness of constructing widget hierarchies
>>>>> without requiring 'foreign' string-based templating.
>>>>>
>>>>> -Ray
>>>>>
>>>>>
>>>>>  On Wed, Sep 2, 2009 at 5:13 PM, Bruce Johnson <[email protected]>wrote:
>>>>>
>>>>>>  On Wed, Sep 2, 2009 at 6:07 PM, Scott Blum <[email protected]>wrote:
>>>>>>
>>>>>>> I do agree with John that we should really discuss how this can be
>>>>>>> implemented.
>>>>>>
>>>>>>
>>>>>> It's already implemented!
>>>>>>
>>>>>>
>>>>>>>  Is there some magic trick to make the browser execute a piece of
>>>>>>> code at the time you want, or do we need to go and modify all our event 
>>>>>>> code
>>>>>>> (like with the global uncaught exception handler)?
>>>>>>
>>>>>>
>>>>>> No trick, it's as bad as you'd hope it wasn't. On the positive side,
>>>>>> it's already been done -- I'm just augmenting the tests for the various
>>>>>> subsystems such as RequestBuilder and event dispatching to make sure we
>>>>>> tighten the correctness noose as much as possible.
>>>>>>
>>>>>> Longer term, Bob and I both would really like to find a general
>>>>>> mechanism for making this pattern easy to do from any path into a GWT 
>>>>>> module
>>>>>> from "the outside", exactly along the lines of what Matt was talking 
>>>>>> about.
>>>>>> I think rolling this functionality into gwt-exporter (and then rolling 
>>>>>> that
>>>>>> sort of functionality directly into GWT proper) will get us pretty far 
>>>>>> down
>>>>>> the road.
>>>>>>
>>>>>> Code review request forthcoming, possibly tomorrow.
>>>>>>
>>>>>> -- Bruce
>>>>>>
>>>>>>
>>>>>>
>>>>>
>>>>
>>>>
>>>>
>>>
>>>
>>>
>>
>> >>
>>
>

--~--~---------~--~----~------------~-------~--~----~
http://groups.google.com/group/Google-Web-Toolkit-Contributors
-~----------~----~----~----~------~----~------~--~---

Reply via email to