Release Healer Man 0.1.9
This commit is contained in:
1 parent
c245a199b6
commit
d060296ade
74 files changed
+5901
-334
No files matched your search
@@ -0,0 +1,64 @@
|
||||
import { describe, expect, it } from "vitest";
|
||||
import {
|
||||
createFrameRateGovernor,
|
||||
resetFrameRateGovernor,
|
||||
stepFrameRateGovernor,
|
||||
} from "./frameRateGovernor";
|
||||
|
||||
function renderCount(targetFps: 30 | 60, sourceFps: number, durationMs = 1_000): number {
|
||||
let state = createFrameRateGovernor(targetFps);
|
||||
let renders = 0;
|
||||
for (let timestamp = 0; timestamp <= durationMs; timestamp += 1_000 / sourceFps) {
|
||||
const step = stepFrameRateGovernor(state, timestamp);
|
||||
state = step.state;
|
||||
if (step.shouldRender) renders += 1;
|
||||
}
|
||||
return renders;
|
||||
}
|
||||
|
||||
describe("frame-rate governor", () => {
|
||||
it("holds capped modes near their target on high-refresh displays", () => {
|
||||
expect(renderCount(30, 144)).toBeGreaterThanOrEqual(30);
|
||||
expect(renderCount(30, 144)).toBeLessThanOrEqual(31);
|
||||
expect(renderCount(60, 240)).toBeGreaterThanOrEqual(60);
|
||||
expect(renderCount(60, 240)).toBeLessThanOrEqual(61);
|
||||
});
|
||||
|
||||
it("renders every source callback in display mode", () => {
|
||||
let state = createFrameRateGovernor("display", 4);
|
||||
for (const timestamp of [1_000, 1_008, 1_016]) {
|
||||
const step = stepFrameRateGovernor(state, timestamp);
|
||||
state = step.state;
|
||||
expect(step.shouldRender).toBe(true);
|
||||
}
|
||||
expect(state.elapsedSeconds).toBeCloseTo(4.016);
|
||||
});
|
||||
|
||||
it("skips missed deadlines without emitting a catch-up burst", () => {
|
||||
let state = createFrameRateGovernor(60);
|
||||
state = stepFrameRateGovernor(state, 0).state;
|
||||
const delayed = stepFrameRateGovernor(state, 100);
|
||||
expect(delayed.shouldRender).toBe(true);
|
||||
expect(delayed.state.nextDeadlineMs).toBeGreaterThan(100);
|
||||
const sameTimestamp = stepFrameRateGovernor(delayed.state, 100);
|
||||
expect(sameTimestamp.shouldRender).toBe(false);
|
||||
});
|
||||
|
||||
it("preserves elapsed time while resetting the wall-clock baseline", () => {
|
||||
let state = createFrameRateGovernor(30, 2);
|
||||
state = stepFrameRateGovernor(state, 1_000).state;
|
||||
state = stepFrameRateGovernor(state, 1_034).state;
|
||||
const reset = resetFrameRateGovernor(state, 60);
|
||||
const resumed = stepFrameRateGovernor(reset, 90_000);
|
||||
expect(resumed.shouldRender).toBe(true);
|
||||
expect(resumed.elapsedSeconds).toBeCloseTo(state.elapsedSeconds);
|
||||
});
|
||||
|
||||
it("never moves elapsed time backwards", () => {
|
||||
let state = createFrameRateGovernor(60);
|
||||
state = stepFrameRateGovernor(state, 20).state;
|
||||
state = stepFrameRateGovernor(state, 40).state;
|
||||
const backwards = stepFrameRateGovernor(state, 10);
|
||||
expect(backwards.elapsedSeconds).toBe(state.elapsedSeconds);
|
||||
});
|
||||
});
|
||||
Reference in new issue
Block a user