Files
scriptc/scripts/split/configs/loop-state/emitter-state.template
T
Chris Tate f1d694b47b Move the emitter's loop optimization state into loop-state.ts
LlEmitter's field list and constructor are where most concurrent edits to
emitter.ts collide. A feature now defines its state in its own file with
defineModuleState (emitter-state.ts) and reads it through the returned key,
so it no longer edits the class. The loop optimizations' twelve fields and
their per-function setup move to loop-state.ts; the emitted IR is unchanged.

scripts/split holds the transforms used for the emitter and lowering
splits, and rehome-split.mjs, which carries an open branch across a split.
2026-10-20 18:58:42 -05:00

25 lines
849 B
Plaintext

/* Per-feature emitter state. A feature defines its state in its own file
* with defineModuleState and reads it through the returned key, so adding
* or extending a feature does not edit LlEmitter's field list or
* constructor. */
import type { LlEmitter } from "./emitter.js";
/** A feature's state on an emitter, read with `key.of(emitter)`. */
export interface EmitterStateKey<T> {
of(emitter: LlEmitter): T;
}
let moduleSlots = 0;
/** State that lives for the whole module, created on first read. */
export function defineModuleState<T>(create: (emitter: LlEmitter) => T): EmitterStateKey<T> {
const slot = moduleSlots++;
return {
of(emitter) {
const states = emitter.moduleStates;
if (slot >= states.length || states[slot] === undefined) states[slot] = create(emitter);
return states[slot] as T;
},
};
}