@@ -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 } ;
893976export default Timer ;
0 commit comments