145 lines
4.0 KiB
JavaScript
145 lines
4.0 KiB
JavaScript
const Engine = (function () {
|
|
const preloader = new Preloader();
|
|
|
|
let loadPromise = null;
|
|
let loadPath = '';
|
|
let initPromise = null;
|
|
|
|
function load(basePath) {
|
|
if (loadPromise == null) {
|
|
loadPath = basePath;
|
|
loadPromise = preloader.loadPromise(`${loadPath}.wasm`);
|
|
requestAnimationFrame(preloader.animateProgress);
|
|
}
|
|
return loadPromise;
|
|
}
|
|
|
|
function unload() {
|
|
loadPromise = null;
|
|
}
|
|
|
|
/** @constructor */
|
|
function Engine(opts) { // eslint-disable-line no-shadow
|
|
this.config = new EngineConfig(opts);
|
|
this.rtenv = null;
|
|
}
|
|
|
|
Engine.prototype.init = /** @param {string=} basePath */ function (basePath) {
|
|
if (initPromise) {
|
|
return initPromise;
|
|
}
|
|
if (loadPromise == null) {
|
|
if (!basePath) {
|
|
initPromise = Promise.reject(new Error('A base path must be provided when calling `init` and the engine is not loaded.'));
|
|
return initPromise;
|
|
}
|
|
load(basePath);
|
|
}
|
|
preloader.setProgressFunc(this.config.onProgress);
|
|
let config = this.config.getModuleConfig(loadPath, loadPromise);
|
|
const me = this;
|
|
initPromise = new Promise(function (resolve, reject) {
|
|
Godot(config).then(function (module) {
|
|
module['initFS'](me.config.persistentPaths).then(function (fs_err) {
|
|
me.rtenv = module;
|
|
if (me.config.unloadAfterInit) {
|
|
unload();
|
|
}
|
|
resolve();
|
|
config = null;
|
|
});
|
|
});
|
|
});
|
|
return initPromise;
|
|
};
|
|
|
|
/** @type {function(string, string):Object} */
|
|
Engine.prototype.preloadFile = function (file, path) {
|
|
return preloader.preload(file, path);
|
|
};
|
|
|
|
/** @type {function(...string):Object} */
|
|
Engine.prototype.start = function (override) {
|
|
this.config.update(override);
|
|
const me = this;
|
|
return me.init().then(function () {
|
|
if (!me.rtenv) {
|
|
return Promise.reject(new Error('The engine must be initialized before it can be started'));
|
|
}
|
|
|
|
let config = {};
|
|
try {
|
|
config = me.config.getGodotConfig(function () {
|
|
me.rtenv = null;
|
|
});
|
|
} catch (e) {
|
|
return Promise.reject(e);
|
|
}
|
|
// Godot configuration.
|
|
me.rtenv['initConfig'](config);
|
|
|
|
// Preload GDNative libraries.
|
|
const libs = [];
|
|
me.config.gdnativeLibs.forEach(function (lib) {
|
|
libs.push(me.rtenv['loadDynamicLibrary'](lib, { 'loadAsync': true }));
|
|
});
|
|
return Promise.all(libs).then(function () {
|
|
return new Promise(function (resolve, reject) {
|
|
preloader.preloadedFiles.forEach(function (file) {
|
|
me.rtenv['copyToFS'](file.path, file.buffer);
|
|
});
|
|
preloader.preloadedFiles.length = 0; // Clear memory
|
|
me.rtenv['callMain'](me.config.args);
|
|
initPromise = null;
|
|
resolve();
|
|
});
|
|
});
|
|
});
|
|
};
|
|
|
|
Engine.prototype.startGame = function (override) {
|
|
this.config.update(override);
|
|
// Add main-pack argument.
|
|
const exe = this.config.executable;
|
|
const pack = this.config.mainPack || `${exe}.pck`;
|
|
this.config.args = ['--main-pack', pack].concat(this.config.args);
|
|
// Start and init with execName as loadPath if not inited.
|
|
const me = this;
|
|
return Promise.all([
|
|
this.init(exe),
|
|
this.preloadFile(pack, pack),
|
|
]).then(function () {
|
|
return me.start.apply(me);
|
|
});
|
|
};
|
|
|
|
Engine.prototype.copyToFS = function (path, buffer) {
|
|
if (this.rtenv == null) {
|
|
throw new Error('Engine must be inited before copying files');
|
|
}
|
|
this.rtenv['copyToFS'](path, buffer);
|
|
};
|
|
|
|
Engine.prototype.requestQuit = function () {
|
|
if (this.rtenv) {
|
|
this.rtenv['request_quit']();
|
|
}
|
|
};
|
|
|
|
// Closure compiler exported engine methods.
|
|
/** @export */
|
|
Engine['isWebGLAvailable'] = Utils.isWebGLAvailable;
|
|
Engine['load'] = load;
|
|
Engine['unload'] = unload;
|
|
Engine.prototype['init'] = Engine.prototype.init;
|
|
Engine.prototype['preloadFile'] = Engine.prototype.preloadFile;
|
|
Engine.prototype['start'] = Engine.prototype.start;
|
|
Engine.prototype['startGame'] = Engine.prototype.startGame;
|
|
Engine.prototype['copyToFS'] = Engine.prototype.copyToFS;
|
|
Engine.prototype['requestQuit'] = Engine.prototype.requestQuit;
|
|
return Engine;
|
|
}());
|
|
if (typeof window !== 'undefined') {
|
|
window['Engine'] = Engine;
|
|
}
|