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

Side by Side Diff: tools/dom/templates/html/impl/impl_Window.darttemplate

Issue 2039963003: Add zone task support for request-anim. (Closed) Base URL: git@github.com:dart-lang/sdk.git@master
Patch Set: Address comments. Created 4 years, 5 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
« no previous file with comments | « tests/html/request_animation_task_test.dart ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file 1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file
2 // for details. All rights reserved. Use of this source code is governed by a 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. 3 // BSD-style license that can be found in the LICENSE file.
4 4
5 part of $LIBRARYNAME; 5 part of $LIBRARYNAME;
6 6
7 typedef void RemoveFrameRequestMapping(int id);
8
9 /**
10 * The task object representing animation-frame requests.
11 *
12 * For historical reasons, [Window.requestAnimationFrame] returns an integer
13 * to users. However, zone tasks must be unique objects, and an integer can
14 * therefore not be used as task object. The [Window] class thus keeps a mapping
15 * from the integer ID to the corresponding task object. All zone related
16 * operations work on this task object, whereas users of
17 * [Window.requestAnimationFrame] only see the integer ID.
18 *
19 * Since this mapping takes up space, it must be removed when the
20 * animation-frame task has triggered. The default implementation does this
21 * automatically, but intercepting implementations of `requestAnimationFrame`
22 * must make sure to call the [AnimationFrameTask.removeMapping]
23 * function that is provided in the task specification.
24 *
25 * *Experimental*. This class may disappear without notice.
26 */
27 abstract class AnimationFrameTask {
28 /** The ID that is returned to users. */
29 int get id;
30
31 /** The zone in which the task will run. */
32 Zone get zone;
33
34 /**
35 * Cancels the animation-frame request.
36 *
37 * A call to [Window.cancelAnimationFrame] with an `id` argument equal to [id]
38 * forwards the request to this function.
39 *
40 * Zones that intercept animation-frame requests implement this method so
41 * that they can react to cancelation requests.
42 */
43 void cancel(Window window);
44
45 /**
46 * Maps animation-frame request IDs to their task objects.
47 */
48 static final Map<int, _AnimationFrameTask> _tasks = {};
49
50 /**
51 * Removes the mapping from [id] to [AnimationFrameTask].
52 *
53 * This function must be invoked by user-implemented animation-frame
54 * tasks, before running [callback].
55 *
56 * See [AnimationFrameTask].
57 */
58 static void removeMapping(int id) {
59 _tasks.remove(id);
60 }
61 }
62
63 class _AnimationFrameTask implements AnimationFrameTask {
64 final int id;
65 final Zone zone;
66 final FrameRequestCallback _callback;
67
68 _AnimationFrameTask(this.id, this.zone, this._callback);
69
70 void cancel(Window window) {
71 window._cancelAnimationFrame(this.id);
72 }
73 }
74
75 /**
76 * The task specification for an animation-frame request.
77 *
78 * *Experimental*. This class may disappear without notice.
79 */
80 class AnimationFrameRequestSpecification implements TaskSpecification {
81 /**
82 * The window on which [Window.requestAnimationFrame] was invoked.
83 */
84 final Window window;
85
86 /**
87 * The callback that is executed when the animation-frame is ready.
88 *
89 * Note that the callback hasn't been registered in any zone when the `create`
90 * function (passed to [Zone.createTask]) is invoked.
91 */
92 final FrameRequestCallback callback;
93
94 AnimationFrameRequestSpecification(this.window, this.callback);
95
96 String get name => "dart.html.request-animation-frame";
97 bool get isOneShot => true;
98 }
99
7 @DocsEditable() 100 @DocsEditable()
8 $if DART2JS 101 $if DART2JS
9 $(ANNOTATIONS)@Native("Window,DOMWindow") 102 $(ANNOTATIONS)@Native("Window,DOMWindow")
10 $(CLASS_MODIFIERS)class $CLASSNAME$EXTENDS$IMPLEMENTS { 103 $(CLASS_MODIFIERS)class $CLASSNAME$EXTENDS$IMPLEMENTS {
11 $else 104 $else
12 $(ANNOTATIONS)$(NATIVESPEC)$(CLASS_MODIFIERS)class $CLASSNAME$EXTENDS$IMPLEMENTS { 105 $(ANNOTATIONS)$(NATIVESPEC)$(CLASS_MODIFIERS)class $CLASSNAME$EXTENDS$IMPLEMENTS {
13 $endif 106 $endif
14 107
15 /** 108 /**
16 * Returns a Future that completes just before the window is about to 109 * Returns a Future that completes just before the window is about to
17 * repaint so the user can draw an animation frame. 110 * repaint so the user can draw an animation frame.
18 * 111 *
19 * If you need to later cancel this animation, use [requestAnimationFrame] 112 * If you need to later cancel this animation, use [requestAnimationFrame]
20 * instead. 113 * instead.
21 * 114 *
22 * The [Future] completes to a timestamp that represents a floating 115 * The [Future] completes to a timestamp that represents a floating
23 * point value of the number of milliseconds that have elapsed since the page 116 * point value of the number of milliseconds that have elapsed since the page
24 * started to load (which is also the timestamp at this call to 117 * started to load (which is also the timestamp at this call to
25 * animationFrame). 118 * animationFrame).
26 * 119 *
27 * Note: The code that runs when the future completes should call 120 * Note: The code that runs when the future completes should call
28 * [animationFrame] again for the animation to continue. 121 * [animationFrame] again for the animation to continue.
29 */ 122 */
30 Future<num> get animationFrame { 123 Future<num> get animationFrame {
31 var completer = new Completer<num>.sync(); 124 var completer = new Completer<num>.sync();
32 requestAnimationFrame((time) { 125 requestAnimationFrame(completer.complete);
33 completer.complete(time);
34 });
35 return completer.future; 126 return completer.future;
36 } 127 }
37 128
38 $if DART2JS 129 $if DART2JS
39 /** 130 /**
40 * The newest document in this window. 131 * The newest document in this window.
41 * 132 *
42 * ## Other resources 133 * ## Other resources
43 * 134 *
44 * * [Loading web 135 * * [Loading web
(...skipping 63 matching lines...) Expand 10 before | Expand all | Expand 10 after
108 * request. This value only needs to be saved if you intend to call 199 * request. This value only needs to be saved if you intend to call
109 * [cancelAnimationFrame] so you can specify the particular animation to 200 * [cancelAnimationFrame] so you can specify the particular animation to
110 * cancel. 201 * cancel.
111 * 202 *
112 * Note: The supplied [callback] needs to call [requestAnimationFrame] again 203 * Note: The supplied [callback] needs to call [requestAnimationFrame] again
113 * for the animation to continue. 204 * for the animation to continue.
114 */ 205 */
115 @DomName('Window.requestAnimationFrame') 206 @DomName('Window.requestAnimationFrame')
116 int requestAnimationFrame(FrameRequestCallback callback) { 207 int requestAnimationFrame(FrameRequestCallback callback) {
117 _ensureRequestAnimationFrame(); 208 _ensureRequestAnimationFrame();
118 return _requestAnimationFrame(_wrapZone/*<dynamic, num>*/(callback)); 209 if (identical(Zone.current, Zone.ROOT)) {
210 return _requestAnimationFrame(callback);
211 }
212 var spec = new AnimationFrameRequestSpecification(this, callback);
213 var task = Zone.current.createTask/*<AnimationFrameTask>*/(
214 _createAnimationFrameTask, spec);
215 AnimationFrameTask._tasks[task.id] = task;
216 return task.id;
217 }
218
219 static _AnimationFrameTask _createAnimationFrameTask(
220 AnimationFrameRequestSpecification spec, Zone zone) {
221 var task;
222 var id = spec.window._requestAnimationFrame((num time) {
223 AnimationFrameTask.removeMapping(task.id);
224 zone.runTask(_runAnimationFrame, task, time);
225 });
226 var callback = zone.registerUnaryCallback(spec.callback);
227 task = new _AnimationFrameTask(id, zone, callback);
228 return task;
229 }
230
231 static void _runAnimationFrame(_AnimationFrameTask task, num time) {
232 task._callback(time);
119 } 233 }
120 234
121 /** 235 /**
122 * Cancels an animation frame request. 236 * Cancels an animation frame request.
123 * 237 *
124 * ## Other resources 238 * ## Other resources
125 * 239 *
126 * * [Window.cancelAnimationFrame](https://developer.mozilla.org/en-US/docs/We b/API/Window.cancelAnimationFrame) 240 * * [Window.cancelAnimationFrame](https://developer.mozilla.org/en-US/docs/We b/API/Window.cancelAnimationFrame)
127 * from MDN. 241 * from MDN.
128 */ 242 */
129 void cancelAnimationFrame(int id) { 243 void cancelAnimationFrame(int id) {
130 _ensureRequestAnimationFrame(); 244 _ensureRequestAnimationFrame();
131 _cancelAnimationFrame(id); 245 var task = AnimationFrameTask._tasks.remove(id);
246 if (task == null) {
247 // Assume that the animation frame request wasn't intercepted by a zone.
248 _cancelAnimationFrame(id);
249 return;
250 }
251 task.cancel(this);
132 } 252 }
133 253
134 @JSName('requestAnimationFrame') 254 @JSName('requestAnimationFrame')
135 int _requestAnimationFrame(FrameRequestCallback callback) native; 255 int _requestAnimationFrame(FrameRequestCallback callback) native;
136 256
137 @JSName('cancelAnimationFrame') 257 @JSName('cancelAnimationFrame')
138 void _cancelAnimationFrame(int id) native; 258 void _cancelAnimationFrame(int id) native;
139 259
140 _ensureRequestAnimationFrame() { 260 _ensureRequestAnimationFrame() {
141 if (JS('bool', 261 if (JS('bool',
(...skipping 233 matching lines...) Expand 10 before | Expand all | Expand 10 after
375 {bool useCapture: false}) { 495 {bool useCapture: false}) {
376 $if DART2JS 496 $if DART2JS
377 // Specify the generic type for _ElementEventStreamImpl only in dart2js to 497 // Specify the generic type for _ElementEventStreamImpl only in dart2js to
378 // avoid checked mode errors in dartium. 498 // avoid checked mode errors in dartium.
379 return new _ElementListEventStreamImpl<BeforeUnloadEvent>(e, _eventType, use Capture); 499 return new _ElementListEventStreamImpl<BeforeUnloadEvent>(e, _eventType, use Capture);
380 $else 500 $else
381 return new _ElementListEventStreamImpl(e, _eventType, useCapture); 501 return new _ElementListEventStreamImpl(e, _eventType, useCapture);
382 $endif 502 $endif
383 } 503 }
384 } 504 }
OLDNEW
« no previous file with comments | « tests/html/request_animation_task_test.dart ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698