From 63c7fc6358343c3de6cfaa40436063646eb8b7a1 Mon Sep 17 00:00:00 2001 From: Leon Krause Date: Tue, 27 Mar 2018 09:06:19 +0200 Subject: [PATCH 1/4] Expose Emscripten libs to engine.js discreetly --- platform/javascript/detect.py | 7 ------- platform/javascript/engine.js | 7 +++++-- platform/javascript/pre.js | 2 +- 3 files changed, 6 insertions(+), 10 deletions(-) diff --git a/platform/javascript/detect.py b/platform/javascript/detect.py index 851f4ecb493..daa97bf2e2d 100644 --- a/platform/javascript/detect.py +++ b/platform/javascript/detect.py @@ -129,13 +129,6 @@ def configure(env): # This setting just makes WebGL 2 APIs available, it does NOT disable WebGL 1. env.Append(LINKFLAGS=['-s', 'USE_WEBGL2=1']) - # engine.js uses FS but is not currently evaluated by Emscripten, so export FS. - # TODO: Getting rid of this export is desirable. - extra_exports = [ - 'FS', - ] - env.Append(LINKFLAGS=['-s', 'EXTRA_EXPORTED_RUNTIME_METHODS="%s"' % repr(extra_exports)]) - env.Append(LINKFLAGS=['-s', 'INVOKE_RUN=0']) # TODO: Reevaluate usage of this setting now that engine.js manages engine runtime. diff --git a/platform/javascript/engine.js b/platform/javascript/engine.js index e6fb48d0d25..c54ccef1eb4 100644 --- a/platform/javascript/engine.js +++ b/platform/javascript/engine.js @@ -1,3 +1,4 @@ + exposedLibs['FS'] = FS; return Module; }, }; @@ -31,6 +32,8 @@ this.rtenv = null; + var LIBS = {}; + var initPromise = null; var unloadAfterInit = true; @@ -80,7 +83,7 @@ return new Promise(function(resolve, reject) { rtenvProps.onRuntimeInitialized = resolve; rtenvProps.onAbort = reject; - rtenvProps.engine.rtenv = Engine.RuntimeEnvironment(rtenvProps); + rtenvProps.engine.rtenv = Engine.RuntimeEnvironment(rtenvProps, LIBS); }); } @@ -163,7 +166,7 @@ this.rtenv.thisProgram = executableName || getBaseName(basePath); preloadedFiles.forEach(function(file) { - this.rtenv.FS.createDataFile('/', file.name, new Uint8Array(file.buffer), true, true, true); + LIBS.FS.createDataFile('/', file.name, new Uint8Array(file.buffer), true, true, true); }, this); preloadedFiles = null; diff --git a/platform/javascript/pre.js b/platform/javascript/pre.js index 311aa44fda9..02194bc75ea 100644 --- a/platform/javascript/pre.js +++ b/platform/javascript/pre.js @@ -1,2 +1,2 @@ var Engine = { - RuntimeEnvironment: function(Module) { + RuntimeEnvironment: function(Module, exposedLibs) { From 6f1bddf4b5e6716f59bcbd9a7587b6d556251ef9 Mon Sep 17 00:00:00 2001 From: Leon Krause Date: Tue, 27 Mar 2018 09:14:03 +0200 Subject: [PATCH 2/4] Fix engine.js preloadFile() with directories --- platform/javascript/engine.js | 16 +++++++++++++--- 1 file changed, 13 insertions(+), 3 deletions(-) diff --git a/platform/javascript/engine.js b/platform/javascript/engine.js index c54ccef1eb4..d0d01b03aad 100644 --- a/platform/javascript/engine.js +++ b/platform/javascript/engine.js @@ -1,3 +1,4 @@ + exposedLibs['PATH'] = PATH; exposedLibs['FS'] = FS; return Module; }, @@ -96,14 +97,14 @@ } if (pathOrBuffer instanceof Uint8Array) { preloadedFiles.push({ - name: bufferFilename, + path: bufferFilename, buffer: pathOrBuffer }); return Promise.resolve(); } else if (typeof pathOrBuffer === 'string') { return loadPromise(pathOrBuffer, preloadProgressTracker).then(function(xhr) { preloadedFiles.push({ - name: pathOrBuffer, + path: pathOrBuffer, buffer: xhr.response }); }); @@ -166,7 +167,16 @@ this.rtenv.thisProgram = executableName || getBaseName(basePath); preloadedFiles.forEach(function(file) { - LIBS.FS.createDataFile('/', file.name, new Uint8Array(file.buffer), true, true, true); + var dir = LIBS.PATH.dirname(file.path); + try { + LIBS.FS.stat(dir); + } catch (e) { + if (e.code !== 'ENOENT') { + throw e; + } + LIBS.FS.mkdirTree(dir); + } + LIBS.FS.createDataFile('/', file.path, new Uint8Array(file.buffer), true, true, true); }, this); preloadedFiles = null; From d373029382208226a55ddfc028a3261e0dc8279b Mon Sep 17 00:00:00 2001 From: Leon Krause Date: Tue, 27 Mar 2018 11:23:38 +0200 Subject: [PATCH 3/4] Allow custom path when using engine.js preloadFile() with URL --- platform/javascript/engine.js | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/platform/javascript/engine.js b/platform/javascript/engine.js index d0d01b03aad..be8d04dd5eb 100644 --- a/platform/javascript/engine.js +++ b/platform/javascript/engine.js @@ -88,7 +88,7 @@ }); } - this.preloadFile = function(pathOrBuffer, bufferFilename) { + this.preloadFile = function(pathOrBuffer, destPath) { if (pathOrBuffer instanceof ArrayBuffer) { pathOrBuffer = new Uint8Array(pathOrBuffer); @@ -97,14 +97,14 @@ } if (pathOrBuffer instanceof Uint8Array) { preloadedFiles.push({ - path: bufferFilename, + path: destPath, buffer: pathOrBuffer }); return Promise.resolve(); } else if (typeof pathOrBuffer === 'string') { return loadPromise(pathOrBuffer, preloadProgressTracker).then(function(xhr) { preloadedFiles.push({ - path: pathOrBuffer, + path: destPath || pathOrBuffer, buffer: xhr.response }); }); From 3014e48ec5a985b9d143ba27b91e32b933dcfdad Mon Sep 17 00:00:00 2001 From: Leon Krause Date: Tue, 27 Mar 2018 11:25:03 +0200 Subject: [PATCH 4/4] Fix engine.js startGame() when loading from directory --- platform/javascript/engine.js | 17 ++++++++++++++--- 1 file changed, 14 insertions(+), 3 deletions(-) diff --git a/platform/javascript/engine.js b/platform/javascript/engine.js index be8d04dd5eb..e4839af4335 100644 --- a/platform/javascript/engine.js +++ b/platform/javascript/engine.js @@ -14,6 +14,13 @@ var loadingFiles = {}; + function getPathLeaf(path) { + + while (path.endsWith('/')) + path = path.slice(0, -1); + return path.slice(path.lastIndexOf('/') + 1); + } + function getBasePath(path) { if (path.endsWith('/')) @@ -25,8 +32,7 @@ function getBaseName(path) { - path = getBasePath(path); - return path.slice(path.lastIndexOf('/') + 1); + return getPathLeaf(getBasePath(path)); } Engine = function Engine() { @@ -123,7 +129,12 @@ this.startGame = function(mainPack) { executableName = getBaseName(mainPack); - return Promise.all([this.init(getBasePath(mainPack)), this.preloadFile(mainPack)]).then( + return Promise.all([ + // Load from directory, + this.init(getBasePath(mainPack)), + // ...but write to root where the engine expects it. + this.preloadFile(mainPack, getPathLeaf(mainPack)) + ]).then( Function.prototype.apply.bind(synchronousStart, this, []) ); };