3 Copyright (c) 2013 The Chromium Authors. All rights reserved.
4 Use of this source code is governed by a BSD-style license that can be
5 found in the LICENSE file.
7 <link rel="import" href="/base/raf.html">
12 tv.exportTo('tracing.importer', function() {
14 * A task is a combination of a run callback, a set of subtasks, and an after
17 * When executed, a task does the following things:
18 * 1. Runs its callback
19 * 2. Runs its subtasks
20 * 3. Runs its after callback.
22 * The list of subtasks and after task can be mutated inside step #1 but as
23 * soon as the task's callback returns, the subtask list and after task is
24 * fixed and cannot be changed again.
26 * Use task.after().after().after() to describe the toplevel passes that make
27 * up your computation. Then, use subTasks to add detail to each subtask as it
30 * taskA = new Task(function() { pieces = getPieces(); });
31 * taskA.after(function(taskA) {
32 * pieces.forEach(function(piece) {
33 * taskA.subTask(function(taskB) { piece.process(); }, this);
39 function Task(runCb, thisArg) {
40 if (thisArg === undefined)
41 throw new Error('Almost certainly, you meant to pass a thisArg.');
43 this.thisArg_ = thisArg;
44 this.afterTask_ = undefined;
50 * See constructor documentation on semantics of subtasks.
52 subTask: function(cb, thisArg) {
53 if (cb instanceof Task)
54 this.subTasks_.push(cb);
56 this.subTasks_.push(new Task(cb, thisArg));
57 return this.subTasks_[this.subTasks_.length - 1];
61 * Runs the current task and returns the task that should be executed next.
64 this.runCb_.call(this.thisArg_, this);
65 var subTasks = this.subTasks_;
66 this.subTasks_ = undefined; // Prevent more subTasks from being posted.
69 return this.afterTask_;
71 // If there are subtasks, then we want to execute all the subtasks and
72 // then this task's afterTask. To make this happen, we update the
73 // afterTask of all the subtasks so the point upward to each other, e.g.
74 // subTask[0].afterTask to subTask[1] and so on. Then, the last subTask's
75 // afterTask points at this task's afterTask.
76 for (var i = 1; i < subTasks.length; i++)
77 subTasks[i - 1].afterTask_ = subTasks[i];
78 subTasks[subTasks.length - 1].afterTask_ = this.afterTask_;
83 * See constructor documentation on semantics of after tasks.
85 after: function(cb, thisArg) {
87 throw new Error('Has an after task already');
88 if (cb instanceof Task)
91 this.afterTask_ = new Task(cb, thisArg);
92 return this.afterTask_;
96 Task.RunSynchronously = function(task) {
99 curTask = curTask.run();
103 * Runs a task using raf.requestIdleCallback, returning
104 * a promise for its completion.
106 Task.RunWhenIdle = function(task) {
107 return new Promise(function(resolve, reject) {
109 function runAnother() {
111 curTask = curTask.run();
114 console.error(e.stack);
119 tv.requestIdleCallback(runAnother);
125 tv.requestIdleCallback(runAnother);