Kaynağa Gözat

Merge pull request #17792 from eska014/enginejs-preloadpaths

Handle directories in engine.js preloadFile()
Rémi Verschelde 7 yıl önce
ebeveyn
işleme
919209907d

+ 0 - 7
platform/javascript/detect.py

@@ -139,13 +139,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.

+ 32 - 8
platform/javascript/engine.js

@@ -1,3 +1,5 @@
+		exposedLibs['PATH'] = PATH;
+		exposedLibs['FS'] = FS;
 		return Module;
 	},
 };
@@ -12,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('/'))
@@ -23,14 +32,15 @@
 
 	function getBaseName(path) {
 
-		path = getBasePath(path);
-		return path.slice(path.lastIndexOf('/') + 1);
+		return getPathLeaf(getBasePath(path));
 	}
 
 	Engine = function Engine() {
 
 		this.rtenv = null;
 
+		var LIBS = {};
+
 		var initPromise = null;
 		var unloadAfterInit = true;
 
@@ -80,11 +90,11 @@
 			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);
 			});
 		}
 
-		this.preloadFile = function(pathOrBuffer, bufferFilename) {
+		this.preloadFile = function(pathOrBuffer, destPath) {
 
 			if (pathOrBuffer instanceof ArrayBuffer) {
 				pathOrBuffer = new Uint8Array(pathOrBuffer);
@@ -93,14 +103,14 @@
 			}
 			if (pathOrBuffer instanceof Uint8Array) {
 				preloadedFiles.push({
-					name: bufferFilename,
+					path: destPath,
 					buffer: pathOrBuffer
 				});
 				return Promise.resolve();
 			} else if (typeof pathOrBuffer === 'string') {
 				return loadPromise(pathOrBuffer, preloadProgressTracker).then(function(xhr) {
 					preloadedFiles.push({
-						name: pathOrBuffer,
+						path: destPath || pathOrBuffer,
 						buffer: xhr.response
 					});
 				});
@@ -119,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, [])
 			);
 		};
@@ -163,7 +178,16 @@
 			this.rtenv.thisProgram = executableName || getBaseName(basePath);
 
 			preloadedFiles.forEach(function(file) {
-				this.rtenv.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;

+ 1 - 1
platform/javascript/pre.js

@@ -1,2 +1,2 @@
 var Engine = {
-	RuntimeEnvironment: function(Module) {
+	RuntimeEnvironment: function(Module, exposedLibs) {