Files
bitburner-src/src/utils/EventEmitter.ts
T
David Walker f3e9e3ddc8 BUGFIX: Avoid re-entrency issues with EventEmitter (#2397)
Subscribing or unsubscribing from within an event handler (possibly
transitively) could cause issues or even infinite loops.

This was initially fixed in #2257, which exhibited such problems.
Currently no code is known to have this issue, but it could easily come
up again in the future.
2025-11-22 18:13:44 -08:00

27 lines
815 B
TypeScript

/** Generic Event Emitter class following a subscribe/publish paradigm. */
export class EventEmitter<T extends any[]> {
private subscribers: Set<(...args: [...T]) => void> = new Set();
subscribe(s: (...args: [...T]) => void): () => void {
this.subscribers.add(s);
return () => {
this.subscribers.delete(s);
};
}
emit(...args: [...T]): void {
// It is necessary to make a copy of the subscribers list, because since
// the subscribers call arbitrary code, it can eventually call back in and
// subscribe or unsubscribe new listeners. We must only dispatch to the
// ones that were active at the time the event came in.
for (const sub of [...this.subscribers]) {
sub(...args);
}
}
hasSubscribers(): boolean {
return this.subscribers.size > 0;
}
}