1 // Copyright (c) 2013 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
7 tvcm.require('tvcm.raf');
8 tvcm.require('tvcm.promise');
10 tvcm.exportTo('tracing.importer', function() {
12 * A task is a combination of a run callback, a set of subtasks, and an after
15 * When executed, a task does the following things:
16 * 1. Runs its callback
17 * 2. Runs its subtasks
18 * 3. Runs its after callback.
20 * The list of subtasks and after task can be mutated inside step #1 but as
21 * soon as the task's callback returns, the subtask list and after task is
22 * fixed and cannot be changed again.
24 * Use task.after().after().after() to describe the toplevel passes that make
25 * up your computation. Then, use subTasks to add detail to each subtask as it
28 * taskA = new Task(function() { pieces = getPieces(); });
29 * taskA.after(function(taskA) {
30 * pieces.forEach(function(piece) {
31 * taskA.subTask(function(taskB) { piece.process(); }, this);
37 function Task(runCb, thisArg) {
38 if (thisArg === undefined)
39 throw new Error('Almost certainly, you meant to pass a thisArg.');
41 this.thisArg_ = thisArg;
42 this.afterTask_ = undefined;
48 * See constructor documentation on semantics of subtasks.
50 subTask: function(cb, thisArg) {
51 if (cb instanceof Task)
52 this.subTasks_.push(cb);
54 this.subTasks_.push(new Task(cb, thisArg));
55 return this.subTasks_[this.subTasks_.length - 1];
59 * Runs the current task and returns the task that should be executed next.
62 this.runCb_.call(this.thisArg_, this);
63 var subTasks = this.subTasks_;
64 this.subTasks_ = undefined; // Prevent more subTasks from being posted.
67 return this.afterTask_;
69 // If there are subtasks, then we want to execute all the subtasks and
70 // then this task's afterTask. To make this happen, we update the
71 // afterTask of all the subtasks so the point upward to each other, e.g.
72 // subTask[0].afterTask to subTask[1] and so on. Then, the last subTask's
73 // afterTask points at this task's afterTask.
74 for (var i = 1; i < subTasks.length; i++)
75 subTasks[i - 1].afterTask_ = subTasks[i];
76 subTasks[subTasks.length - 1].afterTask_ = this.afterTask_;
81 * See constructor documentation on semantics of after tasks.
83 after: function(cb, thisArg) {
85 throw new Error('Has an after task already');
86 if (cb instanceof Task)
89 this.afterTask_ = new Task(cb, thisArg);
90 return this.afterTask_;
94 Task.RunSynchronously = function(task) {
97 curTask = curTask.run();
101 * Runs a task using raf.requestIdleCallback, returning
102 * a promise for its completion.
104 Task.RunWhenIdle = function(task) {
105 return new tvcm.Promise(function(resolver) {
107 function runAnother() {
109 curTask = curTask.run();
117 tvcm.requestIdleCallback(runAnother);
123 tvcm.requestIdleCallback(runAnother);