Skip to content

Commit dc50f7d

Browse files
committed
Add support for random time periods
1 parent ad6df89 commit dc50f7d

22 files changed

+2243
-2451
lines changed

.babelrc

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2,8 +2,5 @@
22
"presets": [
33
"es2015"
44
],
5-
"plugins": [
6-
"add-module-exports"
7-
],
85
"sourceMaps": true
96
}

Gruntfile.js

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -74,7 +74,6 @@ module.exports = function(grunt) {
7474
template: "unit",
7575
src: "dist/chronoman.common.js",
7676
dest: "dist/chronoman.js",
77-
objectToExport: "Timer",
7877
globalAlias: "Chronoman"
7978
}
8079
},

LICENSE

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
The MIT License (MIT)
22

3-
Copyright (c) 2013-2019 Denis Sikuler
3+
Copyright (c) 2013-2020 Denis Sikuler
44

55
Permission is hereby granted, free of charge, to any person obtaining a copy of
66
this software and associated documentation files (the "Software"), to deal in

README.md

Lines changed: 8 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ Utility class to simplify use of timers created by `setTimeout`.
44

55
```js
66
var timer = new Timer({
7-
period: [100, 200, 300, 400, 500],
7+
period: [100, 200, 300, 400, 500, {start: 100, end: 500}],
88
repeatQty: 100,
99
passToAction: true,
1010
action: function(tmr) {
@@ -26,10 +26,6 @@ timer.stop();
2626

2727
npm install chronoman
2828

29-
### [JSPM](http://jspm.io)
30-
31-
jspm install chronoman
32-
3329
### [Bower](http://bower.io)
3430

3531
bower install chronoman
@@ -46,24 +42,17 @@ Use `dist/chronoman.js` or `dist/chronoman.min.js` (minified version).
4642
import Timer from "chronoman";
4743
```
4844

49-
### Node, JSPM
50-
51-
```js
52-
var Timer = require("chronoman");
53-
```
54-
55-
### JSPM
45+
### Node
5646

5747
```js
58-
System.import("chronoman").then(function(Timer) {
59-
...
60-
});
48+
var Timer = require("chronoman").Timer;
6149
```
6250

6351
### AMD
6452

6553
```js
66-
define(["path/to/dist/chronoman.js"], function(Timer) {
54+
define(["path/to/dist/chronoman.js"], function(chronoman) {
55+
var Timer = chronoman.Timer;
6756
...
6857
});
6958
```
@@ -75,7 +64,7 @@ define(["path/to/dist/chronoman.js"], function(Timer) {
7564
<script type="text/javascript" src="path/to/dist/chronoman.js"></script>
7665
<script type="text/javascript">
7766
// сhronoman is available via Chronoman field of window object
78-
var Timer = Chronoman;
67+
var Timer = Chronoman.Timer;
7968
...
8069
</script>
8170
```
@@ -96,7 +85,7 @@ var tmrOne = new Timer({
9685
});
9786

9887
var tmrTwo = new Timer();
99-
tmrTwo.setPeriod([2000, 1500])
88+
tmrTwo.setPeriod([2000, , {start: 1000, end: 1500}])
10089
.setRepeatQty(9)
10190
.setPassToAction(true)
10291
.setAction({
@@ -138,5 +127,5 @@ This module is inspired by [qooxdoo](http://qooxdoo.org)'s `qx.event.Timer` clas
138127

139128
## Licence
140129

141-
Copyright (c) 2013-2019 Denis Sikuler
130+
Copyright (c) 2013-2020 Denis Sikuler
142131
Licensed under the MIT license.

chronoman.js

Lines changed: 104 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -11,16 +11,70 @@ if (! Array.isArray) {
1111
};
1212
}
1313

14+
/**
15+
* Generate random number or randomly select item from specified array.
16+
*
17+
* @param {Array | number} start
18+
* Array from which an item should be selected
19+
* or minimal point of interval from which random number should be generated.
20+
* @param {number} [end=start+1]
21+
* Maximal point of interval from which random number should be generated.
22+
* @param {boolean} [bInteger=true]
23+
* Whether integer number should be returned.
24+
* This parameter can be used when value of <code>start</code> parameter is a number.
25+
* @return {*}
26+
* Random number when <code>start</code> parameter is a number
27+
* or randomly selected item when <code>start</code> parameter is an array.
28+
*/
29+
export function getRandomValue(start, end, bInteger) {
30+
var nL, result;
31+
if (Array.isArray(start)) {
32+
nL = start.length;
33+
if (nL) {
34+
return start[ nL > 1 ? getRandomValue(0, nL - 1) : 0 ];
35+
}
36+
return result;
37+
}
38+
39+
if (typeof end !== "number") {
40+
end = start + 1;
41+
}
42+
if (arguments.length < 3) {
43+
bInteger = true;
44+
}
45+
nL = start + ((end - start) * Math.random());
46+
47+
return bInteger ? Math.round(nL) : nL;
48+
}
49+
1450
/**
1551
* @callback module:chronoman~GetPeriodValue
1652
* @param {module:chronoman~Timer} [timer]
17-
* @return {Integer | Integer[]}
53+
* @return {module:chronoman~SinglePeriodValue | module:chronoman~SinglePeriodValue[]}
54+
*/
55+
56+
/**
57+
* Object describing properties for generating random time period.
58+
*
59+
* @typedef {Object} module:chronoman~RandomPeriod
60+
* @property {Integer} [end]
61+
* Maximal point of interval from which random time period should be generated.
62+
* @property {Integer[]} [list]
63+
* Array from which a time period should be selected randomly.
64+
* @property {Integer} [start]
65+
* Minimal point of interval from which random time period should be generated.
66+
*/
67+
68+
/**
69+
* Single value determining time period in milliseconds that is used to schedule related action execution.
70+
*
71+
* @typedef {Integer | module:chronoman~RandomPeriod} module:chronoman~SinglePeriodValue
1872
*/
1973

2074
/**
2175
* Value determining time period in milliseconds that is used to schedule related action execution.
2276
*
23-
* @typedef {Integer | Integer[] | module:chronoman~GetPeriodValue} module:chronoman~PeriodValue
77+
* @typedef {module:chronoman~SinglePeriodValue | module:chronoman~SinglePeriodValue[] | module:chronoman~GetPeriodValue} module:chronoman~PeriodValue
2478
*/
2579

2680
/**
@@ -74,9 +128,19 @@ var Timer = function Timer(initValue) {
74128

75129

76130
/**
77-
* Time period in milliseconds, array of periods or function that returns period or array of periods.
131+
* Time period in milliseconds, object specifying random time period, array of periods
132+
* or function that returns period or array of periods.
78133
* A related action will be executed when the period is elapsed.
79134
* <br>
135+
* When an object is set the used period is selected randomly.
136+
* The object can have the following properties:
137+
* - <code>list</code> - a non-empty array of integer numbers from which the period will be selected randomly.
138+
* - <code>start</code> - an integer number representing minimal point of interval
139+
* from which random time period should be generated; default value - 0.
140+
* - <code>end</code> - an integer number representing maximal point of interval
141+
* from which random time period should be generated; default value - <code>start + 1000</code>.
142+
*
143+
* <br>
80144
* When array of periods is set the used period is selected in the following way:
81145
* first array item (with index 0) specifies period before first action's execution,
82146
* second array item (with index 1) specifies period before second action's execution,
@@ -126,23 +190,42 @@ Timer.prototype.setPeriod = function(period) {
126190
/**
127191
* Return time period that will be used to schedule related action execution.
128192
*
193+
* @param {module:chronoman~PeriodValue} [value=this.getPeriod()]
194+
* Value that is used to calculation.
129195
* @return {Integer}
130196
* Time period in milliseconds.
131197
* @method
132198
* @see {@link module:chronoman~Timer#_period _period}
133199
* @see {@link module:chronoman~Timer#getPeriod getPeriod}
134200
* @see {@link module:chronoman~Timer#getExecutionQty getExecutionQty}
135201
*/
136-
Timer.prototype.getPeriodValue = function() {
202+
Timer.prototype.getPeriodValue = function(value) {
203+
/*jshint laxbreak:true*/
137204
var execQty;
138-
var period = this.getPeriod();
205+
var period = value || value === 0
206+
? value
207+
: this.getPeriod();
139208
if (typeof period === "function") {
140209
period = period(this);
141210
}
142211
if (Array.isArray(period)) {
143212
execQty = this.getExecutionQty();
144213
period = period[ execQty < period.length ? execQty : period.length - 1 ];
145214
}
215+
if (period && typeof period === "object") {
216+
if (period.list && period.list.length) {
217+
period = getRandomValue(period.list);
218+
}
219+
else {
220+
if (typeof period.start !== "number") {
221+
period.start = 0;
222+
}
223+
if (typeof period.end !== "number") {
224+
period.end = period.start + 1000;
225+
}
226+
period = getRandomValue(period.start, period.end);
227+
}
228+
}
146229
return period;
147230
};
148231

@@ -224,8 +307,9 @@ Timer.prototype.setRepeatQty = function(nQty) {
224307
* Specifies function that should be called after action execution to determine
225308
* whether execution should be repeated.
226309
* If the function returns a true value or non-negative number it means that execution will be repeated.
227-
* When the function returns non-negative number this number will be used
228-
* as time period in milliseconds to schedule next action execution.
310+
* When the function returns non-negative number, array, object or function this value will be used
311+
* to calculate time period in milliseconds to schedule next action execution
312+
* (see {@link module:chronoman~Timer#getPeriodValue getPeriodValue}).
229313
* <br>
230314
* The timer instance to which the test is associated will be passed as function's parameter.
231315
*
@@ -348,8 +432,8 @@ Timer.prototype._timeoutId = null;
348432
/**
349433
* Schedule related action execution.
350434
*
351-
* @param {Integer} [nTimeout]
352-
* Time period in milliseconds that is used to schedule action execution.
435+
* @param {module:chronoman~PeriodValue} [timeout]
436+
* Time period that is used to schedule action execution.
353437
* By default the current value of {@link module:chronoman~Timer#getPeriod period} property is used
354438
* to determine time period.
355439
* @return {Object}
@@ -362,15 +446,9 @@ Timer.prototype._timeoutId = null;
362446
* @see {@link module:chronoman~Timer#execute execute}
363447
* @see {@link module:chronoman~Timer#getPeriodValue getPeriodValue}
364448
*/
365-
Timer.prototype._setTimeout = function(nTimeout) {
449+
Timer.prototype._setTimeout = function(timeout) {
366450
"use strict";
367-
var period;
368-
if (typeof nTimeout === "number") {
369-
period = nTimeout;
370-
}
371-
else {
372-
period = this.getPeriodValue();
373-
}
451+
var period = this.getPeriodValue(timeout);
374452
if (typeof period === "number") {
375453
this._timeoutId = setTimeout(this._onTimeoutEnd, period);
376454
}
@@ -787,7 +865,7 @@ Timer.prototype.execute = function() {
787865
var action = this.getAction(),
788866
bPassToAction = this.isPassToAction(),
789867
repeatTest = this.getRepeatTest(),
790-
bActive, period;
868+
bActive, period, sType;
791869
this._clearTimeout();
792870
if (action) {
793871
if (typeof action === "function") {
@@ -814,9 +892,14 @@ Timer.prototype.execute = function() {
814892
|| this.getRepeatQty() >= this._executionQty
815893
|| (repeatTest
816894
&& ( (period = repeatTest(this)) || period === 0 )
817-
&& (typeof period !== "number" || period >= 0))
895+
&& (sType = typeof period)
896+
&& (sType !== "number" || period >= 0))
818897
) ) {
819-
this._setTimeout(period);
898+
this._setTimeout(
899+
sType === "number" || sType === "object" || sType === "function"
900+
? period
901+
: null
902+
);
820903
}
821904
else if (bActive && ! this._timeoutId) {
822905
this.setActive(false);
@@ -889,5 +972,5 @@ Timer.prototype.toString = function() {
889972
};
890973

891974
// Exports
892-
975+
export { Timer };
893976
export default Timer;

0 commit comments

Comments
 (0)