event_event_handler.js

/**
 * @module EventHandler
 * @fileoverview Contains EventHandler class.
 */

/**
 * Generalized events manager for use in App, Actor, etc.
 * @class
 */
class EventHandler {
    /**
     * Create a new EventHandler.
     * @constructor
     */
    constructor() {
        /** Holds arrays of events to be triggered. */
        this._events = new Map();

        this._children = new Set();
    }

    addChild(child) {
        this._children.add(child);
    }

    getChildren() {
        return Array.from(this._children.values());
    }


    // Management

    /**
     * Register a new event listener.
     * @param {string} event Key for the event to listen for
     * @param {function} func Function to run upon firing
     * @returns {number} Index of added function
     */
    on(event, func = () => {}) {
        if (!this._events.has(event))
            this._events.set(event, []);

        const index = this._events.get(event).length;

        this._events.get(event).push(func);

        return index;
    }


    // Execution

    /**
     * Trigger an event.
     * @param {string} event Key of event to trigger.
     * @param args Arguments to pass into listener function
     */
    do(event, ...args) {
        if (!this._events.has(event))
            return;

        for (const func of this._events.get(event))
            func(...args);
    }


    // Removal

    /**
     * Clear all registered events.
     */
    clear() {
        this._events = new Map();
    }

    clearPrefix(prefix) {
        for (const event of this._events.keys())
            if (event.indexOf(prefix) === 0)
                this._events.delete(event);
    }

    /**
     * Remove a registered event.
     * @param {string} event Event ID/type
     * @param {number} i Index of script (ignore to delete all for event type)
     */
    remove(event, i = -1) {
        if (i === -1) {
            this._events.delete(event);
            return;
        }

        this._events.get(event).splice(i, 1);
        if (this._events.get(event).length === 0)
            this._events.delete(event);
    }


    // Iteration

    /**
     * Run a function for each listing.
     * @param {function} func Function to run
     */
    forEach(func = (array, id) => {}) {
        this._events.forEach(func);
    }
}

export default EventHandler;