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

Unified Diff: sdk/lib/html/dart2js/html_dart2js.dart

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, 6 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:
Download patch
« no previous file with comments | « no previous file | sdk/lib/html/dartium/html_dartium.dart » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: sdk/lib/html/dart2js/html_dart2js.dart
diff --git a/sdk/lib/html/dart2js/html_dart2js.dart b/sdk/lib/html/dart2js/html_dart2js.dart
index 124684b9c29d0920c760c87bcab9c394f0429038..2a968eef81efcd20cd202bae0a5c0bead70f3b76 100644
--- a/sdk/lib/html/dart2js/html_dart2js.dart
+++ b/sdk/lib/html/dart2js/html_dart2js.dart
@@ -34485,6 +34485,99 @@ class WheelEvent extends MouseEvent {
// BSD-style license that can be found in the LICENSE file.
+typedef void RemoveFrameRequestMapping(int id);
+
+/**
+ * The task object representing animation-frame requests.
+ *
+ * For historical reasons, [Window.requestAnimationFrame] returns an integer
+ * to users. However, zone tasks must be unique objects, and an integer can
+ * therefore not be used as task object. The [Window] class thus keeps a mapping
+ * from the integer ID to the corresponding task object. All zone related
+ * operations work on this task object, whereas users of
+ * [Window.requestAnimationFrame] only see the integer ID.
+ *
+ * Since this mapping takes up space, it must be removed when the
+ * animation-frame task has triggered. The default implementation does this
+ * automatically, but intercepting implementations of `requestAnimationFrame`
+ * must make sure to call the [AnimationFrameTask.removeMapping]
+ * function that is provided in the task specification.
+ *
+ * *Experimental*. This class may disappear without notice.
+ */
+abstract class AnimationFrameTask {
+ /** The ID that is returned to users. */
+ int get id;
+
+ /** The zone in which the task will run. */
+ Zone get zone;
+
+ /**
+ * Cancels the animation-frame request.
+ *
+ * A call to [Window.cancelAnimationFrame] with an `id` argument equal to [id]
+ * forwards the request to this function.
+ *
+ * Zones that intercept animation-frame requests implement this method so
+ * that they can react to cancelation requests.
+ */
+ void cancel(Window window);
+
+ /**
+ * Maps animation-frame request IDs to their task objects.
+ */
+ static final Map<int, _AnimationFrameTask> _tasks = {};
+
+ /**
+ * Removes the mapping from [id] to [AnimationFrameTask].
+ *
+ * This function must be invoked by user-implemented animation-frame
+ * tasks, before running [callback].
+ *
+ * See [AnimationFrameTask].
+ */
+ static void removeMapping(int id) {
+ _tasks.remove(id);
+ }
+}
+
+class _AnimationFrameTask implements AnimationFrameTask {
+ final int id;
+ final Zone zone;
+ final FrameRequestCallback _callback;
+
+ _AnimationFrameTask(this.id, this.zone, this._callback);
+
+ void cancel(Window window) {
+ window._cancelAnimationFrame(this.id);
+ }
+}
+
+/**
+ * The task specification for an animation-frame request.
+ *
+ * *Experimental*. This class may disappear without notice.
+ */
+class AnimationFrameRequestSpecification implements TaskSpecification {
+ /**
+ * The window on which [Window.requestAnimationFrame] was invoked.
+ */
+ final Window window;
+
+ /**
+ * The callback that is executed when the animation-frame is ready.
+ *
+ * Note that the callback hasn't been registered in any zone when the `create`
+ * function (passed to [Zone.createTask]) is invoked.
+ */
+ final FrameRequestCallback callback;
+
+ AnimationFrameRequestSpecification(this.window, this.callback);
+
+ String get name => "dart.html.request-animation-frame";
+ bool get isOneShot => true;
+}
+
@DocsEditable()
/**
* Top-level container for the current browser tab or window.
@@ -34540,9 +34633,7 @@ class Window extends EventTarget implements WindowEventHandlers, WindowBase, Glo
*/
Future<num> get animationFrame {
var completer = new Completer<num>.sync();
- requestAnimationFrame((time) {
- completer.complete(time);
- });
+ requestAnimationFrame(completer.complete);
return completer.future;
}
@@ -34625,7 +34716,30 @@ class Window extends EventTarget implements WindowEventHandlers, WindowBase, Glo
@DomName('Window.requestAnimationFrame')
int requestAnimationFrame(FrameRequestCallback callback) {
_ensureRequestAnimationFrame();
- return _requestAnimationFrame(_wrapZone/*<dynamic, num>*/(callback));
+ if (identical(Zone.current, Zone.ROOT)) {
+ return _requestAnimationFrame(callback);
+ }
+ var spec = new AnimationFrameRequestSpecification(this, callback);
+ var task = Zone.current.createTask/*<AnimationFrameTask>*/(
+ _createAnimationFrameTask, spec);
+ AnimationFrameTask._tasks[task.id] = task;
+ return task.id;
+ }
+
+ static _AnimationFrameTask _createAnimationFrameTask(
+ AnimationFrameRequestSpecification spec, Zone zone) {
+ var task;
+ var id = spec.window._requestAnimationFrame((num time) {
+ AnimationFrameTask.removeMapping(task.id);
+ zone.runTask(_runAnimationFrame, task, time);
+ });
+ var callback = zone.registerUnaryCallback(spec.callback);
+ task = new _AnimationFrameTask(id, zone, callback);
+ return task;
+ }
+
+ static void _runAnimationFrame(_AnimationFrameTask task, num time) {
+ task._callback(time);
}
/**
@@ -34638,7 +34752,13 @@ class Window extends EventTarget implements WindowEventHandlers, WindowBase, Glo
*/
void cancelAnimationFrame(int id) {
_ensureRequestAnimationFrame();
- _cancelAnimationFrame(id);
+ var task = AnimationFrameTask._tasks.remove(id);
+ if (task == null) {
+ // Assume that the animation frame request wasn't intercepted by a zone.
+ _cancelAnimationFrame(id);
+ return;
+ }
+ task.cancel(this);
}
@JSName('requestAnimationFrame')
« no previous file with comments | « no previous file | sdk/lib/html/dartium/html_dartium.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698