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