ants/src/GUI.ts

99 lines
3.1 KiB
TypeScript

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<string, EventHandler[]> = 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;