Subversion Repositories Applications.papyrus

Rev

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;
        }
}); 

}