import GUI from "lil-gui"; import Config, { resetConfig, saveConfig } from "./Config"; type EventHandler = () => void; class GUIController { private gui: GUI = new GUI({ container: document.getElementById("gui-container") as HTMLElement, }); private listeners: Map = new Map(); constructor() { const simFolder = this.gui.addFolder("Simulation"); simFolder .add(Config, "worldSize", 256, 4096) .name("World size") .step(1) .onChange(() => this.saveAndEmit("reset")); simFolder .add(Config, "antsCount", 0, 22) .name("Ants count 2^") .step(1) .onChange(() => this.saveAndEmit("reset")); simFolder .add(Config, "scentFadeOutFactor", 0, 0.01) .name("Pheromone evaporation factor") .step(0.0001) .onChange(() => this.saveAndEmit("reset")); simFolder .add(Config, "scentBlurRadius", 0, 0.5) .name("Pheromone diffusion factor") .step(0.01) .onChange(() => this.saveAndEmit("reset")); simFolder .add(Config, "simulationStepsPerSecond", 1, 500) .name("Simulation steps per second") .step(1) .onChange(() => saveConfig()); const controlsFolder = this.gui.addFolder("Controls"); controlsFolder .add(Config, "brushRadius", 1, 100) .name("Brush radius") .onChange(() => saveConfig()); controlsFolder .add(Config, "cameraZoom") .name("Zoom") .step(0.1) .listen() .onChange(() => this.emit("zoomChange")); controlsFolder .add(Config, "viewMode", ["side", "top"]) .name("View mode") .listen() .onChange(() => this.saveAndEmit("reset")); simFolder.open(); controlsFolder.open(); const resetBtn = document.createElement("button"); resetBtn.textContent = "Reset to defaults"; resetBtn.className = "reset-btn"; resetBtn.addEventListener("click", () => { resetConfig(); for (const c of this.gui.controllersRecursive()) { c.updateDisplay(); } this.emit("reset"); }); // biome-ignore lint/style/noNonNullAssertion: gui-container exists in index.html document.getElementById("gui-container")!.appendChild(resetBtn); } on(event: string, handler: EventHandler): void { if (!this.listeners.has(event)) { this.listeners.set(event, []); } // biome-ignore lint/style/noNonNullAssertion: guaranteed by .has() check above this.listeners.get(event)!.push(handler); } private saveAndEmit(event: string): void { saveConfig(); this.emit(event); } private emit(event: string): void { const handlers = this.listeners.get(event); if (handlers) { for (const handler of handlers) { handler(); } } } } export default GUIController;