HumanBreak/src/core/common/eventEmitter.ts

74 lines
1.8 KiB
TypeScript
Raw Normal View History

2023-06-04 23:06:56 +08:00
export interface EmitableEvent {
[event: string]: (...params: any) => any;
}
interface Listener<T extends (...params: any) => any> {
fn: T;
once?: boolean;
}
interface ListenerOptions {
once: boolean;
}
export class EventEmitter<T extends EmitableEvent = {}> {
private events: {
[P in keyof T]?: Listener<T[P]>[];
} = {};
/**
*
* @param event
* @param fn
* @param options
*/
on<K extends keyof T>(
event: K,
fn: T[K],
options?: Partial<ListenerOptions>
) {
this.events[event] ??= [];
this.events[event]?.push({
fn,
once: options?.once
});
}
/**
*
* @param event
* @param fn
*/
off<K extends keyof T>(event: K, fn: T[K]) {
const index = this.events[event]?.findIndex(v => v.fn === fn);
if (index === -1 || index === void 0) return;
this.events[event]?.splice(index, 1);
}
/**
*
* @param event
* @param fn
*/
once<K extends keyof T>(event: K, fn: T[K]) {
this.on(event, fn, { once: true });
}
/**
*
* @param event
* @param params
*/
emit<K extends keyof T>(event: K, ...params: Parameters<T[K]>) {
const events = (this.events[event] ??= []);
for (let i = 0; i < events.length; i++) {
const e = events[i];
e.fn(...(params as any));
if (e.once) {
events.splice(i, 1);
i--;
}
}
}
}