[483] | 1 | define([ |
---|
| 2 | "dojo/_base/kernel", |
---|
| 3 | "dojo/_base/array", |
---|
| 4 | "dojo/_base/declare", |
---|
| 5 | "dojo/_base/lang", |
---|
| 6 | "./_base" |
---|
| 7 | ], function(dojo){ |
---|
| 8 | dojo.experimental("dojox.timing.Sequence"); |
---|
| 9 | |
---|
| 10 | return dojo.declare("dojox.timing.Sequence", null, { |
---|
| 11 | // summary: |
---|
| 12 | // This class provides functionality to really sequentialize |
---|
| 13 | // function calls. You need to provide a list of functions and |
---|
| 14 | // some parameters for each (like: pauseBefore) and they will |
---|
| 15 | // be run one after another. This can be very useful for slideshows |
---|
| 16 | // or alike things. |
---|
| 17 | // |
---|
| 18 | // description: |
---|
| 19 | // This array will contain the sequence defines resolved, so that |
---|
| 20 | // ie. repeat:10 will result in 10 elements in the sequence, so |
---|
| 21 | // the repeat handling is easier and we don't need to handle that |
---|
| 22 | // many extra cases. Also the doneFunction, if given is added at the |
---|
| 23 | // end of the resolved-sequences. |
---|
| 24 | |
---|
| 25 | /*===== |
---|
| 26 | // _defsResolved: Array |
---|
| 27 | // The resolved sequence, for easier handling. |
---|
| 28 | _defsResolved: [], |
---|
| 29 | =====*/ |
---|
| 30 | |
---|
| 31 | // This is the time to wait before goOn() calls _go(), which |
---|
| 32 | // mostly results from a pauseAfter for a function that returned |
---|
| 33 | // false and is later continued by the external goOn() call. |
---|
| 34 | // The time to wait needs to be waited in goOn() where the |
---|
| 35 | // sequence is continued. |
---|
| 36 | |
---|
| 37 | // _goOnPause: Integer |
---|
| 38 | // The pause to wait before really going on. |
---|
| 39 | _goOnPause: 0, |
---|
| 40 | |
---|
| 41 | _running: false, |
---|
| 42 | |
---|
| 43 | constructor: function(){ |
---|
| 44 | this._defsResolved = []; |
---|
| 45 | }, |
---|
| 46 | |
---|
| 47 | go: function(/* Array */defs, /* Function|Array? */doneFunction){ |
---|
| 48 | // summary: |
---|
| 49 | // Run the passed sequence definition |
---|
| 50 | // defs: Array |
---|
| 51 | // The sequence of actions |
---|
| 52 | // doneFunction: Function|Array? |
---|
| 53 | // The function to call when done |
---|
| 54 | this._running = true; |
---|
| 55 | dojo.forEach(defs, function(cur){ |
---|
| 56 | if(cur.repeat > 1){ |
---|
| 57 | var repeat = cur.repeat; |
---|
| 58 | for(var j = 0; j < repeat; j++){ |
---|
| 59 | cur.repeat = 1; |
---|
| 60 | this._defsResolved.push(cur); |
---|
| 61 | } |
---|
| 62 | }else{ |
---|
| 63 | this._defsResolved.push(cur); |
---|
| 64 | } |
---|
| 65 | }, this); |
---|
| 66 | var last = defs[defs.length - 1]; |
---|
| 67 | if(doneFunction){ |
---|
| 68 | this._defsResolved.push({ func: doneFunction }); |
---|
| 69 | } |
---|
| 70 | // stop the sequence, this actually just sets this._running to false |
---|
| 71 | this._defsResolved.push({ func: [this.stop, this] }); |
---|
| 72 | this._curId = 0; |
---|
| 73 | this._go(); |
---|
| 74 | }, |
---|
| 75 | |
---|
| 76 | _go: function(){ |
---|
| 77 | // summary: |
---|
| 78 | // Execute one task of this._defsResolved. |
---|
| 79 | |
---|
| 80 | // if _running was set to false stop the sequence, this is the |
---|
| 81 | // case when i.e. stop() was called. |
---|
| 82 | if(!this._running){ |
---|
| 83 | return; |
---|
| 84 | } |
---|
| 85 | var cur = this._defsResolved[this._curId]; |
---|
| 86 | this._curId += 1; |
---|
| 87 | // create the function to call, the func property might be an array, which means |
---|
| 88 | // [function, context, parameter1, parameter2, ...] |
---|
| 89 | function resolveAndCallFunc(func) { |
---|
| 90 | var ret = null; |
---|
| 91 | if(dojo.isArray(func)){ |
---|
| 92 | // Two elements might only be given when the function+context |
---|
| 93 | // is given, this is nice for using this, ie: [this.func, this] |
---|
| 94 | if(func.length>2){ |
---|
| 95 | ret = func[0].apply(func[1], func.slice(2)); |
---|
| 96 | }else{ |
---|
| 97 | ret = func[0].apply(func[1]); |
---|
| 98 | } |
---|
| 99 | }else{ |
---|
| 100 | ret = func(); |
---|
| 101 | } |
---|
| 102 | return ret; |
---|
| 103 | } |
---|
| 104 | |
---|
| 105 | if(this._curId >= this._defsResolved.length){ |
---|
| 106 | resolveAndCallFunc(cur.func); // call the last function, since it is the doneFunction we dont need to handle pause stuff |
---|
| 107 | // don't go on and call this._go() again, we are done |
---|
| 108 | return; |
---|
| 109 | } |
---|
| 110 | |
---|
| 111 | if(cur.pauseAfter){ |
---|
| 112 | if(resolveAndCallFunc(cur.func) !== false){ |
---|
| 113 | setTimeout(dojo.hitch(this, "_go"), cur.pauseAfter); |
---|
| 114 | }else{ |
---|
| 115 | this._goOnPause = cur.pauseAfter; |
---|
| 116 | } |
---|
| 117 | }else if(cur.pauseBefore){ |
---|
| 118 | var x = dojo.hitch(this,function(){ |
---|
| 119 | if(resolveAndCallFunc(cur.func) !== false){ |
---|
| 120 | this._go() |
---|
| 121 | } |
---|
| 122 | }); |
---|
| 123 | setTimeout(x, cur.pauseBefore); |
---|
| 124 | }else{ |
---|
| 125 | if(resolveAndCallFunc(cur.func) !== false){ |
---|
| 126 | this._go(); |
---|
| 127 | } |
---|
| 128 | } |
---|
| 129 | }, |
---|
| 130 | |
---|
| 131 | goOn: function(){ |
---|
| 132 | // summary: |
---|
| 133 | // This method just provides a hook from the outside, so that |
---|
| 134 | // an interrupted sequence can be continued. |
---|
| 135 | if(this._goOnPause){ |
---|
| 136 | setTimeout(dojo.hitch(this, "_go"), this._goOnPause); |
---|
| 137 | this._goOnPause = 0; // reset it, so if the next one doesnt set it we dont use the old pause |
---|
| 138 | }else{ this._go(); } |
---|
| 139 | }, |
---|
| 140 | |
---|
| 141 | stop: function(){ |
---|
| 142 | // summary: |
---|
| 143 | // Stop the currently running sequence. |
---|
| 144 | // description: |
---|
| 145 | // This can only interrupt the sequence not the last function that |
---|
| 146 | // had been started. If the last function was i.e. a slideshow |
---|
| 147 | // that is handled inside a function that you have given as |
---|
| 148 | // one sequence item it cant be stopped, since it is not controlled |
---|
| 149 | // by this object here. In this case it would be smarter to |
---|
| 150 | // run the slideshow using a sequence object so you can also stop |
---|
| 151 | // it using this method. |
---|
| 152 | this._running = false; |
---|
| 153 | } |
---|
| 154 | |
---|
| 155 | }); |
---|
| 156 | }); |
---|