Skip to content

Commit

Permalink
Add FPS utilities, resolves #658
Browse files Browse the repository at this point in the history
  • Loading branch information
NullVoxPopuli committed Mar 6, 2023
1 parent fb6d628 commit d6637ff
Show file tree
Hide file tree
Showing 3 changed files with 93 additions and 1 deletion.
4 changes: 4 additions & 0 deletions ember-resources/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
"./util": "./dist/util/index.js",
"./util/cell": "./dist/util/cell.js",
"./util/keep-latest": "./dist/util/keep-latest.js",
"./util/fps": "./dist/util/fps.js",
"./util/map": "./dist/util/map.js",
"./util/helper": "./dist/util/helper.js",
"./util/remote-data": "./dist/util/remote-data.js",
Expand Down Expand Up @@ -43,6 +44,9 @@
"util/function": [
"dist/util/function.d.ts"
],
"util/fps": [
"dist/util/fps.d.ts"
],
"util/map": [
"dist/util/map.d.ts"
],
Expand Down
88 changes: 88 additions & 0 deletions ember-resources/src/util/fps.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,88 @@
import { cell, resource, resourceFactory } from '../index';

/**
* Utility that uses requestAnimationFrame to report
* how many frames per second the current monitor is
* rendering at.
*
* The result is rounded to two decimal places.
*
* ```js
* import { FramRate } from 'ember-resources/util/fps';
*
* <template>
* {{FrameRate}}
* </template>
* ```
*/
export const FrameRate = resource(({ on }) => {
let value = cell(0);
let startTime = new Date().getTime();
let frame: number;

let update = () => {
// simulate receiving data as fast as possible
frame = requestAnimationFrame(() => {
value.current++;
update();
});
};

on.cleanup(() => cancelAnimationFrame(frame));

// Start the infinite requestAnimationFrame chain
update();

return () => {
let elapsed = (new Date().getTime() - startTime) * 0.001;
let fps = value.current * Math.pow(elapsed, -1);
let rounded = Math.round(fps * 100) * 0.01;
// account for https://stackoverflow.com/a/588014/356849
let formatted = `${rounded}`.substring(0, 5);

return formatted;
};
});

/**
* Utility that will report the frequency of updates to tracked data.
*
* ```js
* import { UpdateFrequency } from 'ember-resources/util/fps';
*
* export default class Demo extends Component {
* @tracked someProp;
*
* @use updateFrequency = UpdateFrequency(() => this.someProp);
*
* <template>
* {{this.updateFrequency}}
* </template>
* }
* ```
*
* NOTE: the function passed to UpdateFrequency may not set tracked data.
*/
export const UpdateFrequency = resourceFactory((ofWhat: () => void, updateInterval: number) => {
updateInterval ||= 500;

let multiplier = 1000 / updateInterval;
let framesSinceUpdate = 0;

return resource(({ on }) => {
let value = cell(0);
let interval = setInterval(() => {
value.current = framesSinceUpdate * multiplier;
framesSinceUpdate = 0;
}, updateInterval);

on.cleanup(() => clearInterval(interval));

return () => {
ofWhat();
framesSinceUpdate++;

return value.current;
};
});
});
2 changes: 1 addition & 1 deletion test-app/tests/type-tests/types.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
/* eslint-disable @typescript-eslint/ban-ts-comment */
/* eslint-disable @typescript-eslint/ban-types */
import { expectType, type TypeEqual } from 'ts-expect';
import { expectType,type TypeEqual } from 'ts-expect';

import type { ExpandArgs } from 'ember-resources';

Expand Down

0 comments on commit d6637ff

Please sign in to comment.