commit extjs-2.2.1
[extjs.git] / source / util / TaskMgr.js
1 /*\r
2  * Ext JS Library 2.2.1\r
3  * Copyright(c) 2006-2009, Ext JS, LLC.\r
4  * licensing@extjs.com\r
5  * \r
6  * http://extjs.com/license\r
7  */\r
8 \r
9 /**\r
10  * @class Ext.util.TaskRunner\r
11  * Provides the ability to execute one or more arbitrary tasks in a multithreaded manner.  Generally, you can use\r
12  * the singleton {@link Ext.TaskMgr} instead, but if needed, you can create separate instances of TaskRunner.  Any\r
13  * number of separate tasks can be started at any time and will run independently of each other.  Example usage:\r
14  * <pre><code>\r
15 // Start a simple clock task that updates a div once per second\r
16 var task = {\r
17     run: function(){\r
18         Ext.fly('clock').update(new Date().format('g:i:s A'));\r
19     },\r
20     interval: 1000 //1 second\r
21 }\r
22 var runner = new Ext.util.TaskRunner();\r
23 runner.start(task);\r
24 </code></pre>\r
25  * @constructor\r
26  * @param {Number} interval (optional) The minimum precision in milliseconds supported by this TaskRunner instance\r
27  * (defaults to 10)\r
28  */\r
29 Ext.util.TaskRunner = function(interval){\r
30     interval = interval || 10;\r
31     var tasks = [], removeQueue = [];\r
32     var id = 0;\r
33     var running = false;\r
34 \r
35     // private\r
36     var stopThread = function(){\r
37         running = false;\r
38         clearInterval(id);\r
39         id = 0;\r
40     };\r
41 \r
42     // private\r
43     var startThread = function(){\r
44         if(!running){\r
45             running = true;\r
46             id = setInterval(runTasks, interval);\r
47         }\r
48     };\r
49 \r
50     // private\r
51     var removeTask = function(t){\r
52         removeQueue.push(t);\r
53         if(t.onStop){\r
54             t.onStop.apply(t.scope || t);\r
55         }\r
56     };\r
57 \r
58     // private\r
59     var runTasks = function(){\r
60         if(removeQueue.length > 0){\r
61             for(var i = 0, len = removeQueue.length; i < len; i++){\r
62                 tasks.remove(removeQueue[i]);\r
63             }\r
64             removeQueue = [];\r
65             if(tasks.length < 1){\r
66                 stopThread();\r
67                 return;\r
68             }\r
69         }\r
70         var now = new Date().getTime();\r
71         for(var i = 0, len = tasks.length; i < len; ++i){\r
72             var t = tasks[i];\r
73             var itime = now - t.taskRunTime;\r
74             if(t.interval <= itime){\r
75                 var rt = t.run.apply(t.scope || t, t.args || [++t.taskRunCount]);\r
76                 t.taskRunTime = now;\r
77                 if(rt === false || t.taskRunCount === t.repeat){\r
78                     removeTask(t);\r
79                     return;\r
80                 }\r
81             }\r
82             if(t.duration && t.duration <= (now - t.taskStartTime)){\r
83                 removeTask(t);\r
84             }\r
85         }\r
86     };\r
87 \r
88     /**\r
89      * @member Ext.util.TaskRunner\r
90      * @method start\r
91      * Starts a new task.\r
92      * @param {Object} task A config object that supports the following properties:<ul>\r
93      * <li><code>run</code> : Function<div class="sub-desc">The function to execute each time the task is run. The\r
94      * function will be called at each interval and passed the <code>args</code> argument if specified.  If a\r
95      * particular scope is required, be sure to specify it using the <code>scope</scope> argument.</div></li>\r
96      * <li><code>interval</code> : Number<div class="sub-desc">The frequency in milliseconds with which the task\r
97      * should be executed.</div></li>\r
98      * <li><code>args</code> : Array<div class="sub-desc">(optional) An array of arguments to be passed to the function\r
99      * specified by <code>run</code>.</div></li>\r
100      * <li><code>scope</code> : Object<div class="sub-desc">(optional) The scope in which to execute the\r
101      * <code>run</code> function.</div></li>\r
102      * <li><code>duration</code> : Number<div class="sub-desc">(optional) The length of time in milliseconds to execute\r
103      * the task before stopping automatically (defaults to indefinite).</div></li>\r
104      * <li><code>repeat</code> : Number<div class="sub-desc">(optional) The number of times to execute the task before\r
105      * stopping automatically (defaults to indefinite).</div></li>\r
106      * </ul>\r
107      * @return {Object} The task\r
108      */\r
109     this.start = function(task){\r
110         tasks.push(task);\r
111         task.taskStartTime = new Date().getTime();\r
112         task.taskRunTime = 0;\r
113         task.taskRunCount = 0;\r
114         startThread();\r
115         return task;\r
116     };\r
117 \r
118     /**\r
119      * @member Ext.util.TaskRunner\r
120      * @method stop\r
121      * Stops an existing running task.\r
122      * @param {Object} task The task to stop\r
123      * @return {Object} The task\r
124      */\r
125     this.stop = function(task){\r
126         removeTask(task);\r
127         return task;\r
128     };\r
129 \r
130     /**\r
131      * @member Ext.util.TaskRunner\r
132      * @method stopAll\r
133      * Stops all tasks that are currently running.\r
134      */\r
135     this.stopAll = function(){\r
136         stopThread();\r
137         for(var i = 0, len = tasks.length; i < len; i++){\r
138             if(tasks[i].onStop){\r
139                 tasks[i].onStop();\r
140             }\r
141         }\r
142         tasks = [];\r
143         removeQueue = [];\r
144     };\r
145 };\r
146 \r
147 /**\r
148  * @class Ext.TaskMgr\r
149  * A static {@link Ext.util.TaskRunner} instance that can be used to start and stop arbitrary tasks.  See\r
150  * {@link Ext.util.TaskRunner} for supported methods and task config properties.\r
151  * <pre><code>\r
152 // Start a simple clock task that updates a div once per second\r
153 var task = {\r
154     run: function(){\r
155         Ext.fly('clock').update(new Date().format('g:i:s A'));\r
156     },\r
157     interval: 1000 //1 second\r
158 }\r
159 Ext.TaskMgr.start(task);\r
160 </code></pre>\r
161  * @singleton\r
162  */\r
163 Ext.TaskMgr = new Ext.util.TaskRunner();