Update To 11.40.268.0
[platform/framework/web/crosswalk.git] / src / third_party / trace-viewer / trace_viewer / tracing / importer / task.html
1 <!DOCTYPE html>
2 <!--
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.
6 -->
7 <link rel="import" href="/base/raf.html">
8
9 <script>
10 'use strict';
11
12 tv.exportTo('tracing.importer', function() {
13   /**
14    * A task is a combination of a run callback, a set of subtasks, and an after
15    * task.
16    *
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.
21    *
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.
25    *
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
28    * runs. For example:
29    *    var pieces = [];
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);
34    *      });
35    *    });
36    *
37    * @constructor
38    */
39   function Task(runCb, thisArg) {
40     if (thisArg === undefined)
41       throw new Error('Almost certainly, you meant to pass a thisArg.');
42     this.runCb_ = runCb;
43     this.thisArg_ = thisArg;
44     this.afterTask_ = undefined;
45     this.subTasks_ = [];
46   }
47
48   Task.prototype = {
49     /*
50      * See constructor documentation on semantics of subtasks.
51      */
52     subTask: function(cb, thisArg) {
53       if (cb instanceof Task)
54         this.subTasks_.push(cb);
55       else
56         this.subTasks_.push(new Task(cb, thisArg));
57       return this.subTasks_[this.subTasks_.length - 1];
58     },
59
60     /**
61      * Runs the current task and returns the task that should be executed next.
62      */
63     run: function() {
64       this.runCb_.call(this.thisArg_, this);
65       var subTasks = this.subTasks_;
66       this.subTasks_ = undefined; // Prevent more subTasks from being posted.
67
68       if (!subTasks.length)
69         return this.afterTask_;
70
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_;
79       return subTasks[0];
80     },
81
82     /*
83      * See constructor documentation on semantics of after tasks.
84      */
85     after: function(cb, thisArg) {
86       if (this.afterTask_)
87         throw new Error('Has an after task already');
88       if (cb instanceof Task)
89         this.afterTask_ = cb;
90       else
91         this.afterTask_ = new Task(cb, thisArg);
92       return this.afterTask_;
93     }
94   };
95
96   Task.RunSynchronously = function(task) {
97     var curTask = task;
98     while (curTask)
99       curTask = curTask.run();
100   }
101
102   /**
103    * Runs a task using raf.requestIdleCallback, returning
104    * a promise for its completion.
105    */
106   Task.RunWhenIdle = function(task) {
107     return new Promise(function(resolve, reject) {
108       var curTask = task;
109       function runAnother() {
110         try {
111           curTask = curTask.run();
112         } catch (e) {
113           reject(e);
114           console.error(e.stack);
115           return;
116         }
117
118         if (curTask) {
119           tv.requestIdleCallback(runAnother);
120           return;
121         }
122
123         resolve();
124       }
125       tv.requestIdleCallback(runAnother);
126     });
127   }
128
129   return {
130     Task: Task
131   };
132 });
133 </script>