Blame | Last modification | View Log | RSS feed
if(!dojo._hasResource["dojox.timing.Sequence"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
dojo._hasResource["dojox.timing.Sequence"] = true;
dojo.provide("dojox.timing.Sequence");
dojo.experimental("dojox.timing.Sequence"); // in case it gets moved/renamed somewhere soon
dojo.declare("dojox.timing.Sequence",null,{
// summary:
// This class provides functionality to really sequentialize
// function calls. You need to provide a list of functions and
// some parameters for each (like: pauseBefore) and they will
// be run one after another. This can be very useful for slideshows
// or alike things.
//
// description:
// This array will contain the sequence defines resolved, so that
// ie. repeat:10 will result in 10 elements in the sequence, so
// the repeat handling is easier and we don't need to handle that
// many extra cases. Also the doneFunction, if given is added at the
// end of the resolved-sequences.
// _defsResolved: Array
// The resolved sequence, for easier handling.
_defsResolved: [],
// This is the time to wait before goOn() calls _go(), which
// mostly results from a pauseAfter for a function that returned
// false and is later continued by the external goOn() call.
// The time to wait needs to be waited in goOn() where the
// sequence is continued.
// _goOnPause: Integer
// The pause to wait before really going on.
_goOnPause: 0,
_running: false,
go: function(/* Array */defs, /* function|Array? */doneFunction){
// summary:
//
// defs: Array
// the sequence of actions
// doneFunction: Function|Array?
// The function to call when done
this._running = true;
var self = this;
dojo.forEach(defs, function(cur){
if(cur.repeat > 1){
var repeat = cur.repeat;
for(var j=0; j<repeat ;j++){
cur.repeat = 1;
self._defsResolved.push(cur);
}
}else{
self._defsResolved.push(cur);
}
});
var last = defs[defs.length-1];
if (doneFunction) {
self._defsResolved.push({func: doneFunction});
}
// stop the sequence, this actually just sets this._running to false
self._defsResolved.push({func: [this.stop, this]});
this._curId = 0;
this._go();
},
_go: function(){
// summary: Execute one task of this._defsResolved.
//
// if _running was set to false stop the sequence, this is the
// case when i.e. stop() was called.
if(!this._running){
return;
}
var cur = this._defsResolved[this._curId];
this._curId += 1;
// create the function to call, the func property might be an array, which means
// [function, context, parameter1, parameter2, ...]
function resolveAndCallFunc(func) {
var ret = null;
if(dojo.isArray(func)){
// Two elements might only be given when the function+context
// is given, this is nice for using this, ie: [this.func, this]
if(func.length>2){
ret = func[0].apply(func[1], func.slice(2));
}else{
ret = func[0].apply(func[1]);
}
}else{
ret = func();
}
return ret;
}
if(this._curId >= this._defsResolved.length){
resolveAndCallFunc(cur.func); // call the last function, since it is the doneFunction we dont need to handle pause stuff
// don't go on and call this._go() again, we are done
return;
}
var self = this;
if(cur.pauseAfter){
if(resolveAndCallFunc(cur.func)!==false){
window.setTimeout(function() {self._go()}, cur.pauseAfter);
}else{
this._goOnPause = cur.pauseAfter;
}
}else if(cur.pauseBefore){
var x = function(){
if(resolveAndCallFunc(cur.func)!==false){
self._go()
}
};
window.setTimeout(x, cur.pauseBefore);
}else{
if(resolveAndCallFunc(cur.func)!==false){
this._go();
}
}
},
goOn: function(){
// summary: This method just provides a hook from the outside, so that
// an interrupted sequence can be continued.
if(this._goOnPause){
var self = this;
setTimeout(function(){ self._go() }, this._goOnPause);
this._goOnPause = 0; // reset it, so if the next one doesnt set it we dont use the old pause
}else{ this._go(); }
},
stop: function(){
// summary: Stop the currently running sequence.
// description:
// This can only interrupt the sequence not the last function that
// had been started. If the last function was i.e. a slideshow
// that is handled inside a function that you have given as
// one sequence item it cant be stopped, since it is not controlled
// by this object here. In this case it would be smarter to
// run the slideshow using a sequence object so you can also stop
// it using this method.
this._running = false;
}
});
}