mirror of
				https://github.com/godotengine/godot.git
				synced 2025-11-03 23:21:15 +00:00 
			
		
		
		
	
		
			
	
	
		
			367 lines
		
	
	
	
		
			9.2 KiB
		
	
	
	
		
			JavaScript
		
	
	
	
	
	
		
		
			
		
	
	
			367 lines
		
	
	
	
		
			9.2 KiB
		
	
	
	
		
			JavaScript
		
	
	
	
	
	
| 
								 | 
							
										return Module;
							 | 
						||
| 
								 | 
							
									},
							 | 
						||
| 
								 | 
							
								};
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								(function() {
							 | 
						||
| 
								 | 
							
									var engine = Engine;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									var USING_WASM = engine.USING_WASM;
							 | 
						||
| 
								 | 
							
									var DOWNLOAD_ATTEMPTS_MAX = 4;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									var basePath = null;
							 | 
						||
| 
								 | 
							
									var engineLoadPromise = null;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									var loadingFiles = {};
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									function getBasePath(path) {
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
										if (path.endsWith('/'))
							 | 
						||
| 
								 | 
							
											path = path.slice(0, -1);
							 | 
						||
| 
								 | 
							
										if (path.lastIndexOf('.') > path.lastIndexOf('/'))
							 | 
						||
| 
								 | 
							
											path = path.slice(0, path.lastIndexOf('.'));
							 | 
						||
| 
								 | 
							
										return path;
							 | 
						||
| 
								 | 
							
									}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									function getBaseName(path) {
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
										path = getBasePath(path);
							 | 
						||
| 
								 | 
							
										return path.slice(path.lastIndexOf('/') + 1);
							 | 
						||
| 
								 | 
							
									}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									Engine = function Engine() {
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
										this.rtenv = null;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
										var gameInitPromise = null;
							 | 
						||
| 
								 | 
							
										var unloadAfterInit = true;
							 | 
						||
| 
								 | 
							
										var memorySize = 268435456;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
										var progressFunc = null;
							 | 
						||
| 
								 | 
							
										var pckProgressTracker = {};
							 | 
						||
| 
								 | 
							
										var lastProgress = { loaded: 0, total: 0 };
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
										var canvas = null;
							 | 
						||
| 
								 | 
							
										var stdout = null;
							 | 
						||
| 
								 | 
							
										var stderr = null;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
										this.initGame = function(mainPack) {
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
											if (!gameInitPromise) {
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
												if (mainPack === undefined) {
							 | 
						||
| 
								 | 
							
													if (basePath !== null) {
							 | 
						||
| 
								 | 
							
														mainPack = basePath + '.pck';
							 | 
						||
| 
								 | 
							
													} else {
							 | 
						||
| 
								 | 
							
														return Promise.reject(new Error("No main pack to load specified"));
							 | 
						||
| 
								 | 
							
													}
							 | 
						||
| 
								 | 
							
												}
							 | 
						||
| 
								 | 
							
												if (basePath === null)
							 | 
						||
| 
								 | 
							
													basePath = getBasePath(mainPack);
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
												gameInitPromise = Engine.initEngine().then(
							 | 
						||
| 
								 | 
							
													instantiate.bind(this)
							 | 
						||
| 
								 | 
							
												);
							 | 
						||
| 
								 | 
							
												var gameLoadPromise = loadPromise(mainPack, pckProgressTracker).then(function(xhr) { return xhr.response; });
							 | 
						||
| 
								 | 
							
												gameInitPromise = Promise.all([gameLoadPromise, gameInitPromise]).then(function(values) {
							 | 
						||
| 
								 | 
							
													// resolve with pck
							 | 
						||
| 
								 | 
							
													return new Uint8Array(values[0]);
							 | 
						||
| 
								 | 
							
												});
							 | 
						||
| 
								 | 
							
												if (unloadAfterInit)
							 | 
						||
| 
								 | 
							
													gameInitPromise.then(Engine.unloadEngine);
							 | 
						||
| 
								 | 
							
												requestAnimationFrame(animateProgress);
							 | 
						||
| 
								 | 
							
											}
							 | 
						||
| 
								 | 
							
											return gameInitPromise;
							 | 
						||
| 
								 | 
							
										};
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
										function instantiate(initializer) {
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
											var rtenvOpts = {
							 | 
						||
| 
								 | 
							
												noInitialRun: true,
							 | 
						||
| 
								 | 
							
												thisProgram: getBaseName(basePath),
							 | 
						||
| 
								 | 
							
												engine: this,
							 | 
						||
| 
								 | 
							
											};
							 | 
						||
| 
								 | 
							
											if (typeof stdout === 'function')
							 | 
						||
| 
								 | 
							
												rtenvOpts.print = stdout;
							 | 
						||
| 
								 | 
							
											if (typeof stderr === 'function')
							 | 
						||
| 
								 | 
							
												rtenvOpts.printErr = stderr;
							 | 
						||
| 
								 | 
							
											if (typeof WebAssembly === 'object' && initializer instanceof WebAssembly.Module) {
							 | 
						||
| 
								 | 
							
												rtenvOpts.instantiateWasm = function(imports, onSuccess) {
							 | 
						||
| 
								 | 
							
													WebAssembly.instantiate(initializer, imports).then(function(result) {
							 | 
						||
| 
								 | 
							
														onSuccess(result);
							 | 
						||
| 
								 | 
							
													});
							 | 
						||
| 
								 | 
							
													return {};
							 | 
						||
| 
								 | 
							
												};
							 | 
						||
| 
								 | 
							
											} else if (initializer.asm && initializer.mem) {
							 | 
						||
| 
								 | 
							
												rtenvOpts.asm = initializer.asm;
							 | 
						||
| 
								 | 
							
												rtenvOpts.memoryInitializerRequest = initializer.mem;
							 | 
						||
| 
								 | 
							
												rtenvOpts.TOTAL_MEMORY = memorySize;
							 | 
						||
| 
								 | 
							
											} else {
							 | 
						||
| 
								 | 
							
												throw new Error("Invalid initializer");
							 | 
						||
| 
								 | 
							
											}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
											return new Promise(function(resolve, reject) {
							 | 
						||
| 
								 | 
							
												rtenvOpts.onRuntimeInitialized = resolve;
							 | 
						||
| 
								 | 
							
												rtenvOpts.onAbort = reject;
							 | 
						||
| 
								 | 
							
												rtenvOpts.engine.rtenv = Engine.RuntimeEnvironment(rtenvOpts);
							 | 
						||
| 
								 | 
							
											});
							 | 
						||
| 
								 | 
							
										}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
										this.start = function(mainPack) {
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
											return this.initGame(mainPack).then(synchronousStart.bind(this));
							 | 
						||
| 
								 | 
							
										};
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
										function synchronousStart(pckView) {
							 | 
						||
| 
								 | 
							
											// TODO don't expect canvas when runninng as cli tool
							 | 
						||
| 
								 | 
							
											if (canvas instanceof HTMLCanvasElement) {
							 | 
						||
| 
								 | 
							
												this.rtenv.canvas = canvas;
							 | 
						||
| 
								 | 
							
											} else {
							 | 
						||
| 
								 | 
							
												var firstCanvas = document.getElementsByTagName('canvas')[0];
							 | 
						||
| 
								 | 
							
												if (firstCanvas instanceof HTMLCanvasElement) {
							 | 
						||
| 
								 | 
							
													this.rtenv.canvas = firstCanvas;
							 | 
						||
| 
								 | 
							
												} else {
							 | 
						||
| 
								 | 
							
													throw new Error("No canvas found");
							 | 
						||
| 
								 | 
							
												}
							 | 
						||
| 
								 | 
							
											}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
											var actualCanvas = this.rtenv.canvas;
							 | 
						||
| 
								 | 
							
											var context = false;
							 | 
						||
| 
								 | 
							
											try {
							 | 
						||
| 
								 | 
							
												context = actualCanvas.getContext('webgl2') || actualCanvas.getContext('experimental-webgl2');
							 | 
						||
| 
								 | 
							
											} catch (e) {}
							 | 
						||
| 
								 | 
							
											if (!context) {
							 | 
						||
| 
								 | 
							
												throw new Error("WebGL 2 not available");
							 | 
						||
| 
								 | 
							
											}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
											// canvas can grab focus on click
							 | 
						||
| 
								 | 
							
											if (actualCanvas.tabIndex < 0) {
							 | 
						||
| 
								 | 
							
												actualCanvas.tabIndex = 0;
							 | 
						||
| 
								 | 
							
											}
							 | 
						||
| 
								 | 
							
											// necessary to calculate cursor coordinates correctly
							 | 
						||
| 
								 | 
							
											actualCanvas.style.padding = 0;
							 | 
						||
| 
								 | 
							
											actualCanvas.style.borderWidth = 0;
							 | 
						||
| 
								 | 
							
											actualCanvas.style.borderStyle = 'none';
							 | 
						||
| 
								 | 
							
											// until context restoration is implemented
							 | 
						||
| 
								 | 
							
											actualCanvas.addEventListener('webglcontextlost', function(ev) {
							 | 
						||
| 
								 | 
							
												alert("WebGL context lost, please reload the page");
							 | 
						||
| 
								 | 
							
												ev.preventDefault();
							 | 
						||
| 
								 | 
							
											}, false);
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
											this.rtenv.FS.createDataFile('/', this.rtenv.thisProgram + '.pck', pckView, true, true, true);
							 | 
						||
| 
								 | 
							
											gameInitPromise = null;
							 | 
						||
| 
								 | 
							
											this.rtenv.callMain();
							 | 
						||
| 
								 | 
							
										}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
										this.setProgressFunc = function(func) {
							 | 
						||
| 
								 | 
							
											progressFunc = func;
							 | 
						||
| 
								 | 
							
										};
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
										function animateProgress() {
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
											var loaded = 0;
							 | 
						||
| 
								 | 
							
											var total = 0;
							 | 
						||
| 
								 | 
							
											var totalIsValid = true;
							 | 
						||
| 
								 | 
							
											var progressIsFinal = true;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
											[loadingFiles, pckProgressTracker].forEach(function(tracker) {
							 | 
						||
| 
								 | 
							
												Object.keys(tracker).forEach(function(file) {
							 | 
						||
| 
								 | 
							
													if (!tracker[file].final)
							 | 
						||
| 
								 | 
							
														progressIsFinal = false;
							 | 
						||
| 
								 | 
							
													if (!totalIsValid || tracker[file].total === 0) {
							 | 
						||
| 
								 | 
							
														totalIsValid = false;
							 | 
						||
| 
								 | 
							
														total = 0;
							 | 
						||
| 
								 | 
							
													} else {
							 | 
						||
| 
								 | 
							
														total += tracker[file].total;
							 | 
						||
| 
								 | 
							
													}
							 | 
						||
| 
								 | 
							
													loaded += tracker[file].loaded;
							 | 
						||
| 
								 | 
							
												});
							 | 
						||
| 
								 | 
							
											});
							 | 
						||
| 
								 | 
							
											if (loaded !== lastProgress.loaded || total !== lastProgress.total) {
							 | 
						||
| 
								 | 
							
												lastProgress.loaded = loaded;
							 | 
						||
| 
								 | 
							
												lastProgress.total = total;
							 | 
						||
| 
								 | 
							
												if (typeof progressFunc === 'function')
							 | 
						||
| 
								 | 
							
													progressFunc(loaded, total);
							 | 
						||
| 
								 | 
							
											}
							 | 
						||
| 
								 | 
							
											if (!progressIsFinal)
							 | 
						||
| 
								 | 
							
												requestAnimationFrame(animateProgress);
							 | 
						||
| 
								 | 
							
										}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
										this.setCanvas = function(elem) {
							 | 
						||
| 
								 | 
							
											canvas = elem;
							 | 
						||
| 
								 | 
							
										};
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
										this.setAsmjsMemorySize = function(size) {
							 | 
						||
| 
								 | 
							
											memorySize = size;
							 | 
						||
| 
								 | 
							
										};
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
										this.setUnloadAfterInit = function(enabled) {
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
											if (enabled && !unloadAfterInit && gameInitPromise) {
							 | 
						||
| 
								 | 
							
												gameInitPromise.then(Engine.unloadEngine);
							 | 
						||
| 
								 | 
							
											}
							 | 
						||
| 
								 | 
							
											unloadAfterInit = enabled;
							 | 
						||
| 
								 | 
							
										};
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
										this.setStdoutFunc = function(func) {
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
											var print = function(text) {
							 | 
						||
| 
								 | 
							
												if (arguments.length > 1) {
							 | 
						||
| 
								 | 
							
													text = Array.prototype.slice.call(arguments).join(" ");
							 | 
						||
| 
								 | 
							
												}
							 | 
						||
| 
								 | 
							
												func(text);
							 | 
						||
| 
								 | 
							
											};
							 | 
						||
| 
								 | 
							
											if (this.rtenv)
							 | 
						||
| 
								 | 
							
												this.rtenv.print = print;
							 | 
						||
| 
								 | 
							
											stdout = print;
							 | 
						||
| 
								 | 
							
										};
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
										this.setStderrFunc = function(func) {
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
											var printErr = function(text) {
							 | 
						||
| 
								 | 
							
												if (arguments.length > 1)
							 | 
						||
| 
								 | 
							
													text = Array.prototype.slice.call(arguments).join(" ");
							 | 
						||
| 
								 | 
							
												func(text);
							 | 
						||
| 
								 | 
							
											};
							 | 
						||
| 
								 | 
							
											if (this.rtenv)
							 | 
						||
| 
								 | 
							
												this.rtenv.printErr = printErr;
							 | 
						||
| 
								 | 
							
											stderr = printErr;
							 | 
						||
| 
								 | 
							
										};
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									}; // Engine()
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									Engine.RuntimeEnvironment = engine.RuntimeEnvironment;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									Engine.initEngine = function(newBasePath) {
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
										if (newBasePath !== undefined) basePath = getBasePath(newBasePath);
							 | 
						||
| 
								 | 
							
										if (engineLoadPromise === null) {
							 | 
						||
| 
								 | 
							
											if (USING_WASM) {
							 | 
						||
| 
								 | 
							
												if (typeof WebAssembly !== 'object')
							 | 
						||
| 
								 | 
							
													return Promise.reject(new Error("Browser doesn't support WebAssembly"));
							 | 
						||
| 
								 | 
							
												// TODO cache/retrieve module to/from idb
							 | 
						||
| 
								 | 
							
												engineLoadPromise = loadPromise(basePath + '.wasm').then(function(xhr) {
							 | 
						||
| 
								 | 
							
													return WebAssembly.compile(xhr.response);
							 | 
						||
| 
								 | 
							
												});
							 | 
						||
| 
								 | 
							
											} else {
							 | 
						||
| 
								 | 
							
												var asmjsPromise = loadPromise(basePath + '.asm.js').then(function(xhr) {
							 | 
						||
| 
								 | 
							
													return asmjsModulePromise(xhr.response);
							 | 
						||
| 
								 | 
							
												});
							 | 
						||
| 
								 | 
							
												var memPromise = loadPromise(basePath + '.mem');
							 | 
						||
| 
								 | 
							
												engineLoadPromise = Promise.all([asmjsPromise, memPromise]).then(function(values) {
							 | 
						||
| 
								 | 
							
													return { asm: values[0], mem: values[1] };
							 | 
						||
| 
								 | 
							
												});
							 | 
						||
| 
								 | 
							
											}
							 | 
						||
| 
								 | 
							
											engineLoadPromise = engineLoadPromise.catch(function(err) {
							 | 
						||
| 
								 | 
							
												engineLoadPromise = null;
							 | 
						||
| 
								 | 
							
												throw err;
							 | 
						||
| 
								 | 
							
											});
							 | 
						||
| 
								 | 
							
										}
							 | 
						||
| 
								 | 
							
										return engineLoadPromise;
							 | 
						||
| 
								 | 
							
									};
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									function asmjsModulePromise(module) {
							 | 
						||
| 
								 | 
							
										var elem = document.createElement('script');
							 | 
						||
| 
								 | 
							
										var script = new Blob([
							 | 
						||
| 
								 | 
							
											'Engine.asm = (function() { var Module = {};',
							 | 
						||
| 
								 | 
							
											module,
							 | 
						||
| 
								 | 
							
											'return Module.asm; })();'
							 | 
						||
| 
								 | 
							
										]);
							 | 
						||
| 
								 | 
							
										var url = URL.createObjectURL(script);
							 | 
						||
| 
								 | 
							
										elem.src = url;
							 | 
						||
| 
								 | 
							
										return new Promise(function(resolve, reject) {
							 | 
						||
| 
								 | 
							
											elem.addEventListener('load', function() {
							 | 
						||
| 
								 | 
							
												URL.revokeObjectURL(url);
							 | 
						||
| 
								 | 
							
												var asm = Engine.asm;
							 | 
						||
| 
								 | 
							
												Engine.asm = undefined;
							 | 
						||
| 
								 | 
							
												setTimeout(function() {
							 | 
						||
| 
								 | 
							
													// delay to reclaim compilation memory
							 | 
						||
| 
								 | 
							
													resolve(asm);
							 | 
						||
| 
								 | 
							
												}, 1);
							 | 
						||
| 
								 | 
							
											});
							 | 
						||
| 
								 | 
							
											elem.addEventListener('error', function() {
							 | 
						||
| 
								 | 
							
												URL.revokeObjectURL(url);
							 | 
						||
| 
								 | 
							
												reject("asm.js faiilure");
							 | 
						||
| 
								 | 
							
											});
							 | 
						||
| 
								 | 
							
											document.body.appendChild(elem);
							 | 
						||
| 
								 | 
							
										});
							 | 
						||
| 
								 | 
							
									}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									Engine.unloadEngine = function() {
							 | 
						||
| 
								 | 
							
										engineLoadPromise = null;
							 | 
						||
| 
								 | 
							
									};
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									function loadPromise(file, tracker) {
							 | 
						||
| 
								 | 
							
										if (tracker === undefined)
							 | 
						||
| 
								 | 
							
											tracker = loadingFiles;
							 | 
						||
| 
								 | 
							
										return new Promise(function(resolve, reject) {
							 | 
						||
| 
								 | 
							
											loadXHR(resolve, reject, file, tracker);
							 | 
						||
| 
								 | 
							
										});
							 | 
						||
| 
								 | 
							
									}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									function loadXHR(resolve, reject, file, tracker) {
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
										var xhr = new XMLHttpRequest;
							 | 
						||
| 
								 | 
							
										xhr.open('GET', file);
							 | 
						||
| 
								 | 
							
										if (!file.endsWith('.js')) {
							 | 
						||
| 
								 | 
							
											xhr.responseType = 'arraybuffer';
							 | 
						||
| 
								 | 
							
										}
							 | 
						||
| 
								 | 
							
										['loadstart', 'progress', 'load', 'error', 'timeout', 'abort'].forEach(function(ev) {
							 | 
						||
| 
								 | 
							
											xhr.addEventListener(ev, onXHREvent.bind(xhr, resolve, reject, file, tracker));
							 | 
						||
| 
								 | 
							
										});
							 | 
						||
| 
								 | 
							
										xhr.send();
							 | 
						||
| 
								 | 
							
									}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									function onXHREvent(resolve, reject, file, tracker, ev) {
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
										if (this.status >= 400) {
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
											if (this.status < 500 || ++tracker[file].attempts >= DOWNLOAD_ATTEMPTS_MAX) {
							 | 
						||
| 
								 | 
							
												reject(new Error("Failed loading file '" + file + "': " + this.statusText));
							 | 
						||
| 
								 | 
							
												this.abort();
							 | 
						||
| 
								 | 
							
												return;
							 | 
						||
| 
								 | 
							
											} else {
							 | 
						||
| 
								 | 
							
												loadXHR(resolve, reject, file);
							 | 
						||
| 
								 | 
							
											}
							 | 
						||
| 
								 | 
							
										}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
										switch (ev.type) {
							 | 
						||
| 
								 | 
							
											case 'loadstart':
							 | 
						||
| 
								 | 
							
												if (tracker[file] === undefined) {
							 | 
						||
| 
								 | 
							
													tracker[file] = {
							 | 
						||
| 
								 | 
							
														total: ev.total,
							 | 
						||
| 
								 | 
							
														loaded: ev.loaded,
							 | 
						||
| 
								 | 
							
														attempts: 0,
							 | 
						||
| 
								 | 
							
														final: false,
							 | 
						||
| 
								 | 
							
													};
							 | 
						||
| 
								 | 
							
												}
							 | 
						||
| 
								 | 
							
												break;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
											case 'progress':
							 | 
						||
| 
								 | 
							
												tracker[file].loaded = ev.loaded;
							 | 
						||
| 
								 | 
							
												tracker[file].total = ev.total;
							 | 
						||
| 
								 | 
							
												break;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
											case 'load':
							 | 
						||
| 
								 | 
							
												tracker[file].final = true;
							 | 
						||
| 
								 | 
							
												resolve(this);
							 | 
						||
| 
								 | 
							
												break;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
											case 'error':
							 | 
						||
| 
								 | 
							
											case 'timeout':
							 | 
						||
| 
								 | 
							
												if (++tracker[file].attempts >= DOWNLOAD_ATTEMPTS_MAX) {
							 | 
						||
| 
								 | 
							
													tracker[file].final = true;
							 | 
						||
| 
								 | 
							
													reject(new Error("Failed loading file '" + file + "'"));
							 | 
						||
| 
								 | 
							
												} else {
							 | 
						||
| 
								 | 
							
													loadXHR(resolve, reject, file);
							 | 
						||
| 
								 | 
							
												}
							 | 
						||
| 
								 | 
							
												break;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
											case 'abort':
							 | 
						||
| 
								 | 
							
												tracker[file].final = true;
							 | 
						||
| 
								 | 
							
												reject(new Error("Loading file '" + file + "' was aborted."));
							 | 
						||
| 
								 | 
							
												break;
							 | 
						||
| 
								 | 
							
										}
							 | 
						||
| 
								 | 
							
									}
							 | 
						||
| 
								 | 
							
								})();
							 |