private class fields for EffectIntegrator

This commit is contained in:
“chrisshank” 2024-12-19 00:29:39 -08:00
parent c556153fab
commit f80e9f2d9a
2 changed files with 24 additions and 22 deletions

View File

@ -5,47 +5,47 @@ import type { FolkShape } from '../labs/folk-shape';
* Systems register, yield effects, and await integration when all systems are ready. * Systems register, yield effects, and await integration when all systems are ready.
*/ */
export class EffectIntegrator<E extends Element, T> { export class EffectIntegrator<E extends Element, T> {
private pending = new Map<E, T[] | T>(); #pending = new Map<E, T[] | T>();
private systems = new Set<string>(); #systems = new Set<string>();
private waiting = new Set<string>(); #waiting = new Set<string>();
private resolvers: ((value: Map<E, T>) => void)[] = []; #resolvers: ((value: Map<E, T>) => void)[] = [];
/** Register a system to participate in effect integration */ /** Register a system to participate in effect integration */
register(id: string) { register(id: string) {
this.systems.add(id); this.#systems.add(id);
return { return {
yield: (element: E, effect: T) => { yield: (element: E, effect: T) => {
if (!this.pending.has(element)) { if (!this.#pending.has(element)) {
this.pending.set(element, []); this.#pending.set(element, []);
} }
(this.pending.get(element)! as T[]).push(effect); (this.#pending.get(element)! as T[]).push(effect);
}, },
/** Wait for all systems to submit effects, then receive integrated results */ /** Wait for all systems to submit effects, then receive integrated results */
integrate: async (): Promise<Map<E, T>> => { integrate: async (): Promise<Map<E, T>> => {
this.waiting.add(id); this.#waiting.add(id);
if (this.waiting.size === this.systems.size) { if (this.#waiting.size === this.#systems.size) {
// Last system to call integrate - do integration // Last system to call integrate - do integration
for (const [element, effects] of this.pending) { for (const [element, effects] of this.#pending) {
this.pending.set(element, (this.constructor as typeof EffectIntegrator).integrate(element, effects as T[])); this.#pending.set(element, (this.constructor as typeof EffectIntegrator).integrate(element, effects as T[]));
} }
const results = this.pending as Map<E, T>; const results = this.#pending as Map<E, T>;
// Reset for next frame // Reset for next frame
this.pending = new Map(); this.#pending = new Map();
this.waiting.clear(); this.#waiting.clear();
// Resolve all waiting systems // Resolve all waiting systems
this.resolvers.forEach((resolve) => resolve(results)); this.#resolvers.forEach((resolve) => resolve(results));
this.resolvers = []; this.#resolvers = [];
return results; return results;
} }
// Not all systems ready - wait for integration // Not all systems ready - wait for integration
return new Promise((resolve) => { return new Promise((resolve) => {
this.resolvers.push(resolve); this.#resolvers.push(resolve);
}); });
}, },
}; };
@ -67,13 +67,13 @@ interface TransformEffect {
} }
export class TransformIntegrator extends EffectIntegrator<FolkShape, TransformEffect> { export class TransformIntegrator extends EffectIntegrator<FolkShape, TransformEffect> {
private static instance: TransformIntegrator; static #instance: TransformIntegrator;
static register(id: string) { static register(id: string) {
if (!TransformIntegrator.instance) { if (!TransformIntegrator.#instance) {
TransformIntegrator.instance = new TransformIntegrator(); TransformIntegrator.#instance = new TransformIntegrator();
} }
return TransformIntegrator.instance.register(id); return TransformIntegrator.#instance.register(id);
} }
/** If the element is focused, return the elements rect, otherwise average the effects */ /** If the element is focused, return the elements rect, otherwise average the effects */

View File

@ -1,5 +1,7 @@
/** A raw tagged template literal that just provides GLSL syntax highlighting/LSP support. */
export const glsl = String.raw; export const glsl = String.raw;
/** A raw tagged template literal that just provides HTML syntax highlighting/LSP support. */
export const html = String.raw; export const html = String.raw;
export function css(strings: TemplateStringsArray, ...values: any[]) { export function css(strings: TemplateStringsArray, ...values: any[]) {