From ce4884c48a8ed239dd8e78d2892181f3ea4fb9a2 Mon Sep 17 00:00:00 2001 From: Peter Fajdiga Date: Sat, 29 Nov 2025 17:57:59 +0100 Subject: [PATCH] Implement signal grouping --- src/lib/utils/SignalGrouping.ts | 66 +++++++++++++++++++++++++++++++++ 1 file changed, 66 insertions(+) create mode 100644 src/lib/utils/SignalGrouping.ts diff --git a/src/lib/utils/SignalGrouping.ts b/src/lib/utils/SignalGrouping.ts new file mode 100644 index 0000000..c986a77 --- /dev/null +++ b/src/lib/utils/SignalGrouping.ts @@ -0,0 +1,66 @@ +namespace SignalGrouping { + export class Group[]> { + private signalManager: SignalManager; + private argsBySignal: Map> = new Map(); + private delayer = new Delayer(50, () => this.fire()); + + constructor( + private handlers: Handler[], // in order of decreasing priority + ) { + this.signalManager = new SignalManager(); + const signals = collectSignals(handlers); + for (const signal of signals) { + this.signalManager.connect(signal, (...args: any) => { + this.argsBySignal.set(signal, args); + this.delayer.run(); + }); + } + } + + public fire() { + for (const handler of this.handlers) { + const args = this.getGroupArgs(handler.signals); + if (args !== null) { + handler.f(...args); + break; + } + } + this.argsBySignal.clear(); + } + + public destroy() { + this.signalManager.destroy(); + } + + private getGroupArgs(signals: [...S]) { + const groupArgs = signals.map(signal => this.argsBySignal.get(signal)); + if (groupArgs.some(args => args === undefined)) { + return null; + } + return groupArgs as [...GroupArgs]; + } + } + + function collectSignals[]>(handlers: Handler[]) { + const signals: S[number][] = []; + for (const handler of handlers) { + for (const signal of handler.signals) { + if (!signals.includes(signal)) { + signals.push(signal); + } + } + } + return signals; + } + + interface Handler[]> { + signals: [...S]; + f: (...args: [...GroupArgs]) => void; + } + + type GroupArgs[]> = { + [K in keyof S]: S[K] extends QSignal ? A : never; + }; + + type GroupUnion[]> = S[number] extends QSignal ? A : never; +}