| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105 | /** *  Events allow for applications to use the observer pattern, which *  allows subscribing and publishing events, outside the normal *  execution paths. * *  @_section api/utils/events:Events  [about-events] */import { defineProperties } from "./properties.js";/** *  A callback function called when a an event is triggered. */export type Listener = (...args: Array<any>) => void;/** *  An **EventEmitterable** behaves similar to an EventEmitter *  except provides async access to its methods. * *  An EventEmitter implements the observer pattern. */export interface EventEmitterable<T> {    /**     *  Registers a %%listener%% that is called whenever the     *  %%event%% occurs until unregistered.     */    on(event: T, listener: Listener): Promise<this>;    /**     *  Registers a %%listener%% that is called the next time     *  %%event%% occurs.     */    once(event: T, listener: Listener): Promise<this>;    /**     *  Triggers each listener for %%event%% with the %%args%%.     */    emit(event: T, ...args: Array<any>): Promise<boolean>;    /**     *  Resolves to the number of listeners for %%event%%.     */    listenerCount(event?: T): Promise<number>;    /**     *  Resolves to the listeners for %%event%%.     */    listeners(event?: T): Promise<Array<Listener>>;    /**     *  Unregister the %%listener%% for %%event%%. If %%listener%%     *  is unspecified, all listeners are unregistered.     */    off(event: T, listener?: Listener): Promise<this>;    /**     *  Unregister all listeners for %%event%%.     */    removeAllListeners(event?: T): Promise<this>;    /**     *  Alias for [[on]].     */    addListener(event: T, listener: Listener): Promise<this>;    /**     *  Alias for [[off]].     */    removeListener(event: T, listener: Listener): Promise<this>;}/** *  When an [[EventEmitterable]] triggers a [[Listener]], the *  callback always ahas one additional argument passed, which is *  an **EventPayload**. */export class EventPayload<T> {    /**     *  The event filter.     */    readonly filter!: T;    /**     *  The **EventEmitterable**.     */    readonly emitter!: EventEmitterable<T>;    readonly #listener: null | Listener;    /**     *  Create a new **EventPayload** for %%emitter%% with     *  the %%listener%% and for %%filter%%.     */    constructor(emitter: EventEmitterable<T>, listener: null | Listener, filter: T) {        this.#listener = listener;        defineProperties<EventPayload<any>>(this, { emitter, filter });    }    /**     *  Unregister the triggered listener for future events.     */    async removeListener(): Promise<void> {        if (this.#listener == null) { return; }        await this.emitter.off(this.filter, this.#listener);    }}
 |