Base.Timer = Base.Comp.inherits({ /** This property contains the setTimeout() result value being used for the * timer. */ timer: null, /** This property contains the timestamp of the last executed tick. */ lastAt: 0, /** This property contains the timestamp at which the timer was paused. */ pausedAt: 0, /** This property is used internally to lock access to the instance's * properties. */ locked: false, /** This property indicates whether the timer is currently running. */ running: false, /** The constructor initialises a new timer instance. It does not start * the timer, however - the start() method has to be called. * @param miliseconds the interval for the timer, in milliseconds * @param repeat a boolean indicating whether the timer fires * only once (false) or repeatedly (true) */ constructor: function (miliseconds, repeat) { this.base(); this.addSlot('start'); this.addSlot('stop'); this.addSlot('restart'); this.addSlot('pause'); this.addEvent('Tick'); this.miliseconds = miliseconds; this.repeat = repeat; }, /** This method stops the timer then destroys the instance. */ destroy: function () { while (this.locked) ; this.locked = true; if (this.running) { clearTimeout(this.timer); this.lastAt = this.pausedAt = 0; this.running = false; } this.base(); }, /** This method initialises the timer itself. */ start: function() { while (this.locked) ; this.locked = true; if (!this.running) { this.running = true; this.lastAt = new Date().getTime(); this.setTimer(); } this.locked = false; }, /** This method stops the timer from running. */ stop: function() { while (this.locked) ; this.locked = true; if (this.running) { clearTimeout(this.timer); this.lastAt = this.pausedAt = 0; this.running = false; } this.locked = false; }, /** This method restarts the timer. It is equivalent to calling * stop() then start(), but it is faster. */ restart: function() { while (this.locked) ; this.locked = true; if (this.running) { clearTimeout(this.timer); this.pausedAt = 0; } else { this.running = true; } this.lastAt = new Date().getTime(); this.setTimer(); this.locked = false; }, /** This method puts the timer on pause if it is currently running or * restarts it if it had been paused earlier. */ pause: function () { while (this.locked) ; this.locked = true; if (this.running) { if (this.pausedAt == 0) { this.pausedAt = new Date().getTime(); if (this.timer) { clearTimeout(this.timer); } } else { this.setTimer(); this.pausedAt = 0; } } this.locked = false; }, /** This method is called automatically by the setTimeout() timer; if * the current instance is still supposed to be running, it will: * - re-run setTimeout() to initialise the next tick if the timer is * in "repeat" mode, * - trigger the Tick event. */ tick: function() { while (this.locked) ; this.locked = true; var re; if (re = (this.running && !this.pausedAt)) { if (this.repeat) { this.lastAt = new Date().getTime(); this.setTimer(); } else { this.running = false; this.timer = null; this.lastAt = 0; } } this.locked = false; if (re) { this.onTick(); } }, /** This method is used internally in order to run setTimeout() with * the required parameters. */ setTimer: function() { var _t = this.pausedAt ? (this.miliseconds - this.pausedAt + this.lastAt) : this.miliseconds; this.timer = setTimeout("Base.Comp.get(" + this._cid + ").tick()", _t); } });