🚀 Socket Launch Week Day 5:Introducing Repository Access Permissions and Custom Roles.Learn more
Sign In

@armniko/ticker

Package Overview
Dependencies
Maintainers
1
Versions
7
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

@armniko/ticker - npm Package Compare versions

Comparing version
1.0.0
to
1.1.0
+1
dist/index.esm.js
var s={d:(t,e)=>{for(var i in e)s.o(e,i)&&!s.o(t,i)&&Object.defineProperty(t,i,{enumerable:!0,get:e[i]})},o:(s,t)=>Object.prototype.hasOwnProperty.call(s,t)},t={};s.d(t,{R:()=>a});class e{_minFps;_currentFps=60;_lastChecks=[];_calculateFpsEachMs=2e3;_msSinceLastCalculation=0;_lowFpsInRow=0;_lowFpsCallback;currentFps(){return this._currentFps}calculate(s){this.collectFps(s),this._msSinceLastCalculation+=s,this._msSinceLastCalculation>=this._calculateFpsEachMs&&(this._msSinceLastCalculation=0,this.calculateAverageFps(),this.checkAndNotifyLowFps())}onLowFps(s,t){this._minFps=s,this._lowFpsCallback=t}collectFps(s){this._lastChecks.push(Math.round(1e3/s))}calculateAverageFps(){const s=this._lastChecks.reduce(((s,t)=>s+t),0);this._currentFps=Math.round(s/this._lastChecks.length),this._lastChecks=[]}checkAndNotifyLowFps(){this._minFps&&this._currentFps<this._minFps&&(this._lowFpsInRow++,5===this._lowFpsInRow&&(this._lowFpsInRow=0,this._lowFpsCallback&&this._lowFpsCallback()))}}class i{_maxMsBetweenTicks;_expectedMsBetweenTicks;_ticksMissed=1;_msBetweenTicks=0;_lastTickTime=0;_requestFrameId;_tickCallback;constructor(s,t){this._maxMsBetweenTicks=1e3/s,this._expectedMsBetweenTicks=1e3/t}start(){this._tickCallback&&(this._lastTickTime=performance.now(),this.loop())}stop(){this._requestFrameId&&(window.cancelAnimationFrame(this._requestFrameId),this._requestFrameId=void 0)}isStarted(){return!!this._requestFrameId}onTick(s){this._tickCallback=s}msBetweenTicks(){return this._msBetweenTicks}ticksMissed(){return this._ticksMissed}loop(){const s=performance.now();this._msBetweenTicks=s-this._lastTickTime,this._ticksMissed=this._msBetweenTicks/this._expectedMsBetweenTicks,this._msBetweenTicks>=this._maxMsBetweenTicks&&(this._lastTickTime=s,this._tickCallback&&this._tickCallback(this._msBetweenTicks)),this._requestFrameId=window.requestAnimationFrame(this.loop.bind(this))}}class c{_expectedMsBetweenTicks;_ticksMissed=1;_msBetweenTicks=0;_lastTickTime=0;_timeoutId;_tickCallback;constructor(s){this._expectedMsBetweenTicks=1e3/s}start(){this._tickCallback&&(this._lastTickTime=performance.now(),this.delayLoop())}stop(){this._timeoutId&&(clearTimeout(this._timeoutId),this._timeoutId=void 0)}isStarted(){return!!this._timeoutId}onTick(s){this._tickCallback=s}msBetweenTicks(){return this._msBetweenTicks}ticksMissed(){return this._ticksMissed}delayLoop(){this._timeoutId=setTimeout((()=>this.loop()),this._expectedMsBetweenTicks)}loop(){const s=performance.now();this._msBetweenTicks=s-this._lastTickTime,this._ticksMissed=this._msBetweenTicks/this._expectedMsBetweenTicks,this._lastTickTime=s,this._tickCallback&&this._tickCallback(this._msBetweenTicks),this.delayLoop()}}class a{_fps=new e;_logicTicker;_drawTicker;constructor(s){const t=s?.minFps||0,e=this.compensatedMaxFps(s?.maxFps||60),a=s?.expectedFps||60,r=s?.onLogicTick,o=s?.onDrawTick,h=s?.onLowFps;this._logicTicker=new c(a),this._drawTicker=new i(e,a),r&&this._logicTicker.onTick(r),o&&this._drawTicker.onTick((s=>{o(),this._fps.calculate(s)})),h&&this._fps.onLowFps(t,h)}start(){this._logicTicker.start(),this._drawTicker.start()}stop(){this._logicTicker.stop(),this._drawTicker.stop()}isStarted(){return this._logicTicker.isStarted()||this._drawTicker.isStarted()}fps(){return this._fps.currentFps()}msBetweenTicks(){return this._logicTicker.isStarted()?this._logicTicker.msBetweenTicks():this._drawTicker.msBetweenTicks()}ticksMissed(){return this._logicTicker.isStarted()?this._logicTicker.ticksMissed():this._drawTicker.ticksMissed()}compensatedMaxFps(s){return Math.floor(1.1*s)+10*Math.floor(s/100)}}var r=t.R;export{r as Ticker};
!function(e,t){"object"==typeof exports&&"object"==typeof module?module.exports=t():"function"==typeof define&&define.amd?define("Ticker",[],t):"object"==typeof exports?exports.Ticker=t():e.Ticker=t()}(self,(()=>(()=>{"use strict";var e={d:(t,s)=>{for(var i in s)e.o(s,i)&&!e.o(t,i)&&Object.defineProperty(t,i,{enumerable:!0,get:s[i]})},o:(e,t)=>Object.prototype.hasOwnProperty.call(e,t),r:e=>{"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(e,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(e,"__esModule",{value:!0})}},t={};e.r(t),e.d(t,{Ticker:()=>r});class s{_minFps;_currentFps=60;_lastChecks=[];_calculateFpsEachMs=2e3;_msSinceLastCalculation=0;_lowFpsInRow=0;_lowFpsCallback;currentFps(){return this._currentFps}calculate(e){this.collectFps(e),this._msSinceLastCalculation+=e,this._msSinceLastCalculation>=this._calculateFpsEachMs&&(this._msSinceLastCalculation=0,this.calculateAverageFps(),this.checkAndNotifyLowFps())}onLowFps(e,t){this._minFps=e,this._lowFpsCallback=t}collectFps(e){this._lastChecks.push(Math.round(1e3/e))}calculateAverageFps(){const e=this._lastChecks.reduce(((e,t)=>e+t),0);this._currentFps=Math.round(e/this._lastChecks.length),this._lastChecks=[]}checkAndNotifyLowFps(){this._minFps&&this._currentFps<this._minFps&&(this._lowFpsInRow++,5===this._lowFpsInRow&&(this._lowFpsInRow=0,this._lowFpsCallback&&this._lowFpsCallback()))}}class i{_maxMsBetweenTicks;_expectedMsBetweenTicks;_ticksMissed=1;_msBetweenTicks=0;_lastTickTime=0;_requestFrameId;_tickCallback;constructor(e,t){this._maxMsBetweenTicks=1e3/e,this._expectedMsBetweenTicks=1e3/t}start(){this._tickCallback&&(this._lastTickTime=performance.now(),this.loop())}stop(){this._requestFrameId&&(window.cancelAnimationFrame(this._requestFrameId),this._requestFrameId=void 0)}isStarted(){return!!this._requestFrameId}onTick(e){this._tickCallback=e}msBetweenTicks(){return this._msBetweenTicks}ticksMissed(){return this._ticksMissed}loop(){const e=performance.now();this._msBetweenTicks=e-this._lastTickTime,this._ticksMissed=this._msBetweenTicks/this._expectedMsBetweenTicks,this._msBetweenTicks>=this._maxMsBetweenTicks&&(this._lastTickTime=e,this._tickCallback&&this._tickCallback(this._msBetweenTicks)),this._requestFrameId=window.requestAnimationFrame(this.loop.bind(this))}}class c{_expectedMsBetweenTicks;_ticksMissed=1;_msBetweenTicks=0;_lastTickTime=0;_timeoutId;_tickCallback;constructor(e){this._expectedMsBetweenTicks=1e3/e}start(){this._tickCallback&&(this._lastTickTime=performance.now(),this.delayLoop())}stop(){this._timeoutId&&(clearTimeout(this._timeoutId),this._timeoutId=void 0)}isStarted(){return!!this._timeoutId}onTick(e){this._tickCallback=e}msBetweenTicks(){return this._msBetweenTicks}ticksMissed(){return this._ticksMissed}delayLoop(){this._timeoutId=setTimeout((()=>this.loop()),this._expectedMsBetweenTicks)}loop(){const e=performance.now();this._msBetweenTicks=e-this._lastTickTime,this._ticksMissed=this._msBetweenTicks/this._expectedMsBetweenTicks,this._lastTickTime=e,this._tickCallback&&this._tickCallback(this._msBetweenTicks),this.delayLoop()}}class r{_fps=new s;_logicTicker;_drawTicker;constructor(e){const t=e?.minFps||0,s=this.compensatedMaxFps(e?.maxFps||60),r=e?.expectedFps||60,o=e?.onLogicTick,a=e?.onDrawTick,n=e?.onLowFps;this._logicTicker=new c(r),this._drawTicker=new i(s,r),o&&this._logicTicker.onTick(o),a&&this._drawTicker.onTick((e=>{a(),this._fps.calculate(e)})),n&&this._fps.onLowFps(t,n)}start(){this._logicTicker.start(),this._drawTicker.start()}stop(){this._logicTicker.stop(),this._drawTicker.stop()}isStarted(){return this._logicTicker.isStarted()||this._drawTicker.isStarted()}fps(){return this._fps.currentFps()}msBetweenTicks(){return this._logicTicker.isStarted()?this._logicTicker.msBetweenTicks():this._drawTicker.msBetweenTicks()}ticksMissed(){return this._logicTicker.isStarted()?this._logicTicker.ticksMissed():this._drawTicker.ticksMissed()}compensatedMaxFps(e){return Math.floor(1.1*e)+10*Math.floor(e/100)}}return t})()));
+13
-8
{
"name": "@armniko/ticker",
"version": "1.0.0",
"version": "1.1.0",
"description": "Javascript/typescript library for running app loop with separate logical/drawing ticks and FPS limitation.",

@@ -15,4 +15,6 @@ "author": "Armīns Nikolajevs <armins.nikolajevs@gmail.com>",

],
"main": "dist/index.js",
"types": "dist/index.d.ts",
"main": "./dist/index.umd.js",
"module": "./dist/index.esm.js",
"typings": "./dist/index.d.ts",
"type": "module",
"files": [

@@ -22,7 +24,7 @@ "dist"

"scripts": {
"build": "tsc --project tsconfig.build.json",
"dev": "node test/server/main.js & tsc --watch",
"lint": "eslint src --max-warnings=0",
"build": "rimraf dist && webpack",
"dev": "node test/server/main.js & webpack --watch",
"lint": "tsc --noEmit && eslint src --max-warnings=0",
"lint:fix": "npm run lint -- --fix",
"test": "jest --runInBand",
"test": "npm run build && jest",
"test:coverage": "npm run test -- --collect-coverage"

@@ -42,4 +44,7 @@ },

"ts-jest": "^29.1.2",
"typescript": "^5.4.3"
"ts-loader": "^9.5.1",
"typescript": "^5.4.3",
"webpack": "^5.91.0",
"webpack-cli": "^5.1.4"
}
}

@@ -78,1 +78,18 @@ <h1 align="center">Ticker</h1>

```
## Changelog
<table>
<tr>
<td>v1.1.0</td>
<td>
Precompile UMD and ESM<br>
</td>
</tr>
<tr>
<td>v1.0.0</td>
<td>
Initial version
</td>
</tr>
</table>
/* eslint-disable @typescript-eslint/no-unused-vars */
export * from './libraries/ticker';
export class Fps {
_minFps;
_currentFps = 60;
_lastChecks = [];
_calculateFpsEachMs = 2000;
_msSinceLastCalculation = 0;
_lowFpsInRow = 0;
_lowFpsCallback;
currentFps() {
return this._currentFps;
}
calculate(msSinceLastTick) {
this.collectFps(msSinceLastTick);
this._msSinceLastCalculation += msSinceLastTick;
if (this._msSinceLastCalculation >= this._calculateFpsEachMs) {
this._msSinceLastCalculation = 0;
this.calculateAverageFps();
this.checkAndNotifyLowFps();
}
}
onLowFps(minFps, callback) {
this._minFps = minFps;
this._lowFpsCallback = callback;
}
collectFps(msSinceLastTick) {
this._lastChecks.push(Math.round(1000 / msSinceLastTick));
}
calculateAverageFps() {
const sumFps = this._lastChecks.reduce((a, b) => a + b, 0);
this._currentFps = Math.round(sumFps / this._lastChecks.length);
this._lastChecks = [];
}
checkAndNotifyLowFps() {
if (this._minFps && this._currentFps < this._minFps) {
this._lowFpsInRow++;
if (this._lowFpsInRow === 5) {
this._lowFpsInRow = 0;
if (this._lowFpsCallback) {
this._lowFpsCallback();
}
}
}
}
}
import { Fps } from './fps/fps';
import { DrawTicker } from './tickers/draw-ticker';
import { LogicTicker } from './tickers/logic-ticker';
export class Ticker {
_fps = new Fps();
_logicTicker;
_drawTicker;
constructor(options) {
const minFps = options?.minFps || 0;
const maxFps = this.compensatedMaxFps(options?.maxFps || 60);
const expectedFps = options?.expectedFps || 60;
const onLogicTick = options?.onLogicTick;
const onDrawTick = options?.onDrawTick;
const onLowFps = options?.onLowFps;
this._logicTicker = new LogicTicker(expectedFps);
this._drawTicker = new DrawTicker(maxFps, expectedFps);
if (onLogicTick) {
this._logicTicker.onTick(onLogicTick);
}
if (onDrawTick) {
this._drawTicker.onTick((msSinceLastTick) => {
onDrawTick();
this._fps.calculate(msSinceLastTick);
});
}
if (onLowFps) {
this._fps.onLowFps(minFps, onLowFps);
}
}
start() {
this._logicTicker.start();
this._drawTicker.start();
}
stop() {
this._logicTicker.stop();
this._drawTicker.stop();
}
isStarted() {
return this._logicTicker.isStarted() || this._drawTicker.isStarted();
}
fps() {
return this._fps.currentFps();
}
msBetweenTicks() {
return this._logicTicker.isStarted() ? this._logicTicker.msBetweenTicks() : this._drawTicker.msBetweenTicks();
}
ticksMissed() {
return this._logicTicker.isStarted() ? this._logicTicker.ticksMissed() : this._drawTicker.ticksMissed();
}
compensatedMaxFps(maxFps) {
return Math.floor(maxFps * 1.1) + Math.floor(maxFps / 100) * 10;
}
}
export class DrawTicker {
_maxMsBetweenTicks;
_expectedMsBetweenTicks;
_ticksMissed = 1;
_msBetweenTicks = 0;
_lastTickTime = 0;
_requestFrameId;
_tickCallback;
constructor(maxFps, expectedFps) {
this._maxMsBetweenTicks = 1000 / maxFps;
this._expectedMsBetweenTicks = 1000 / expectedFps;
}
start() {
if (this._tickCallback) {
this._lastTickTime = performance.now();
this.loop();
}
}
stop() {
if (this._requestFrameId) {
window.cancelAnimationFrame(this._requestFrameId);
this._requestFrameId = undefined;
}
}
isStarted() {
return !!this._requestFrameId;
}
onTick(callback) {
this._tickCallback = callback;
}
msBetweenTicks() {
return this._msBetweenTicks;
}
ticksMissed() {
return this._ticksMissed;
}
loop() {
const now = performance.now();
this._msBetweenTicks = now - this._lastTickTime;
this._ticksMissed = this._msBetweenTicks / this._expectedMsBetweenTicks;
if (this._msBetweenTicks >= this._maxMsBetweenTicks) {
this._lastTickTime = now;
if (this._tickCallback) {
this._tickCallback(this._msBetweenTicks);
}
}
this._requestFrameId = window.requestAnimationFrame(this.loop.bind(this));
}
}
export class LogicTicker {
_expectedMsBetweenTicks;
_ticksMissed = 1;
_msBetweenTicks = 0;
_lastTickTime = 0;
_timeoutId;
_tickCallback;
constructor(expectedFps) {
this._expectedMsBetweenTicks = 1000 / expectedFps;
}
start() {
if (this._tickCallback) {
this._lastTickTime = performance.now();
this.delayLoop();
}
}
stop() {
if (this._timeoutId) {
clearTimeout(this._timeoutId);
this._timeoutId = undefined;
}
}
isStarted() {
return !!this._timeoutId;
}
onTick(callback) {
this._tickCallback = callback;
}
msBetweenTicks() {
return this._msBetweenTicks;
}
ticksMissed() {
return this._ticksMissed;
}
delayLoop() {
this._timeoutId = setTimeout(() => this.loop(), this._expectedMsBetweenTicks);
}
loop() {
const now = performance.now();
this._msBetweenTicks = now - this._lastTickTime;
this._ticksMissed = this._msBetweenTicks / this._expectedMsBetweenTicks;
this._lastTickTime = now;
if (this._tickCallback) {
this._tickCallback(this._msBetweenTicks);
}
this.delayLoop();
}
}