Created
October 24, 2012 20:35
-
-
Save abstraktor/3948703 to your computer and use it in GitHub Desktop.
Timer
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
define([ | |
'underscore', | |
'backbone' | |
], function(_, Backbone){ | |
/** | |
* static variables | |
**/ | |
var nativeInterval = 10; | |
/** | |
* @constructor | |
* @param optional {Int} initial interval | |
* @example run the t1 to tick every second and t5 to tick every fifth second | |
* var t1 = new Timer(1000), | |
* t5 = new Timer(5000), | |
* logger = function(){console.log(arguments);}; | |
* t1.bind('tick', logger); | |
* t5.bind('tick', logger); | |
* t1.start();t5.start(); | |
**/ | |
var Timer = function(interval){ | |
//instance variables | |
this._timePassed = 0; | |
this._running = false; | |
this._interval = interval || 1000; | |
}; | |
_.extend(Timer.prototype, Backbone.Events, { | |
/** | |
* starts the timer and triggers a 'tick' every __interval_ milliseconds | |
**/ | |
start: function(){ | |
if(this._running) | |
return; | |
this._running = true; | |
//kick off! | |
this.timerId = setInterval(_.bind(this._tick, this), nativeInterval); | |
this.trigger('start'); | |
}, | |
/** | |
* stops the timer immediately and resets the passed time | |
**/ | |
stop: function(){ | |
clearInterval(this.timerId); | |
this._timePassed = 0; | |
this._running = false; | |
this.trigger('stop'); | |
}, | |
/** | |
* @private | |
**/ | |
_setTimePassed: function(newTimePassed){ | |
this._timePassed = newTimePassed; | |
//raise events | |
if(this._timePassed >= this._interval){ | |
this._timePassed -= this._interval; | |
this.trigger("tick", this._interval); | |
} | |
}, | |
/** | |
* @private | |
* called every time, the native _interval timer ticks | |
**/ | |
_tick: function(){ | |
if(this._running) | |
this._setTimePassed(this._timePassed+nativeInterval); | |
}, | |
// Getters and Setters | |
/** | |
* @brief sets the tick-_interval in milliseconds | |
* @param newInterval {Int} the new _interval | |
* if the timer is _running and the passed time exceeds the _interval, it will trigger *one* immediate tick and restart counting at 0 | |
**/ | |
setInterval: function(newInterval){ | |
this._interval = newInterval; | |
if(this._timePassed > newInterval){ | |
this._timePassed = 0; | |
this.trigger("tick", this._interval); | |
} | |
}, | |
getInterval: function(){ | |
return this._interval; | |
}, | |
isRunning: function(){ | |
return this._running; | |
}, | |
/** | |
* @private | |
**/ | |
_getTimePassed: function(){ | |
return this._timePassed; | |
}, | |
}); | |
return Timer; | |
}); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
define([ | |
'utils/timer' | |
], function(Timer) { | |
describe("Timer", function() { | |
var timer, | |
spy; | |
beforeEach(function(){ | |
timer = new Timer; | |
spy = jasmine.createSpy(); | |
timer.bind("tick", spy); | |
spy.reset(); | |
}); | |
it("#start to trigger 'tick'", function() { | |
timer.setInterval(500); | |
timer.start(); | |
//not have been called | |
timer._setTimePassed(499); | |
expect(spy).not.toHaveBeenCalled(); | |
//have been called once | |
timer._setTimePassed(500); | |
expect(spy).toHaveBeenCalled(); | |
expect(spy).toHaveBeenCalledWith(500); // the same, as | |
// expect(spy.calls[0].args[0]).toEqual(500); | |
//have been called again | |
timer._setTimePassed(500); | |
expect(spy.calls.length).toEqual(2); | |
}); | |
it("#setInterval to a lower value", function(){ | |
timer.setInterval(1000); | |
timer.setInterval(500); | |
expect(spy).not.toHaveBeenCalled(); | |
timer._setTimePassed(500); | |
expect(spy).toHaveBeenCalledWith(500); | |
expect(spy.calls.length).toEqual(1); | |
}); | |
it("#setInterval while running", function(){ | |
expect(spy.calls.length).toEqual(0); | |
timer.setInterval(1000); | |
timer.start(); | |
timer._setTimePassed(599); | |
//raises 'tick' once and resets the timePassed to zero | |
timer.setInterval(200); | |
expect(spy).toHaveBeenCalledWith(200); | |
expect(spy.calls.length).toEqual(1); | |
expect(timer._getTimePassed()).toEqual(0); | |
}); | |
it("#stop", function(){ | |
timer.start(); | |
timer.stop(); | |
expect(spy).not.toHaveBeenCalled(); | |
expect(spy.calls.length).toEqual(0); | |
}); | |
it("times parallel", function(){ | |
var t1 = new Timer(10), | |
t5 = new Timer(50), | |
spy1 = jasmine.createSpy('spy1'), | |
spy5 = jasmine.createSpy('spy5'); | |
t1.bind('tick', spy1); | |
t5.bind('tick', spy5); | |
t1.start(); | |
t5.start(); | |
//expect none was called | |
runs(function(){ | |
expect(spy1).not.toHaveBeenCalled(); | |
expect(spy5).not.toHaveBeenCalled(); | |
}); | |
waits(13); //until it runs the following | |
//expect spy1 was called | |
runs(function(){ | |
expect(spy1).toHaveBeenCalled(); | |
expect(spy5).not.toHaveBeenCalled(); | |
spy1.reset(); | |
spy5.reset(); | |
}); | |
waits(43); | |
//expect spy5 was called and spy1 was called 4 times (additionally) | |
runs(function(){ | |
expect(spy1.calls.length).toEqual(4); | |
expect(spy5.calls.length).toEqual(1); | |
spy1.reset(); | |
spy5.reset(); | |
}); | |
runs(function(){ | |
t5.stop(); | |
}); | |
waits(53); | |
runs(function(){ | |
expect(spy1.calls.length).toEqual(5); | |
expect(spy5).not.toHaveBeenCalled(); | |
}); | |
}); | |
}); | |
}) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment