timer-stopwatch-dev
Advanced tools
Comparing version 1.0.1 to 1.1.0
@@ -13,4 +13,4 @@ module.exports = function(grunt) { | ||
}, | ||
all: ["*.js", "lib/**/*.js", "api/**/*js", "test/**/*.js"], | ||
testu: ["*.js", "lib/**/*js", "api/**/*js", "test/unit/*js"] | ||
all: ["*.js", "./lib/*.js", "test/**/*js"], | ||
testu: ["./test/**/*js"] | ||
}, | ||
@@ -33,3 +33,3 @@ | ||
testall: { | ||
files: ["*.js", "lib/**/*js", "api/**/*js", "test/unit/*js"], | ||
files: ["*.js", "./lib/*.js", "test/**/*js"], | ||
//tasks: ['jshint:all', 'mochaTest:unit', 'startMongo', 'wait:giveMongoSomeTimeToLoad', 'force:on','mochaTest:integration', 'force:restore', 'stopMongo'], | ||
@@ -43,3 +43,3 @@ tasks: ["jshint:all", "mochaTest:unit"], | ||
testu: { | ||
files: ["*.js", "lib/**/*js", "api/**/*js", "test/unit/*js"], | ||
files: ["./test/**/*js"], | ||
tasks: ["jshint:testu", "mochaTest:unit"], | ||
@@ -46,0 +46,0 @@ options: { |
@@ -8,211 +8,231 @@ // Developed for TKD-Score-Server by Mick Crozier 2015 | ||
function Stopwatch(countDownMS, options) { | ||
STATUS = { | ||
STOPPED: 0, | ||
RUNNING: 1, | ||
COMPLETE: 2 | ||
}; | ||
STATUS = { | ||
STOPPED: 0, | ||
RUNNING: 1, | ||
COMPLETE: 2 | ||
}; | ||
this.stoptime = 0; // the time the clock has been paused at | ||
this.refTime = 0; // reference time when started | ||
this.stoptime = 0; // the time the clock has been paused at | ||
this.refTime = 0; // reference time when started | ||
this.tickTimer = 0; // interval timer for updateTime | ||
this.tickTimer = 0; // interval timer for updateTime | ||
this.almostDoneFired = false; // true if almostDone event has been fired (prevent mlti hits) | ||
this.doneFired = false; // true if done event has been fired (prevent multi hits) | ||
this.almostDoneFired = false; // true if almostDone event has been fired (prevent mlti hits) | ||
this.doneFired = false; // true if done event has been fired (prevent multi hits) | ||
this.countDownMS = countDownMS || false; | ||
this.ms = this.countDownMS || 0; | ||
this._elapsedMS = 0; // number if elapsed milliseconds | ||
this.state = STATUS.STOPPED; // current status of the timer-stopwatch | ||
this.countDownMS = countDownMS || false; | ||
this.ms = this.countDownMS || 0; | ||
this._elapsedMS = 0; // number if elapsed milliseconds | ||
this.state = STATUS.STOPPED; // current status of the timer-stopwatch | ||
//// options | ||
if (!options) { | ||
options = {}; | ||
} | ||
this.refreshRateMS = options.refreshRateMS || 50; | ||
this.almostDoneMS = options.almostDoneMS || 10000; | ||
//// options | ||
if (!options) { | ||
options = {}; | ||
} | ||
this.refreshRateMS = options.refreshRateMS || 50; | ||
this.almostDoneMS = options.almostDoneMS || 10000; | ||
//// init | ||
this.reset(countDownMS); | ||
//// init | ||
this.reset(countDownMS); | ||
return this; // for chaining | ||
return this; // for chaining | ||
} | ||
Stopwatch.prototype = { | ||
/** | ||
* Start the timer | ||
*/ | ||
start: function() { | ||
if (this.tickTimer) { | ||
clearInterval(this.tickTimer); | ||
} | ||
this.state = STATUS.RUNNING; | ||
/** | ||
* Start the timer | ||
*/ | ||
start: function() { | ||
if (this.tickTimer) { | ||
clearInterval(this.tickTimer); | ||
} | ||
this.state = STATUS.RUNNING; | ||
this.refTime = new Date().getTime(); | ||
this.refTime -= this._elapsedMS; | ||
var self = this; | ||
this.tickTimer = setInterval(function() { | ||
self._updateTime(); | ||
}, this.refreshRateMS); | ||
this._updateTime(this); | ||
}, | ||
this.refTime = new Date().getTime(); | ||
this.refTime -= this._elapsedMS; | ||
var self = this; | ||
this.tickTimer = setInterval(function() { | ||
self._updateTime(); | ||
}, this.refreshRateMS); | ||
this._updateTime(this); | ||
}, | ||
/** | ||
* Stops the timer | ||
* | ||
* Emits the event forcestop, | ||
* with one parameter passed to the callback, | ||
* that consists of the elapsed time. | ||
*/ | ||
stop: function() { | ||
if (this.tickTimer) { | ||
clearInterval(this.tickTimer); | ||
} | ||
if (this.state === STATUS.RUNNING) { | ||
this.state = STATUS.STOPPED; // prevents updatedTime being called in an infinite loop | ||
this._updateTime(this); | ||
this.emit("stop"); | ||
this.emit("forcestop"); // for backwards compatability. Will be depreciated | ||
} | ||
}, | ||
/** | ||
* Stops the timer | ||
* | ||
* Emits the event forcestop, | ||
* with one parameter passed to the callback, | ||
* that consists of the elapsed time. | ||
*/ | ||
stop: function() { | ||
if (this.tickTimer) { | ||
clearInterval(this.tickTimer); | ||
} | ||
if (this.state === STATUS.RUNNING) { | ||
this.state = STATUS.STOPPED; // prevents updatedTime being called in an infinite loop | ||
this._updateTime(this); | ||
this.emit("stop"); | ||
this.emit("forcestop"); // for backwards compatability. Will be depreciated | ||
} | ||
}, | ||
/** | ||
* Stop a timer, and reset it to it's defaults. | ||
* Change the countdown value, if a paramter is provided. | ||
* | ||
* @param {Integer} Milliseconds to set the timer to. | ||
*/ | ||
reset: function(countDownMS) { | ||
this.stop(); | ||
this.state = STATUS.STOPPED; | ||
this.doneFired = false; | ||
this.almostDoneFired = false; | ||
this._elapsedMS = 0; | ||
this.refTime = new Date().getTime(); | ||
/** | ||
* Stop a timer, and reset it to it's defaults. | ||
* Change the countdown value, if a paramter is provided. | ||
* | ||
* @param {Integer} Milliseconds to set the timer to. | ||
*/ | ||
reset: function(countDownMS) { | ||
this.stop(); | ||
this.state = STATUS.STOPPED; | ||
this.doneFired = false; | ||
this.almostDoneFired = false; | ||
this._elapsedMS = 0; | ||
this.refTime = new Date().getTime(); | ||
if (countDownMS) { | ||
this.countDownMS = countDownMS; | ||
} | ||
this.ms = this.countDownMS || 0; | ||
if (countDownMS) { | ||
this.countDownMS = countDownMS; | ||
} | ||
this.ms = this.countDownMS || 0; | ||
this.emit("time", { ms: this.ms, seconds: Math.round(this.ms / 1000) }); | ||
}, | ||
this.emit("time", { ms: this.ms, seconds: Math.round(this.ms / 1000) }); | ||
}, | ||
/** | ||
* Toggle the state of the timer. | ||
* If one of start or stop is given as a argument to the | ||
* function then the timer will be forced into that state. | ||
* | ||
* If no argument is given, then the timer's state will be toggled | ||
* between start and stop. | ||
* i.e. The timer will be stopped, if it is running, and the timer | ||
* will be started if the timer is already stopped. | ||
* | ||
* @param {String} start|stop Optional paramter. | ||
* @returns {Boolean} true if the timer is running, false otherwise. | ||
*/ | ||
/** | ||
* Toggle the state of the timer. | ||
* If one of start or stop is given as a argument to the | ||
* function then the timer will be forced into that state. | ||
* | ||
* If no argument is given, then the timer's state will be toggled | ||
* between start and stop. | ||
* i.e. The timer will be stopped, if it is running, and the timer | ||
* will be started if the timer is already stopped. | ||
* | ||
* @param {String} start|stop Optional paramter. | ||
* @returns {Boolean} true if the timer is running, false otherwise. | ||
*/ | ||
startstop: function() { | ||
if (this.state === STATUS.STOPPED) { | ||
this.start(); | ||
return true; | ||
} else { | ||
this.stop(); | ||
return false; | ||
} | ||
}, | ||
startstop: function() { | ||
if (this.state === STATUS.STOPPED) { | ||
this.start(); | ||
return true; | ||
} else { | ||
this.stop(); | ||
return false; | ||
} | ||
}, | ||
/** | ||
* Updates the time | ||
* @private | ||
*/ | ||
_updateTime: function() { | ||
var self = this; | ||
if (self.countDownMS > 0) { | ||
self._timerCountdown(self); | ||
} else { | ||
self._stopwatchCountup(self); | ||
} | ||
}, | ||
/** | ||
* Updates the time | ||
* @private | ||
*/ | ||
_updateTime: function() { | ||
var self = this; | ||
if (self.countDownMS > 0) { | ||
self._timerCountdown(self); | ||
} else { | ||
self._stopwatchCountup(self); | ||
} | ||
}, | ||
/** | ||
* Updates the time for timer | ||
* @private | ||
*/ | ||
_timerCountdown: function() { | ||
var self = this; | ||
var currentTime = new Date().getTime(); | ||
//Find the difference between current time and start time. | ||
self._elapsedMS = currentTime - self.refTime; | ||
/** | ||
* Updates the time for timer | ||
* @private | ||
*/ | ||
_timerCountdown: function() { | ||
var self = this; | ||
var currentTime = new Date().getTime(); | ||
//Find the difference between current time and start time. | ||
self._elapsedMS = currentTime - self.refTime; | ||
var remainingSeconds = self.countDownMS - self._elapsedMS; | ||
if (remainingSeconds < 0) { | ||
remainingSeconds = 0; | ||
} | ||
var remainingSeconds = self.countDownMS - self._elapsedMS; | ||
if (remainingSeconds < 0) { | ||
remainingSeconds = 0; | ||
} | ||
self.ms = remainingSeconds; | ||
self.emit("time", { ms: self.ms, seconds: Math.round(self.ms / 1000) }); | ||
if (remainingSeconds <= 0 && self.state != 0) { | ||
self.stop(); // stop the clock | ||
if (!self.doneFired) { | ||
self.doneFired = true; | ||
self.state = STATUS.COMPLETE; | ||
self.emit("done"); | ||
} | ||
} else if (remainingSeconds < self.almostDoneMS) { | ||
if (!self.almostDoneFired) { | ||
self.almostDoneFired = true; | ||
self.emit("almostdone"); | ||
} | ||
} | ||
}, | ||
self.ms = remainingSeconds; | ||
self.emit("time", { ms: self.ms, seconds: Math.round(self.ms / 1000) }); | ||
if (remainingSeconds <= 0 && self.state != STATUS.STOPPED) { | ||
self.stop(); // stop the clock | ||
if (!self.doneFired) { | ||
self.doneFired = true; | ||
self.state = STATUS.COMPLETE; | ||
self.emit("done"); | ||
} | ||
} else if (remainingSeconds < self.almostDoneMS) { | ||
if (!self.almostDoneFired) { | ||
self.almostDoneFired = true; | ||
self.emit("almostdone"); | ||
} | ||
} | ||
}, | ||
/** | ||
* Updates the time for stopwatch | ||
* @private | ||
*/ | ||
_stopwatchCountup: function() { | ||
var self = this; | ||
var currentTime = new Date().getTime(); | ||
/** | ||
* Updates the time for stopwatch | ||
* @private | ||
*/ | ||
_stopwatchCountup: function() { | ||
var self = this; | ||
var currentTime = new Date().getTime(); | ||
self._elapsedMS = currentTime - self.refTime; | ||
self.ms = self._elapsedMS; | ||
self.emit("time", { ms: self.ms, seconds: Math.round(self.ms / 1000) }); | ||
}, | ||
self._elapsedMS = currentTime - self.refTime; | ||
self.ms = self._elapsedMS; | ||
self.emit("time", { ms: self.ms, seconds: Math.round(self.ms / 1000) }); | ||
}, | ||
/** | ||
* Adds a callback to be fired on the done event | ||
* @returns {Object} itself for chaining | ||
*/ | ||
onDone: function(cb) { | ||
this.on("done", cb); | ||
return this; | ||
}, | ||
getState: function() { | ||
var self = this; | ||
return this.state; | ||
}, | ||
/** | ||
* Adds a callback to be fired on the almostdone event | ||
* @returns {Object} itself for chaining | ||
*/ | ||
onAlmostDone: function(cb) { | ||
this.on('almostdone', cb); | ||
return this; | ||
}, | ||
isStopped: function() { | ||
var self = this; | ||
return self.state == STATUS.STOPPED; | ||
}, | ||
/** | ||
* Adds a callback to be fired on the time event | ||
* @returns {Object} itself for chaining | ||
*/ | ||
onTime: function(cb) { | ||
this.on("time", cb); | ||
return this; | ||
}, | ||
isRunning: function() { | ||
var self = this; | ||
return self.state == STATUS.RUNNING; | ||
}, | ||
/** | ||
* Adds a callback to be fired on the stop event | ||
* @returns {Object} itself for chaining | ||
*/ | ||
onStop: function(cb) { | ||
this.on("stop", cb); | ||
return this; | ||
} | ||
isComplete: function() { | ||
var self = this; | ||
return self.state == STATUS.COMPLETE; | ||
}, | ||
/** | ||
* Adds a callback to be fired on the done event | ||
* @returns {Object} itself for chaining | ||
*/ | ||
onDone: function(cb) { | ||
this.on("done", cb); | ||
return this; | ||
}, | ||
/** | ||
* Adds a callback to be fired on the almostdone event | ||
* @returns {Object} itself for chaining | ||
*/ | ||
onAlmostDone: function(cb) { | ||
this.on("almostdone", cb); | ||
return this; | ||
}, | ||
/** | ||
* Adds a callback to be fired on the time event | ||
* @returns {Object} itself for chaining | ||
*/ | ||
onTime: function(cb) { | ||
this.on("time", cb); | ||
return this; | ||
}, | ||
/** | ||
* Adds a callback to be fired on the stop event | ||
* @returns {Object} itself for chaining | ||
*/ | ||
onStop: function(cb) { | ||
this.on("stop", cb); | ||
return this; | ||
} | ||
}; | ||
@@ -219,0 +239,0 @@ |
{ | ||
"name": "timer-stopwatch-dev", | ||
"version": "1.0.1", | ||
"description": "A stopwatch and countdown timer for node", | ||
"version": "1.1.0", | ||
"description": "A stopwatch and countdown timer for node, maintained.", | ||
"author": "jackyman_cs4@live.it", | ||
@@ -23,8 +23,8 @@ "contributors": [ | ||
"expect.js": "^0.3.1", | ||
"grunt": "^0.4.5", | ||
"grunt": "^1.0.0", | ||
"grunt-cli": "^1.2.0", | ||
"grunt-contrib-jshint": "^0.10.0", | ||
"grunt-contrib-watch": "^0.6.1", | ||
"grunt-contrib-jshint": "^1.1.0", | ||
"grunt-contrib-watch": "^1.0.0", | ||
"grunt-mocha-test": "^0.11.0", | ||
"mocha": "^1.20.1" | ||
"mocha": "^4.0.0" | ||
}, | ||
@@ -31,0 +31,0 @@ "scripts": { |
@@ -5,4 +5,5 @@ # timer-stopwatch | ||
A stopwatch and countdown clock module for node.js | ||
A stopwatch and countdown clock module for node.js, maintained. | ||
## Install | ||
@@ -64,2 +65,6 @@ | ||
timer.reset(countDownMS); // optional countDownMS to reset countdown to that many milliseconds | ||
timer.getState() // Return 0, 1 or 2 if the timer is respectively stopped, running or complete | ||
timer.isStopped() | ||
timer.isRunning() | ||
timer.isComplete() | ||
``` | ||
@@ -85,7 +90,2 @@ | ||
## Breaking Changes in v0.2 | ||
* The `forcestop` event is being depreciated in favour of 'stop'. | ||
* Use the `onTime`, `onAlmostDone`, `onDone` and `onStop` methods in favour of `.on('eventname')`. | ||
## Testing | ||
@@ -101,3 +101,3 @@ | ||
@MickCrozier - The maintainer of the [original package.](https://github.com/MickCrozier/timer-stopwatch/issues/9) | ||
@MickCrozier - The maintainer of the [original package.](https://github.com/MickCrozier/timer-stopwatch) | ||
@@ -104,0 +104,0 @@ Other contributors: |
@@ -28,2 +28,32 @@ ///////////////////////////////////////////////////// | ||
it("should be able to properly update the state and expose it", function(done) { | ||
var countdownTimer = new Stopwatch(50); | ||
expect(countdownTimer.isStopped()).to.be(true); | ||
expect(countdownTimer.isRunning()).to.be(false); | ||
expect(countdownTimer.isComplete()).to.be(false); | ||
countdownTimer.start(); | ||
expect(countdownTimer.isStopped()).to.be(false); | ||
expect(countdownTimer.isRunning()).to.be(true); | ||
expect(countdownTimer.isComplete()).to.be(false); | ||
countdownTimer.stop(); | ||
expect(countdownTimer.isStopped()).to.be(true); | ||
expect(countdownTimer.isRunning()).to.be(false); | ||
expect(countdownTimer.isComplete()).to.be(false); | ||
countdownTimer.startstop(); | ||
expect(countdownTimer.isStopped()).to.be(false); | ||
expect(countdownTimer.isRunning()).to.be(true); | ||
expect(countdownTimer.isComplete()).to.be(false); | ||
countdownTimer.startstop(); | ||
expect(countdownTimer.isStopped()).to.be(true); | ||
expect(countdownTimer.isRunning()).to.be(false); | ||
expect(countdownTimer.isComplete()).to.be(false); | ||
countdownTimer.start(); | ||
setTimeout(function() { | ||
expect(countdownTimer.isStopped()).to.be(false); | ||
expect(countdownTimer.isRunning()).to.be(false); | ||
expect(countdownTimer.isComplete()).to.be(true); | ||
done(); | ||
}, 55); | ||
}); | ||
it("should countdown with a normal refresh rate", function(done) { | ||
@@ -92,2 +122,16 @@ var countdownTimer = new Stopwatch(60000, { refreshRateMS: 50 }); | ||
it("should fire the onTime event", function(done) { | ||
var countdownTimer = new Stopwatch(60000); | ||
var startTime = countdownTimer.ms; | ||
countdownTimer.onTime(function(time) { | ||
expect(time.ms).to.equal(countdownTimer.ms); | ||
if (countdownTimer.state === 1) { | ||
done(); | ||
} | ||
countdownTimer.stop(); | ||
}); | ||
countdownTimer.start(); | ||
}); | ||
it("should fire the almostdone event", function(done) { | ||
@@ -112,2 +156,21 @@ var countdownTimer = new Stopwatch(40, { | ||
it("should fire the almostDone event", function(done) { | ||
var countdownTimer = new Stopwatch(40, { | ||
almostDoneMS: 20, | ||
refreshRateMS: 10 | ||
}); | ||
var startTime = countdownTimer.ms; | ||
var onDone = function onDone() { | ||
countdownTimer.stop(); | ||
expect(countdownTimer.ms).to.below(20); | ||
expect(countdownTimer.ms).to.above(5); | ||
countdownTimer.removeListener("almostdone", onDone); | ||
done(); | ||
}; | ||
countdownTimer.start(); | ||
countdownTimer.onAlmostDone(onDone); | ||
}); | ||
it("should fire the done event", function(done) { | ||
@@ -127,2 +190,16 @@ var countdownTimer = new Stopwatch(30, { almostDoneMS: 20 }); | ||
it("should fire the onDone event", function(done) { | ||
var countdownTimer = new Stopwatch(30, { almostDoneMS: 20 }); | ||
var startTime = countdownTimer.ms; | ||
var onDone = function onDone() { | ||
expect(countdownTimer.ms).to.equal(0); | ||
countdownTimer.removeListener("done", onDone); | ||
done(); | ||
}; | ||
countdownTimer.start(); | ||
countdownTimer.onDone(onDone); | ||
}); | ||
it("should fire the done event when done again after reset", function(done) { | ||
@@ -129,0 +206,0 @@ var countdownTimer = new Stopwatch(40, { |
Sorry, the diff of this file is not supported yet
58377
13
695