import { Container, Graphics } from 'pixi.js';
import { PixelText } from '../ui/PixelText';
/**
* Дебаг-счётчик FPS движка: плашка в левом верхнем углу, среднее за окно
* ~полсекунды (текст перерисовывается не чаще — растеризация дорогая).
* Скрыт по умолчанию; переключение — F3: движок слушает клавишу сам,
* независимо от привязок ввода приложения (preventDefault — F3 в Firefox
* открывает поиск).
*/
export class FpsMeter {
readonly view = new Container();
private bg = new Graphics();
private label = new PixelText({ text: 'FPS --', size: 10, color: 0xd7e4ec });
private frames = 0;
private windowStart = 0;
private lastFps = 0;
private shown = false;
private onKey = (e: KeyboardEvent): void => {
if (e.code !== 'F3') return;
e.preventDefault();
this.toggle();
};
constructor() {
this.view.addChild(this.bg, this.label);
this.label.position.set(4, 2);
this.view.position.set(2, 2);
this.view.visible = false;
window.addEventListener('keydown', this.onKey);
}
/** Учёт кадра отрисовки (Engine зовёт из render). */
frame(): void {
this.frames++;
const now = performance.now();
const elapsed = now - this.windowStart;
if (elapsed < 500) return;
this.lastFps = Math.round((this.frames * 1000) / elapsed);
this.frames = 0;
this.windowStart = now;
if (!this.shown) return;
this.label.text = `FPS ${this.lastFps}`;
this.bg
.clear()
.rect(0, 0, this.label.width + 8, this.label.height + 4)
.fill({ color: 0x101018, alpha: 0.8 })
.stroke({ color: 0x8899aa, width: 1 });
}
/** Средний FPS за последнее окно (~0,5 с); считается всегда, даже скрытым. */
get fps(): number {
return this.lastFps;
}
/** Показать/скрыть; после показа окно начинается с нуля. */
toggle(): void {
this.shown = !this.shown;
this.view.visible = this.shown;
if (this.shown) {
this.frames = 0;
this.windowStart = performance.now();
}
}
dispose(): void {
window.removeEventListener('keydown', this.onKey);
}
}