/** * @class Events * @description A basic event handling system that supports adding events, listeners, and emitting events. */ export default class Events { /** Stores events and associated data. */ private _events: Record>; /** Stores listeners for specific events. */ private _listeners: Record void; context: any }>>; /** Initializes an empty events storage and listeners storage. */ constructor() { this._events = {}; this._listeners = {}; } /** * Adds an event with associated data to be emitted later. * @param event * @param data */ addEvent(event: string, data?: any): void { if (!this._events[event]) { this._events[event] = []; } this._events[event].push(data); } /** * Registers a listener for a specific event. * @param event * @param fn * @param context */ addListener(event: string, fn: (data?: any) => void, context: any): void { if (!this._listeners[event]) { this._listeners[event] = []; } this._listeners[event].push({ event, fn, context }); } /** * Removes a specific listener for an event. * @param event * @param fn * @param context */ removeEventListener(event: string, fn: (data?: any) => void, context: any): void { if (!this._listeners[event]) return; this._listeners[event] = this._listeners[event].filter( (listener) => listener.fn !== fn || listener.context !== context ); } /** Clears all stored events. */ clearEvents(): void { this._events = {}; } /** * Emits all stored events, invoking associated listeners with the event data. * The listeners for each event receive each piece of data associated with that event. */ emitEvents(): void { for (const eventName in this._events) { const dataObjects = this._events[eventName]; const listeners = this._listeners[eventName]; if (!listeners) continue; dataObjects.forEach((data) => { listeners.forEach((listener) => { listener.fn.call(listener.context, data); }); }); delete this._events[eventName]; } } }