105 lines
4.0 KiB
JavaScript
105 lines
4.0 KiB
JavaScript
"use strict";
|
|
(function modulePrivateClosure () {
|
|
/**
|
|
* A class that represents Mimicry Module
|
|
* */
|
|
class Module {
|
|
/**
|
|
* @param {Array<Dependency>} 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;
|
|
})(); |