import { Utils } from '../common/Utils';
import { FPSTimer } from '../common/FPSTimer';
import { BaseComponent } from './BaseComponent';
const __ = {
private: Symbol('private'),
}
/**
* @class AppTimerComponent
* The application timer component.
* @memberof THING
* @extends THING.BaseComponent
*/
class AppTimerComponent extends BaseComponent {
/**
* The timer controller for application.
*/
constructor() {
super();
this[__.private] = {};
let _private = this[__.private];
// Delta time
_private.frameRate = 0;
_private.lastFrame = 0;
_private.startTime = 0;
if (_NEED_LOGGER) {
_private.loggerTime = 0;
}
// Initialize FPS timer
_private.fpsTimer = new FPSTimer();
// Callback functions
_private.onTick = null;
}
// #region Private
/**
* Get fixed delta time in milliseconds.
* @param {Number} elapsedTime The elapsed time in milliseconds.
* @returns {Number}
* @private
*/
_getDeltaTime(elapsedTime) {
let _private = this[__.private];
let deltaTime = 0;
if (_private.startTime === 0) {
_private.startTime = elapsedTime;
deltaTime = elapsedTime;
}
else {
const currentFrame = Math.round((elapsedTime - _private.startTime) / _private.frameRate);
deltaTime = (currentFrame - _private.lastFrame) * _private.frameRate;
_private.lastFrame = currentFrame;
}
return deltaTime;
}
_updateLogger(deltaTime) {
let app = this.object;
let _private = this[__.private];
_private.loggerTime += deltaTime;
if (_private.loggerTime > 30) {
let objectManager = app.objectManager;
let msg = {
"common": {
'tickableObjects': objectManager.tickableObjects.length,
'lateUpdateObjects': objectManager.lateUpdateObjects.length,
'objects': objectManager.objects.length,
},
"render": {
"fps": this.fpsCounter,
},
}
Utils.logger.api("frame", { msg: JSON.stringify(msg) });
let collector = Utils.logger.getApiCollector();
if (collector) {
let count = collector.getApiCount();
Utils.logger.api("apiCount", { msg: JSON.stringify(count) });
collector.clearApiCount();
}
_private.loggerTime = 0;
}
}
// #endregion
// #region BaseComponent Interface
onAdd(object) {
super.onAdd(object);
}
onRemove() {
let _private = this[__.private];
_private.fpsTimer = null;
_private.onTick = null;
super.onRemove();
}
// #endregion
init(options = {}) {
let _private = this[__.private];
// Delta time
let frameRate = Utils.parseValue(options['frameRate'], 60);
_private.frameRate = 1000 / frameRate;
_private.lastFrame = 0;
_private.startTime = 0;
if (_NEED_LOGGER) {
_private.loggerTime = 0;
}
_private.onTick = options['onTick'];
}
update(elapsedTime) {
let _private = this[__.private];
// Get the delta time by elapsed time in milliseconds
let deltaTime = this._getDeltaTime(elapsedTime);
// Convert delta time from milliseconds to seconds to update fps timer
deltaTime = _private.fpsTimer.update(deltaTime / 1000);
if (!deltaTime) {
return;
}
_private.onTick(deltaTime);
if (_NEED_LOGGER) {
this._updateLogger(deltaTime);
}
}
/**
* Get the elapsed time(seconds) when started.
* @type {Number}
* @example
* let elapsedTime = THING.App.current.elapsedTime;
* console.log(elapsedTime);
*/
get elapsedTime() {
return this[__.private].fpsTimer.elapsedTime;
}
/**
* Get the delta time(seconds) of previous frame.
* @type {Number}
* @example
* let deltaTime = THING.App.current.deltaTime;
* console.log(deltaTime);
*/
get deltaTime() {
return this[__.private].fpsTimer.deltaTime;
}
/**
* Get the current total frame count after started.
* @type {Number}
* @example
* let currentFrameCount = THING.App.current.currentFrameCount;
* console.log(currentFrameCount);
*/
get currentFrameCount() {
return this[__.private].fpsTimer.currentFrameCount;
}
/**
* Get/Set fixed delta time in seconds.
* @type {Number}
* @private
*/
get fixedDeltaTime() {
return this[__.private].fpsTimer.fixedDeltaTime;
}
set fixedDeltaTime(value) {
this[__.private].fpsTimer.fixedDeltaTime = value;
}
/**
* Get/Set the max FPS number, null indicates unlimited.
* @type {Number}
* @example
* // Limit max render FPS to 1
* THING.App.current.maxFPS = 1;
* // Unlimit max render FPS
* THING.App.current.maxFPS = null;
*/
get maxFPS() {
return this[__.private].fpsTimer.maxFPS;
}
set maxFPS(value) {
this[__.private].fpsTimer.maxFPS = value;
}
/**
* Enable/Disable slow motion.
* @type {Boolean}
* @private
*/
get slowMotion() {
return this.fixedDeltaTime === 1 / 1000;
}
set slowMotion(value) {
if (value) {
this.fixedDeltaTime = 1 / 1000;
}
else {
this.fixedDeltaTime = null;
}
}
/**
* Get the FPS Counter.
* @type {Number}
* @example
* let fpsCounter = THING.App.current.fpsCounter;
* console.log(fpsCounter);
*/
get fpsCounter() {
let _private = this[__.private];
return _private.fpsTimer.fpsCounter;
}
}
AppTimerComponent.exportProperties = [
'elapsedTime',
'deltaTime',
'currentFrameCount',
'maxFPS',
'fpsCounter'
];
export { AppTimerComponent }