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,86 @@
|
||||
export type FrameRateGovernorMode = number | "display";
|
||||
|
||||
export interface FrameRateGovernorState {
|
||||
readonly mode: FrameRateGovernorMode;
|
||||
readonly lastTimestampMs: number | null;
|
||||
readonly nextDeadlineMs: number | null;
|
||||
readonly elapsedSeconds: number;
|
||||
}
|
||||
|
||||
export interface FrameRateGovernorStep {
|
||||
readonly state: FrameRateGovernorState;
|
||||
readonly shouldRender: boolean;
|
||||
readonly elapsedSeconds: number;
|
||||
}
|
||||
|
||||
function frameIntervalMs(mode: FrameRateGovernorMode): number | null {
|
||||
if (mode === "display") return null;
|
||||
return Number.isFinite(mode) && mode > 0 ? 1_000 / mode : 1_000 / 60;
|
||||
}
|
||||
|
||||
export function createFrameRateGovernor(
|
||||
mode: FrameRateGovernorMode,
|
||||
elapsedSeconds = 0,
|
||||
): FrameRateGovernorState {
|
||||
return {
|
||||
mode,
|
||||
lastTimestampMs: null,
|
||||
nextDeadlineMs: null,
|
||||
elapsedSeconds: Math.max(0, elapsedSeconds),
|
||||
};
|
||||
}
|
||||
|
||||
export function resetFrameRateGovernor(
|
||||
state: FrameRateGovernorState,
|
||||
mode: FrameRateGovernorMode = state.mode,
|
||||
): FrameRateGovernorState {
|
||||
return createFrameRateGovernor(mode, state.elapsedSeconds);
|
||||
}
|
||||
|
||||
export function stepFrameRateGovernor(
|
||||
state: FrameRateGovernorState,
|
||||
rawTimestampMs: number,
|
||||
): FrameRateGovernorStep {
|
||||
const fallbackTimestamp = state.lastTimestampMs ?? 0;
|
||||
const finiteTimestamp = Number.isFinite(rawTimestampMs) ? rawTimestampMs : fallbackTimestamp;
|
||||
const timestampMs = Math.max(fallbackTimestamp, finiteTimestamp);
|
||||
const intervalMs = frameIntervalMs(state.mode);
|
||||
|
||||
if (state.lastTimestampMs === null) {
|
||||
const nextState: FrameRateGovernorState = {
|
||||
...state,
|
||||
lastTimestampMs: timestampMs,
|
||||
nextDeadlineMs: intervalMs === null ? null : timestampMs + intervalMs,
|
||||
};
|
||||
return { state: nextState, shouldRender: true, elapsedSeconds: nextState.elapsedSeconds };
|
||||
}
|
||||
|
||||
const elapsedSeconds = state.elapsedSeconds + (timestampMs - state.lastTimestampMs) / 1_000;
|
||||
if (intervalMs === null) {
|
||||
const nextState: FrameRateGovernorState = {
|
||||
...state,
|
||||
lastTimestampMs: timestampMs,
|
||||
elapsedSeconds,
|
||||
};
|
||||
return { state: nextState, shouldRender: true, elapsedSeconds };
|
||||
}
|
||||
|
||||
const deadlineMs = state.nextDeadlineMs ?? timestampMs;
|
||||
if (timestampMs < deadlineMs) {
|
||||
const nextState: FrameRateGovernorState = {
|
||||
...state,
|
||||
lastTimestampMs: timestampMs,
|
||||
elapsedSeconds,
|
||||
};
|
||||
return { state: nextState, shouldRender: false, elapsedSeconds };
|
||||
}
|
||||
|
||||
const missedIntervals = Math.floor(Math.max(0, timestampMs - deadlineMs) / intervalMs);
|
||||
const nextState: FrameRateGovernorState = {
|
||||
...state,
|
||||
lastTimestampMs: timestampMs,
|
||||
nextDeadlineMs: deadlineMs + (missedIntervals + 1) * intervalMs,
|
||||
elapsedSeconds,
|
||||
};
|
||||
return { state: nextState, shouldRender: true, elapsedSeconds };
|
||||
}
|
||||
Reference in new issue
Block a user