UNPKG

@itwin/core-bentley

Version:

Bentley JavaScript core components

153 lines 6.04 kB
"use strict"; /*--------------------------------------------------------------------------------------------- * Copyright (c) Bentley Systems, Incorporated. All rights reserved. * See LICENSE.md in the project root for license terms and full copyright notice. *--------------------------------------------------------------------------------------------*/ /** @packageDocumentation * @module Events */ Object.defineProperty(exports, "__esModule", { value: true }); exports.BeEventList = exports.BeUiEvent = exports.BeEvent = void 0; const UnexpectedErrors_1 = require("./UnexpectedErrors"); /** * Manages a set of *listeners* for a particular event and notifies them when the event is raised. * This class is usually instantiated inside of a container class and * exposed as a property for others to *subscribe* via [[BeEvent.addListener]]. * @public */ class BeEvent { _listeners = []; _insideRaiseEvent = false; /** The number of listeners currently subscribed to the event. */ get numberOfListeners() { return this._listeners.length; } /** * Registers a Listener to be executed whenever this event is raised. * @param listener The function to be executed when the event is raised. * @param scope An optional object scope to serve as the 'this' pointer when listener is invoked. * @returns A function that will remove this event listener. * @see [[BeEvent.raiseEvent]], [[BeEvent.removeListener]] */ addListener(listener, scope) { this._listeners.push({ listener, scope, once: false }); return () => this.removeListener(listener, scope); } /** * Registers a callback function to be executed *only once* when the event is raised. * @param listener The function to be executed once when the event is raised. * @param scope An optional object scope to serve as the `this` pointer in which the listener function will execute. * @returns A function that will remove this event listener. * @see [[BeEvent.raiseEvent]], [[BeEvent.removeListener]] */ addOnce(listener, scope) { this._listeners.push({ listener, scope, once: true }); return () => this.removeListener(listener, scope); } /** * Un-register a previously registered listener. * @param listener The listener to be unregistered. * @param scope The scope that was originally passed to addListener. * @returns 'true' if the listener was removed; 'false' if the listener and scope are not registered with the event. * @see [[BeEvent.raiseEvent]], [[BeEvent.addListener]] */ removeListener(listener, scope) { const listeners = this._listeners; for (let i = 0; i < listeners.length; ++i) { const context = listeners[i]; if (context.listener === listener && context.scope === scope) { if (this._insideRaiseEvent) { context.listener = undefined; } else { listeners.splice(i, 1); } return true; } } return false; } /** * Raises the event by calling each registered listener with the supplied arguments. * @param args This method takes any number of parameters and passes them through to the listeners. * @see [[BeEvent.removeListener]], [[BeEvent.addListener]] */ raiseEvent(...args) { this._insideRaiseEvent = true; const listeners = this._listeners; const length = listeners.length; let dropped = false; for (let i = 0; i < length; ++i) { const context = listeners[i]; if (!context.listener) { dropped = true; } else { try { context.listener.apply(context.scope, args); } catch (e) { UnexpectedErrors_1.UnexpectedErrors.handle(e); } if (context.once) { context.listener = undefined; dropped = true; } } } // if we had dropped listeners, remove them now if (dropped) this._listeners = this._listeners.filter((ctx) => ctx.listener !== undefined); this._insideRaiseEvent = false; } /** Determine whether this BeEvent has a specified listener registered. * @param listener The listener to check. * @param scope optional scope argument to match call to addListener */ has(listener, scope) { for (const ctx of this._listeners) { if (ctx.listener === listener && ctx.scope === scope) { return true; } } return false; } /** Clear all Listeners from this BeEvent. */ clear() { this._listeners.length = 0; } } exports.BeEvent = BeEvent; /** Specialization of BeEvent for events that take a single strongly typed argument, primarily used for UI events. * @public */ class BeUiEvent extends BeEvent { /** Raises event with single strongly typed argument. */ emit(args) { this.raiseEvent(args); } } exports.BeUiEvent = BeUiEvent; /** * A list of BeEvent objects, accessible by an event name. * This class may be used instead of explicitly declaring each BeEvent as a member of a containing class. * @public */ class BeEventList { _events = {}; /** * Gets the event associated with the specified name, creating the event if it does not already exist. * @param name The name of the event. */ get(name) { let event = this._events[name]; if (event) return event; event = new BeEvent(); this._events[name] = event; return event; } /** * Removes the event associated with a name. * @param name The name of the event. */ remove(name) { this._events[name] = undefined; } } exports.BeEventList = BeEventList; //# sourceMappingURL=BeEvent.js.map