"use strict"; (function modulePrivateClosure () { /** * A class that represents Mimicry Module * */ class Module { /** * @param {Array} deps - array of files that this module depends on * @param {Function} body - body function of the module that defines the module itself * */ constructor (deps, body) { this._dependencies = deps; this._body = body; this._loaded = 0; this._callbacks = []; this._value = null; this._executed = false; } /** * @returns {Boolean} - true if the module have already been executed * */ get executed () { return this._executed; } /** * @returns {any} - a value that is returned from the module body function * */ get value () { return this._value; } /** * @returns {Boolean} - true if the module has its dependencies resolved * */ get allDependenciesResolved () { return this.executed || this._loaded === this._dependencies.length; } /** * This function should be called when one of the dependencies are considered to be satisfied * If the dependency is not a module this happens when the file is loaded * If the dependency is a module this happens when the module is executed * * @param {Mimicry} mimicry - Mimicry instance that was loading this module, * it is needed for calling "execute" if the dependencies are resolved * @param {any} global - a global object for current platform * */ incrementDependency (mimicry, global) { ++this._loaded if (this.allDependenciesResolved) this.execute(mimicry, global); } /** * If the modules is executed - calls the callback immediately * Otherwise remembers the callback and executes all of them in the same order * that they were added. * * Callback is called with the following arguments: * first: global object * second: the value of this module * * @param {Function} callback - a callback to call * @param {any} global - a global object for current platform * */ addCallback (/*Function*/callback, global) { if (this._executed) callback.call(null, global, this._value); else this._callbacks.push(callback); } /** * Executes a module, launching its body function * * @param {Mimicry} mimicry - an instance of Mimicry that was loading this module * It is needed to acquire values of dependencies * @param {any} global - a global object for current platform * */ execute (mimicry, global) { if (this.executed) throw new Error("An attempt to execute a module for the second time"); if (this._body instanceof Function) { const values = []; for (let i = 0; i < this._dependencies.length; ++i) { const name = this._dependencies[i].name; values.push(mimicry.getModule(name) || mimicry.getAsset(name)); } this._value = this._body.call(null, global, values); } else { this._value = null; } this._executed = true; const callbacks = this._callbacks; delete this._callbacks; delete this._dependencies; for (let i = 0; i < callbacks.length; ++i) callbacks[i].call(null, global, this._value); } } if (typeof module === 'object' && module.exports) module.exports = Module; else window.__MimicryModule__ = Module; })();