/**
* Class for representing a timer.
*
* @author {@link https://github.com/Mugen87|Mugen87}
*/
class Time {
/**
* Constructs a new time object.
*/
constructor() {
this._previousTime = 0;
this._currentTime = 0;
this._delta = 0;
this._elapsed = 0;
this._timescale = 1;
this._useFixedDelta = false;
this._fixedDelta = 16.67; // ms, corresponds to approx. 60 FPS
// use Page Visibility API to avoid large time delta values
this._usePageVisibilityAPI = ( typeof document !== 'undefined' && document.hidden !== undefined );
if ( this._usePageVisibilityAPI === true ) {
this._pageVisibilityHandler = handleVisibilityChange.bind( this );
document.addEventListener( 'visibilitychange', this._pageVisibilityHandler, false );
}
}
/**
* Disables the usage of a fixed delta value.
*
* @return {Time} A reference to this time object.
*/
disableFixedDelta() {
this._useFixedDelta = false;
return this;
}
/**
* Frees all internal resources.
*
* @return {Time} A reference to this time object.
*/
dispose() {
if ( this._usePageVisibilityAPI === true ) {
document.removeEventListener( 'visibilitychange', this._pageVisibilityHandler );
}
return this;
}
/**
* Enables the usage of a fixed delta value. Can be useful for debugging and testing.
*
* @return {Time} A reference to this time object.
*/
enableFixedDelta() {
this._useFixedDelta = true;
return this;
}
/**
* Returns the delta time in seconds. Represents the completion time in seconds since
* the last simulation step.
*
* @return {Number} The delta time in seconds.
*/
getDelta() {
return this._delta / 1000;
}
/**
* Returns the elapsed time in seconds. It's the accumulated
* value of all previous time deltas.
*
* @return {Number} The elapsed time in seconds.
*/
getElapsed() {
return this._elapsed / 1000;
}
/**
* Returns the fixed delta time in seconds.
*
* @return {Number} The fixed delta time in seconds.
*/
getFixedDelta() {
return this._fixedDelta / 1000;
}
/**
* Returns the timescale value.
*
* @return {Number} The timescale value.
*/
getTimescale() {
return this._timescale;
}
/**
* Resets this time object.
*
* @return {Time} A reference to this time object.
*/
reset() {
this._currentTime = this._now();
return this;
}
/**
* Sets a fixed time delta value.
*
* @param {Number} fixedDelta - Fixed time delta in seconds.
* @return {Time} A reference to this time object.
*/
setFixedDelta( fixedDelta ) {
this._fixedDelta = fixedDelta * 1000;
return this;
}
/**
* Sets a timescale value. This value represents the scale at which time passes.
* Can be used for slow down or accelerate the simulation.
*
* @param {Number} timescale - The timescale value.
* @return {Time} A reference to this time object.
*/
setTimescale( timescale ) {
this._timescale = timescale;
return this;
}
/**
* Updates the internal state of this time object.
*
* @return {Time} A reference to this time object.
*/
update() {
if ( this._useFixedDelta === true ) {
this._delta = this._fixedDelta;
} else {
this._previousTime = this._currentTime;
this._currentTime = this._now();
this._delta = this._currentTime - this._previousTime;
}
this._delta *= this._timescale;
this._elapsed += this._delta; // _elapsed is the accumulation of all previous deltas
return this;
}
// private
_now() {
return ( typeof performance === 'undefined' ? Date : performance ).now();
}
}
//
function handleVisibilityChange() {
if ( document.hidden === false ) this.reset();
}
export { Time };