HJ_Server/src/shared/myEventEmitter.ts
DESKTOP-15R5JU0\legu 97e070ea81 init
2023-11-17 12:02:12 +08:00

130 lines
3.7 KiB
TypeScript

// type EventCallback = (...args: any[]) => void;
// export class myEventEmitter {
// private events: Map<string, Set<EventCallback>>;
// constructor() {
// this.events = new Map();
// }
// public on(eventName: string, callback: EventCallback) {
// if (!this.events.has(eventName)) {
// this.events.set(eventName, new Set());
// }
// const eventListeners = this.events.get(eventName);
// eventListeners.add(callback);
// }
// public once(eventName: string, callback: EventCallback) {
// const onceCallback: EventCallback = (...args: any[]) => {
// this.off(eventName, onceCallback);
// callback(...args);
// };
// this.on(eventName, onceCallback);
// }
// public off(eventName: string, callback: EventCallback) {
// if (!this.events.has(eventName)) {
// return;
// }
// const eventListeners = this.events.get(eventName);
// let isSucc = eventListeners.delete(callback);
// if (eventListeners.size === 0) {
// this.events.delete(eventName);
// }
// }
// public emit(eventName: string, ...args: any[]) {
// if (!this.events.has(eventName)) {
// return;
// }
// const eventListeners = this.events.get(eventName);
// eventListeners.forEach((callback) => {
// callback(...args);
// });
// }
// }
type Listener<T extends any[]> = (...args: T) => void;
interface EventMap {
[event: string]: unknown[];
}
interface ListenerMap {
[event: string]: Listener<any>[];
}
interface EventEmitter {
on<T extends any[]>(event: string, listener: Listener<T>): this;
once<T extends any[]>(event: string, listener: Listener<T>): this;
off<T extends any[]>(event: string, listener: Listener<T>): this;
emit<T extends any[]>(event: string, ...args: T): this;
}
class EventEmitterImpl implements EventEmitter {
private events: EventMap = {};
private listeners: ListenerMap = {};
public on<T extends any[]>(event: string, listener: Listener<T>): this {
this.addListener(event, listener);
return this;
}
public once<T extends any[]>(event: string, listener: Listener<T>): this {
const onceListener: Listener<T> = (...args: T) => {
this.off(event, onceListener);
listener(...args);
};
this.addListener(event, onceListener);
return this;
}
public off<T extends any[]>(event: string, listener: Listener<T>): this {
const listeners = this.listeners[event];
if (!listeners) return this;
const index = listeners.indexOf(listener);
if (index >= 0) {
listeners.splice(index, 1);
if (listeners.length === 0) {
delete this.events[event];
delete this.listeners[event];
}
}
return this;
}
public emit<T extends any[]>(event: string, ...args: T): this {
const listeners = this.listeners[event];
if (!listeners) return this;
const events = this.events[event] as T;
if (events) {
events.push(...args);
} else {
this.events[event] = args;
}
listeners.slice().forEach((listener) => listener(...args));
return this;
}
public clear(): void {
this.events = {};
this.listeners = {};
}
private addListener<T extends any[]>(event: string, listener: Listener<T>): void {
if (!this.listeners[event]) {
this.listeners[event] = [];
}
this.listeners[event].push(listener);
}
}
export const myEventEmitter = EventEmitterImpl;