1 /** A function queue that will only execute at *most* every interval miliseconds.
  2     @class
  3     @example
  4       myQueue = MBX.Queue.create({ interval: 500 });
  5       myQueue.add(function () {
  6           //do something 'spensive
  7       });
  8 */    
  9 MBX.Queue = MBX.JsModel.create("Queue", {
 10     
 11     /**
 12         Instances of a Queue
 13         @name MBX.Queue#
 14         @class A single instance of a MBX.Queue
 15     */
 16     instanceMethods: /** @lends MBX.Queue# */ {
 17         defaults: {
 18             interval: 1000,
 19             functions: [],
 20             singleItem: false,
 21             selfStopped: false
 22         },
 23         
 24         _fireTimerEvent: function () {
 25             MBX.EventHandler.fireCustom(this, "timer_complete", {
 26                 queue: this
 27             });
 28         },
 29         
 30         _setupTimer: function () {
 31             var interval = this.get('interval');
 32             var timer = this.get('timer');
 33             if (timer) {
 34                 clearTimeout(timer);
 35             }
 36             this.set('timer', setTimeout(function () {
 37                 this._fireTimerEvent();
 38                 this._setupTimer();
 39             }.bind(this), interval));            
 40         },
 41         
 42         /** stop the queue
 43             @returns {MBX.Queue#instance} the queue
 44         */
 45         stop: function () {
 46             var timer = this.get('timer');
 47             if (timer) {
 48                 clearTimeout(timer);
 49                 this.set('timer', null);
 50             }
 51             return this;
 52         },
 53         
 54         /** start the queue back up - the queue is NOT started at creation time
 55             @returns {MBX.Queue#instance} the queue
 56         */
 57         start: function () {
 58             if (this.get('functions').length === 0) {
 59                 this.set('selfStopped', true);
 60             } else {
 61                 this._setupTimer();
 62             }
 63             return this;
 64         },
 65         
 66         /** adds a function to the queue
 67             @params {Function} func the function to add
 68         */
 69         add: function (func) {
 70             if (this.get("singleItem")) {
 71                 this.get('functions')[0] = func;
 72             } else {
 73                 this.get('functions').push(func);
 74             }
 75             if (this.get('selfStopped')) {
 76                 this._setupTimer();
 77                 this.set('selfStopped', false);
 78             }
 79         },
 80         
 81         /** removes the function that is passed in from the queue
 82             @params {Function} func the function to remove
 83         */
 84         remove: function (func) {
 85             var iterator = function (f) {
 86                 return f == func;
 87             };
 88             this.set("functions", $A(this.get("functions")).reject(iterator));
 89         },
 90         
 91         /** returns but does not remove the next function in the queue */
 92         nextFunction: function () {
 93             return this.get('functions')[0];
 94         },
 95         
 96         /** fires and removes the next pending function in the queue */
 97         fireNextFunction: function () {
 98             var funcs = this.get('functions');
 99             funcs.shift()();
100             if (funcs.length === 0) {
101                 this.stop();
102                 this.set('selfStopped', true);
103             }
104         }
105     }
106     
107 });
108