more cleaning up
This commit is contained in:
parent
2c7d72a699
commit
560398fefb
110 changed files with 931 additions and 2645 deletions
|
|
@ -5,7 +5,6 @@ import { gardenAudioConfig } from '../audio/garden-audio-config';
|
|||
import { appConfig } from '../config';
|
||||
import { activeVibe, settings } from '../settings';
|
||||
import { DeltaTimeCalculator } from '../utils/delta-time-calculator';
|
||||
import { sleep } from '../utils/sleep';
|
||||
import { AgentPopulation } from './agent-population';
|
||||
import { EraserPreview } from './eraser-preview';
|
||||
import { Export4KRenderer } from './export-4k-renderer';
|
||||
|
|
@ -18,9 +17,7 @@ import { RenderInputCache } from './render-input-cache';
|
|||
import { ToolbarContrastMonitor } from './toolbar-contrast-monitor';
|
||||
|
||||
export default class GameLoop {
|
||||
private static readonly MAX_MIRROR_SEGMENT_COUNT =
|
||||
appConfig.simulation.maxMirrorSegmentCount;
|
||||
private static readonly DEV_STATS_INTERVAL_MS = 250;
|
||||
private static readonly MAX_MIRROR_SEGMENT_COUNT = appConfig.toolbar.mirror.max;
|
||||
|
||||
private readonly resources: GameLoopResources;
|
||||
private readonly audio = new GardenAudio(gardenAudioConfig);
|
||||
|
|
@ -32,13 +29,10 @@ export default class GameLoop {
|
|||
private readonly export4KRenderer: Export4KRenderer;
|
||||
private readonly framePerformance = new FramePerformance();
|
||||
private readonly toolbarContrastMonitor: ToolbarContrastMonitor;
|
||||
private readonly devStatsElement: HTMLDivElement | null;
|
||||
private readonly seed = Math.floor(Math.random() * 0xffffffff).toString(16);
|
||||
private readonly resizeListener = this.resize.bind(this);
|
||||
private readonly keydownListener: (event: KeyboardEvent) => void;
|
||||
|
||||
private lastDevStatsUpdateAt = 0;
|
||||
private isStatsOverlayPinned = false;
|
||||
private hasFinished = false;
|
||||
private readonly finished = Promise.withResolvers<void>();
|
||||
|
||||
|
|
@ -49,8 +43,6 @@ export default class GameLoop {
|
|||
ui: GardenUi
|
||||
) {
|
||||
this.resize();
|
||||
this.devStatsElement = this.createDevStatsElement();
|
||||
this.syncDevStatsVisibility();
|
||||
this.resources = new GameLoopResources(canvas, device, this.canvasSize);
|
||||
this.introPrompt = new IntroPrompt(ui.prompt);
|
||||
this.eraserPreview = new EraserPreview(canvas, ui.eraserPreview);
|
||||
|
|
@ -102,25 +94,14 @@ export default class GameLoop {
|
|||
}
|
||||
|
||||
public onVibeChanged(): void {
|
||||
this.agentPopulation.onVibeChanged();
|
||||
this.renderInputs.invalidate();
|
||||
this.agentPopulation.onVibeChanged();
|
||||
}
|
||||
|
||||
public setAudioMuted(isMuted: boolean): void {
|
||||
this.audio.setMuted(isMuted);
|
||||
}
|
||||
|
||||
public setStatsOverlayPinned(isPinned: boolean): void {
|
||||
const wasVisible = this.shouldShowDevStats;
|
||||
this.isStatsOverlayPinned = isPinned;
|
||||
this.syncDevStatsVisibility();
|
||||
|
||||
if (!wasVisible && this.shouldShowDevStats) {
|
||||
this.lastDevStatsUpdateAt = Number.NEGATIVE_INFINITY;
|
||||
this.updateDevStats(performance.now());
|
||||
}
|
||||
}
|
||||
|
||||
public startAudio(userGesture = false): void {
|
||||
this.audio.start(activeVibe, { userGesture });
|
||||
}
|
||||
|
|
@ -134,10 +115,6 @@ export default class GameLoop {
|
|||
return this.finished.promise;
|
||||
}
|
||||
|
||||
public get maxAgentCount(): number {
|
||||
return this.agentPopulation.maxAgentCount;
|
||||
}
|
||||
|
||||
public async export4K(): Promise<void> {
|
||||
return this.export4KRenderer.export();
|
||||
}
|
||||
|
|
@ -150,7 +127,6 @@ export default class GameLoop {
|
|||
window.removeEventListener('keydown', this.keydownListener);
|
||||
this.pointerInput.detach();
|
||||
this.toolbarContrastMonitor.destroy();
|
||||
this.devStatsElement?.remove();
|
||||
this.introPrompt.destroy();
|
||||
this.resources.destroy();
|
||||
await this.audio.destroy();
|
||||
|
|
@ -164,29 +140,19 @@ export default class GameLoop {
|
|||
|
||||
const deltaTime = this.deltaTimeCalculator.calculateDeltaTimeInSeconds(time);
|
||||
this.framePerformance.update(time);
|
||||
this.agentPopulation.growBudget(
|
||||
deltaTime,
|
||||
this.framePerformance.smoothedFps,
|
||||
this.framePerformance.refreshTargetFps
|
||||
);
|
||||
this.agentPopulation.growBudget(deltaTime, this.framePerformance.smoothedFps);
|
||||
this.introPrompt.update();
|
||||
this.resize();
|
||||
this.resizeSimulationToCanvas();
|
||||
|
||||
const { channelColors, backgroundColor } = this.renderInputs.get();
|
||||
const introProgress = this.introPrompt.progress;
|
||||
const cameraZoom = 1;
|
||||
const cameraCenter: [number, number] = [
|
||||
this.canvas.width / 2,
|
||||
this.canvas.height / 2,
|
||||
];
|
||||
const eraserPixelSize = settings.eraserSize * this.devicePixelRatio;
|
||||
const isErasing = this.pointerInput.isEraseMode;
|
||||
const accentColor = channelColors[settings.selectedColorIndex] ?? channelColors[0];
|
||||
this.renderInputs.updateAccentColor(accentColor);
|
||||
this.audio.update({
|
||||
vibe: activeVibe,
|
||||
selectedColorIndex: settings.selectedColorIndex,
|
||||
isErasing,
|
||||
});
|
||||
|
||||
|
|
@ -200,8 +166,6 @@ export default class GameLoop {
|
|||
isErasing,
|
||||
channelColors,
|
||||
backgroundColor,
|
||||
cameraCenter,
|
||||
cameraZoom,
|
||||
eraserPixelSize,
|
||||
});
|
||||
|
||||
|
|
@ -213,60 +177,9 @@ export default class GameLoop {
|
|||
this.pointerInput.clearSwipesIfIdle();
|
||||
await this.agentPopulation.compactAfterErase(this.pointerInput.isSwipeActive);
|
||||
|
||||
this.updateDevStats(time);
|
||||
|
||||
if (settings.simulatedDelayMs > 0) {
|
||||
await sleep(settings.simulatedDelayMs);
|
||||
}
|
||||
|
||||
requestAnimationFrame(this.render);
|
||||
};
|
||||
|
||||
private createDevStatsElement(): HTMLDivElement | null {
|
||||
const container = this.canvas.parentElement;
|
||||
if (!container) {
|
||||
return null;
|
||||
}
|
||||
|
||||
const element = document.createElement('div');
|
||||
element.className = 'dev-stats-overlay';
|
||||
element.setAttribute('aria-hidden', 'true');
|
||||
container.appendChild(element);
|
||||
return element;
|
||||
}
|
||||
|
||||
private updateDevStats(time: DOMHighResTimeStamp): void {
|
||||
if (
|
||||
!this.devStatsElement ||
|
||||
!this.shouldShowDevStats ||
|
||||
time - this.lastDevStatsUpdateAt < GameLoop.DEV_STATS_INTERVAL_MS
|
||||
) {
|
||||
return;
|
||||
}
|
||||
|
||||
this.lastDevStatsUpdateAt = time;
|
||||
const displayRefreshFps = Math.round(this.framePerformance.displayRefreshFps);
|
||||
this.devStatsElement.textContent = [
|
||||
`FPS ${this.framePerformance.smoothedFps.toFixed(1)} / ${displayRefreshFps}`,
|
||||
`Agents ${this.formatDevStatNumber(this.agentPopulation.activeAgentCount)}`,
|
||||
`Cap ${this.formatDevStatNumber(settings.agentBudgetMax)}`,
|
||||
].join('\n');
|
||||
}
|
||||
|
||||
private syncDevStatsVisibility(): void {
|
||||
if (!this.devStatsElement) {
|
||||
return;
|
||||
}
|
||||
|
||||
const isVisible = this.shouldShowDevStats;
|
||||
this.devStatsElement.hidden = !isVisible;
|
||||
this.devStatsElement.setAttribute('aria-hidden', String(!isVisible));
|
||||
}
|
||||
|
||||
private formatDevStatNumber(value: number): string {
|
||||
return Math.max(0, Math.round(value)).toLocaleString('en-US');
|
||||
}
|
||||
|
||||
private resize(): void {
|
||||
const width = Math.max(
|
||||
1,
|
||||
|
|
@ -310,8 +223,4 @@ export default class GameLoop {
|
|||
: 1;
|
||||
return Math.min(GameLoop.MAX_MIRROR_SEGMENT_COUNT, Math.max(1, Math.round(count)));
|
||||
}
|
||||
|
||||
private get shouldShowDevStats(): boolean {
|
||||
return import.meta.env.DEV || this.isStatsOverlayPinned;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in a new issue