Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(1)

Side by Side Diff: client/observable/EventBatch.dart

Issue 9382027: Move client/{base, observable, layout, touch, util, view} to samples/ui_lib . (Closed) Base URL: http://dart.googlecode.com/svn/branches/bleeding_edge/dart/
Patch Set: '' Created 8 years, 10 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « client/observable/ChangeEvent.dart ('k') | client/observable/observable.dart » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
(Empty)
1 // Copyright (c) 2011, the Dart project authors. Please see the AUTHORS file
2 // for details. All rights reserved. Use of this source code is governed by a
3 // BSD-style license that can be found in the LICENSE file.
4
5 /**
6 * Accumulates change events from several observable objects.
7 *
8 * wrap() is public and used by client code. The other methods are used by
9 * AbstractObservable, which works with this class to implement batching.
10 */
11 class EventBatch {
12
13 /** The current active batch, if any. */
14 static EventBatch current;
15
16 /** Used to generate unique ids for observable objects. */
17 static int nextUid;
18
19 /** Map from observable object's uid to their tracked events. */
20 // TODO(sigmund): use [Observable] instead of [int] when [Map] can support it,
21 Map<int, EventSummary> summaries;
22
23 /** Whether this batch is currently firing and therefore is sealed. */
24 bool sealed = false;
25
26 /**
27 * Private constructor that shouldn't be used externally. Use [wrap] to ensure
28 * that a batch exists when running a function.
29 */
30 EventBatch._internal() : summaries = new Map<int, EventSummary>();
31
32 /**
33 * Ensure there is an event batch where [userFunction] can accumuluate events.
34 * When the batch is complete, fire all events at once.
35 */
36 static Function wrap(userFunction(var a)) {
37 return (e) {
38 if (current == null) {
39 // Not in a batch so create one.
40 final batch = new EventBatch._internal();
41 current = batch;
42 var result = null;
43 try {
44 // TODO(jmesserly): don't return here, otherwise an exception in
45 // the finally clause will cause it to rerun. See bug#5350131.
46 result = userFunction(e);
47 } finally {
48 assert(current == batch); // no one should've changed this
49 // TODO(jmesserly): VM doesn't seem to like nested try/finally, so
50 // set current to null before _notify. That will ensure we're back
51 // to the right state, even if _notify throws.
52 current = null;
53 batch._notify();
54 }
55 return result;
56 } else {
57 // Already in a batch, so just use it.
58 // TODO(rnystrom): Re-entrant calls to wrap() are kind of hairy. They
59 // can occur in at least one known place:
60 // 1. You respond to an event handler by calling a function with wrap()
61 // (i.e. the normal way we wrap event handlers).
62 // 2. In that handler, you spawn an XHR. You give it a callback which
63 // is also calling wrap, so that when it's later invoked, that is in
64 // a batch too.
65 // 3. Because of an error the XHR fails and calls the callback
66 // immediately instead of unwinding the stack past the first wrap()
67 // and then calling it asynchronously.
68 // This check handles that, but ideally we'd have a more elegant way of
69 // notifying after a series of changes like a onEventHandlerFinished
70 // event or something built into the DOM API.
71 return userFunction(e);
72 }
73 };
74 }
75
76 /** Returns a unique global id for observable objects. */
77 static int genUid() {
78 if (nextUid == null) {
79 nextUid = 1;
80 }
81 return nextUid++;
82 }
83
84 /** Retrieves the events associated with {@code obj}. */
85 EventSummary getEvents(Observable obj) {
86 int uid = obj.uid;
87 EventSummary summary = summaries[uid];
88 if (summary == null) {
89 assert (!sealed);
90 summary = new EventSummary(obj);
91 summaries[uid] = summary;
92 }
93 return summary;
94 }
95
96 /** Fires all events at once. */
97 void _notify() {
98 assert(!sealed);
99 sealed = true;
100 for (final summary in summaries.getValues()) {
101 summary.notify();
102 }
103 }
104 }
OLDNEW
« no previous file with comments | « client/observable/ChangeEvent.dart ('k') | client/observable/observable.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698