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