export type ListenerCB = (this: T, ...args: any[]) => void; /** * A callback that listens to _changes_ in the Emitter listeners. This is mainly used for * internal purposes. */ export type ChangeCB = (hasListeners: boolean) => void; /** * This is an implementation of a doubly-linked list, with just the minimal functionality we need. * @internal */ export declare class LLink { protected _next: LLink | null; protected _prev: LLink | null; constructor(); isDisposed(): boolean; protected _insertBefore(next: LLink, node: LLink): void; protected _removeNode(node: LLink): void; protected _disposeList(): void; } /** * An `Emitter` emits events to a list of listeners. Listeners are * simply functions to call, and "emitting an event" just calls those functions. * * This is similar to Backbone events, with more focus on efficiency. Both inserting and removing * listeners is constant time. * * To create an emitter: * ```ts * const emitter = new Emitter(); * ``` * * To add a listener: * ```ts * const listener = fooEmitter.addListener(callback); * ``` * * To remove a listener: * ```ts * listener.dispose(); * ``` * * The only way to remove a listener is to dispose the `Listener` object returned by `addListener()`. * You can often use autoDispose to do this automatically when subscribing in a constructor: * ```ts * this.autoDispose(fooEmitter.addListener(this.onFoo, this)); * ``` * * To emit an event, call `emit()` with any number of arguments: * ```ts * emitter.emit("hello", "world"); * ``` * * @privateRemarks * * Note about a possible alternative implementation. * * We could implement the same interface using an array of listeners. Certain issues apply, in * particular with removing listeners from inside emit(), and in ensuring that removals are * constant time on average. Such an implementation was attempted and timed. The result is that * compared to the linked-list implementation here, add/remove combination could be made nearly * twice faster (on average), while emit and add/remove/emit are consistently slightly slower. * * The implementation here was chosen based on those timings, and as the simpler one. For example, * on one setup (macbook, node4, 5-listener queue), add+remove take 0.1us, while add+remove+emit * take 3.82us. (In array-based implementation with same set up, add+remove is 0.06us, while * add+remove+emit is 4.80us.) */ export declare class Emitter extends LLink { private _changeCB; private _changeCBContext; /** * Adds a listening callback to the list of functions to call on emit(). * @param callback - Function to call. * @param optContext - Context for the function. * @returns Listener object. Its dispose() method removes the callback from the list. */ addListener(callback: ListenerCB, optContext?: T): Listener; /** * Calls all listener callbacks, passing all arguments to each of them. */ emit(...args: any[]): void; /** * Sets the single callback that would get called when a listener is added or removed. * @param changeCB - Function to call after a listener is added or * removed. It's called with a boolean indicating whether this Emitter has any listeners. * Pass in `null` to unset the callback. Note that it can be called multiple times in a row * with hasListeners `true`. */ setChangeCB(changeCB: ChangeCB, optContext?: any): void; /** * Helper used by Listener class, but not intended for public usage. * @internal */ _triggerChangeCB(): void; /** * Returns whether this Emitter has any listeners. */ hasListeners(): boolean; /** * Disposes the Emitter. It breaks references between the emitter and all the items, allowing * for better garbage collection. It effectively disposes all current listeners. */ dispose(): void; } /** * The `Listener` object wraps a callback added to an Emitter, allowing for O(1) removal when the * listener is disposed. It implements `IDisposable`. */ export declare class Listener extends LLink { private emitter; private callback; private context?; /** @internal */ static callAll(begin: LLink, end: LLink, args: any[]): void; constructor(emitter: Emitter, callback: ListenerCB, context?: any); /** @internal */ dispose(): void; }