Source: engine/StateEngine.js

(function() {
    /**
     * @namespace engine
     * @memberof Help4
     */
    Help4.engine = {};

    /**
     * @typedef {Object} Help4.engine.StateEngine.Params
     * @property {Help4.controller.Controller} [controller = null]
     * @property {Help4.EventBus} [eventBus = null]
     */

    /**
     * @augments Help4.Object
     * @param {Help4.engine.StateEngine.Params} params
     * @param {Object} classParams
     * @constructor
     */
    Help4.engine.StateEngine = function(params, classParams = null) {
        if (classParams) this._params = classParams;

        this._params = Help4.extendObject(this._params || {}, {
            controller: null,
            eventBus: null
        }, false);

        Help4.Object.call(this, params);

        this._controls = {};
        this._observers = {};
        this._started = false;
    };
    Help4.engine.StateEngine.prototype = Object.create(Help4.Object.prototype);
    Help4.engine.StateEngine.prototype.constructor = Help4.engine.StateEngine;

    Help4.extendObject(Help4.engine.StateEngine.prototype, {
        destroy: _destroy,
        getController: function() { return this._params.controller; },
        isStarted: function() { return this._started; },
        start: function() { this._started = true; },
        stop: _stop,

        _getControlParams: _getControlParams
    });

    function _destroy() {
        this.stop();
        delete this._controls;
        delete this._started;

        const {_observers} = this;
        if (_observers) {
            for (const observer of Object.values(_observers)) {
                observer.destroy?.();
            }
            delete this._observers;
        }

        Help4.Object.prototype.destroy.call(this);
    }

    function _stop() {
        if (!this._started) return;

        const {_controls = {}, _observers = {}} = this;

        for (const observer of Object.values(_observers)) {
            observer.disconnect?.();
        }
        for (const control of Object.values(_controls)) {
            control.destroy?.();
        }

        this._controls = {};
        this._started = false;
    }

    function _getControlParams() {
        const {rtl, mobile, language} = this._params;
        return {rtl, mobile, language};
    }
})();