mirror of
				https://github.com/godotengine/godot.git
				synced 2025-10-31 13:41:03 +00:00 
			
		
		
		
	[Web] Rename JavaScript platform to Web.
Also rename export name from "HTML5" to "Web".
This commit is contained in:
		
							parent
							
								
									223e083d36
								
							
						
					
					
						commit
						d20b32186f
					
				
					 120 changed files with 547 additions and 548 deletions
				
			
		|  | @ -1,427 +0,0 @@ | |||
| /*************************************************************************/ | ||||
| /*  library_godot_os.js                                                  */ | ||||
| /*************************************************************************/ | ||||
| /*                       This file is part of:                           */ | ||||
| /*                           GODOT ENGINE                                */ | ||||
| /*                      https://godotengine.org                          */ | ||||
| /*************************************************************************/ | ||||
| /* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur.                 */ | ||||
| /* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md).   */ | ||||
| /*                                                                       */ | ||||
| /* Permission is hereby granted, free of charge, to any person obtaining */ | ||||
| /* a copy of this software and associated documentation files (the       */ | ||||
| /* "Software"), to deal in the Software without restriction, including   */ | ||||
| /* without limitation the rights to use, copy, modify, merge, publish,   */ | ||||
| /* distribute, sublicense, and/or sell copies of the Software, and to    */ | ||||
| /* permit persons to whom the Software is furnished to do so, subject to */ | ||||
| /* the following conditions:                                             */ | ||||
| /*                                                                       */ | ||||
| /* The above copyright notice and this permission notice shall be        */ | ||||
| /* included in all copies or substantial portions of the Software.       */ | ||||
| /*                                                                       */ | ||||
| /* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,       */ | ||||
| /* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF    */ | ||||
| /* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/ | ||||
| /* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY  */ | ||||
| /* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,  */ | ||||
| /* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE     */ | ||||
| /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.                */ | ||||
| /*************************************************************************/ | ||||
| 
 | ||||
| const IDHandler = { | ||||
| 	$IDHandler: { | ||||
| 		_last_id: 0, | ||||
| 		_references: {}, | ||||
| 
 | ||||
| 		get: function (p_id) { | ||||
| 			return IDHandler._references[p_id]; | ||||
| 		}, | ||||
| 
 | ||||
| 		add: function (p_data) { | ||||
| 			const id = ++IDHandler._last_id; | ||||
| 			IDHandler._references[id] = p_data; | ||||
| 			return id; | ||||
| 		}, | ||||
| 
 | ||||
| 		remove: function (p_id) { | ||||
| 			delete IDHandler._references[p_id]; | ||||
| 		}, | ||||
| 	}, | ||||
| }; | ||||
| 
 | ||||
| autoAddDeps(IDHandler, '$IDHandler'); | ||||
| mergeInto(LibraryManager.library, IDHandler); | ||||
| 
 | ||||
| const GodotConfig = { | ||||
| 	$GodotConfig__postset: 'Module["initConfig"] = GodotConfig.init_config;', | ||||
| 	$GodotConfig__deps: ['$GodotRuntime'], | ||||
| 	$GodotConfig: { | ||||
| 		canvas: null, | ||||
| 		locale: 'en', | ||||
| 		canvas_resize_policy: 2, // Adaptive
 | ||||
| 		virtual_keyboard: false, | ||||
| 		persistent_drops: false, | ||||
| 		on_execute: null, | ||||
| 		on_exit: null, | ||||
| 
 | ||||
| 		init_config: function (p_opts) { | ||||
| 			GodotConfig.canvas_resize_policy = p_opts['canvasResizePolicy']; | ||||
| 			GodotConfig.canvas = p_opts['canvas']; | ||||
| 			GodotConfig.locale = p_opts['locale'] || GodotConfig.locale; | ||||
| 			GodotConfig.virtual_keyboard = p_opts['virtualKeyboard']; | ||||
| 			GodotConfig.persistent_drops = !!p_opts['persistentDrops']; | ||||
| 			GodotConfig.on_execute = p_opts['onExecute']; | ||||
| 			GodotConfig.on_exit = p_opts['onExit']; | ||||
| 			if (p_opts['focusCanvas']) { | ||||
| 				GodotConfig.canvas.focus(); | ||||
| 			} | ||||
| 		}, | ||||
| 
 | ||||
| 		locate_file: function (file) { | ||||
| 			return Module['locateFile'](file); // eslint-disable-line no-undef
 | ||||
| 		}, | ||||
| 		clear: function () { | ||||
| 			GodotConfig.canvas = null; | ||||
| 			GodotConfig.locale = 'en'; | ||||
| 			GodotConfig.canvas_resize_policy = 2; | ||||
| 			GodotConfig.virtual_keyboard = false; | ||||
| 			GodotConfig.persistent_drops = false; | ||||
| 			GodotConfig.on_execute = null; | ||||
| 			GodotConfig.on_exit = null; | ||||
| 		}, | ||||
| 	}, | ||||
| 
 | ||||
| 	godot_js_config_canvas_id_get__sig: 'vii', | ||||
| 	godot_js_config_canvas_id_get: function (p_ptr, p_ptr_max) { | ||||
| 		GodotRuntime.stringToHeap(`#${GodotConfig.canvas.id}`, p_ptr, p_ptr_max); | ||||
| 	}, | ||||
| 
 | ||||
| 	godot_js_config_locale_get__sig: 'vii', | ||||
| 	godot_js_config_locale_get: function (p_ptr, p_ptr_max) { | ||||
| 		GodotRuntime.stringToHeap(GodotConfig.locale, p_ptr, p_ptr_max); | ||||
| 	}, | ||||
| }; | ||||
| 
 | ||||
| autoAddDeps(GodotConfig, '$GodotConfig'); | ||||
| mergeInto(LibraryManager.library, GodotConfig); | ||||
| 
 | ||||
| const GodotFS = { | ||||
| 	$GodotFS__deps: ['$ERRNO_CODES', '$FS', '$IDBFS', '$GodotRuntime'], | ||||
| 	$GodotFS__postset: [ | ||||
| 		'Module["initFS"] = GodotFS.init;', | ||||
| 		'Module["copyToFS"] = GodotFS.copy_to_fs;', | ||||
| 	].join(''), | ||||
| 	$GodotFS: { | ||||
| 		_idbfs: false, | ||||
| 		_syncing: false, | ||||
| 		_mount_points: [], | ||||
| 
 | ||||
| 		is_persistent: function () { | ||||
| 			return GodotFS._idbfs ? 1 : 0; | ||||
| 		}, | ||||
| 
 | ||||
| 		// Initialize godot file system, setting up persistent paths.
 | ||||
| 		// Returns a promise that resolves when the FS is ready.
 | ||||
| 		// We keep track of mount_points, so that we can properly close the IDBFS
 | ||||
| 		// since emscripten is not doing it by itself. (emscripten GH#12516).
 | ||||
| 		init: function (persistentPaths) { | ||||
| 			GodotFS._idbfs = false; | ||||
| 			if (!Array.isArray(persistentPaths)) { | ||||
| 				return Promise.reject(new Error('Persistent paths must be an array')); | ||||
| 			} | ||||
| 			if (!persistentPaths.length) { | ||||
| 				return Promise.resolve(); | ||||
| 			} | ||||
| 			GodotFS._mount_points = persistentPaths.slice(); | ||||
| 
 | ||||
| 			function createRecursive(dir) { | ||||
| 				try { | ||||
| 					FS.stat(dir); | ||||
| 				} catch (e) { | ||||
| 					if (e.errno !== ERRNO_CODES.ENOENT) { | ||||
| 						throw e; | ||||
| 					} | ||||
| 					FS.mkdirTree(dir); | ||||
| 				} | ||||
| 			} | ||||
| 
 | ||||
| 			GodotFS._mount_points.forEach(function (path) { | ||||
| 				createRecursive(path); | ||||
| 				FS.mount(IDBFS, {}, path); | ||||
| 			}); | ||||
| 			return new Promise(function (resolve, reject) { | ||||
| 				FS.syncfs(true, function (err) { | ||||
| 					if (err) { | ||||
| 						GodotFS._mount_points = []; | ||||
| 						GodotFS._idbfs = false; | ||||
| 						GodotRuntime.print(`IndexedDB not available: ${err.message}`); | ||||
| 					} else { | ||||
| 						GodotFS._idbfs = true; | ||||
| 					} | ||||
| 					resolve(err); | ||||
| 				}); | ||||
| 			}); | ||||
| 		}, | ||||
| 
 | ||||
| 		// Deinit godot file system, making sure to unmount file systems, and close IDBFS(s).
 | ||||
| 		deinit: function () { | ||||
| 			GodotFS._mount_points.forEach(function (path) { | ||||
| 				try { | ||||
| 					FS.unmount(path); | ||||
| 				} catch (e) { | ||||
| 					GodotRuntime.print('Already unmounted', e); | ||||
| 				} | ||||
| 				if (GodotFS._idbfs && IDBFS.dbs[path]) { | ||||
| 					IDBFS.dbs[path].close(); | ||||
| 					delete IDBFS.dbs[path]; | ||||
| 				} | ||||
| 			}); | ||||
| 			GodotFS._mount_points = []; | ||||
| 			GodotFS._idbfs = false; | ||||
| 			GodotFS._syncing = false; | ||||
| 		}, | ||||
| 
 | ||||
| 		sync: function () { | ||||
| 			if (GodotFS._syncing) { | ||||
| 				GodotRuntime.error('Already syncing!'); | ||||
| 				return Promise.resolve(); | ||||
| 			} | ||||
| 			GodotFS._syncing = true; | ||||
| 			return new Promise(function (resolve, reject) { | ||||
| 				FS.syncfs(false, function (error) { | ||||
| 					if (error) { | ||||
| 						GodotRuntime.error(`Failed to save IDB file system: ${error.message}`); | ||||
| 					} | ||||
| 					GodotFS._syncing = false; | ||||
| 					resolve(error); | ||||
| 				}); | ||||
| 			}); | ||||
| 		}, | ||||
| 
 | ||||
| 		// Copies a buffer to the internal file system. Creating directories recursively.
 | ||||
| 		copy_to_fs: function (path, buffer) { | ||||
| 			const idx = path.lastIndexOf('/'); | ||||
| 			let dir = '/'; | ||||
| 			if (idx > 0) { | ||||
| 				dir = path.slice(0, idx); | ||||
| 			} | ||||
| 			try { | ||||
| 				FS.stat(dir); | ||||
| 			} catch (e) { | ||||
| 				if (e.errno !== ERRNO_CODES.ENOENT) { | ||||
| 					throw e; | ||||
| 				} | ||||
| 				FS.mkdirTree(dir); | ||||
| 			} | ||||
| 			FS.writeFile(path, new Uint8Array(buffer)); | ||||
| 		}, | ||||
| 	}, | ||||
| }; | ||||
| mergeInto(LibraryManager.library, GodotFS); | ||||
| 
 | ||||
| const GodotOS = { | ||||
| 	$GodotOS__deps: ['$GodotRuntime', '$GodotConfig', '$GodotFS'], | ||||
| 	$GodotOS__postset: [ | ||||
| 		'Module["request_quit"] = function() { GodotOS.request_quit() };', | ||||
| 		'Module["onExit"] = GodotOS.cleanup;', | ||||
| 		'GodotOS._fs_sync_promise = Promise.resolve();', | ||||
| 	].join(''), | ||||
| 	$GodotOS: { | ||||
| 		request_quit: function () {}, | ||||
| 		_async_cbs: [], | ||||
| 		_fs_sync_promise: null, | ||||
| 
 | ||||
| 		atexit: function (p_promise_cb) { | ||||
| 			GodotOS._async_cbs.push(p_promise_cb); | ||||
| 		}, | ||||
| 
 | ||||
| 		cleanup: function (exit_code) { | ||||
| 			const cb = GodotConfig.on_exit; | ||||
| 			GodotFS.deinit(); | ||||
| 			GodotConfig.clear(); | ||||
| 			if (cb) { | ||||
| 				cb(exit_code); | ||||
| 			} | ||||
| 		}, | ||||
| 
 | ||||
| 		finish_async: function (callback) { | ||||
| 			GodotOS._fs_sync_promise.then(function (err) { | ||||
| 				const promises = []; | ||||
| 				GodotOS._async_cbs.forEach(function (cb) { | ||||
| 					promises.push(new Promise(cb)); | ||||
| 				}); | ||||
| 				return Promise.all(promises); | ||||
| 			}).then(function () { | ||||
| 				return GodotFS.sync(); // Final FS sync.
 | ||||
| 			}).then(function (err) { | ||||
| 				// Always deferred.
 | ||||
| 				setTimeout(function () { | ||||
| 					callback(); | ||||
| 				}, 0); | ||||
| 			}); | ||||
| 		}, | ||||
| 	}, | ||||
| 
 | ||||
| 	godot_js_os_finish_async__sig: 'vi', | ||||
| 	godot_js_os_finish_async: function (p_callback) { | ||||
| 		const func = GodotRuntime.get_func(p_callback); | ||||
| 		GodotOS.finish_async(func); | ||||
| 	}, | ||||
| 
 | ||||
| 	godot_js_os_request_quit_cb__sig: 'vi', | ||||
| 	godot_js_os_request_quit_cb: function (p_callback) { | ||||
| 		GodotOS.request_quit = GodotRuntime.get_func(p_callback); | ||||
| 	}, | ||||
| 
 | ||||
| 	godot_js_os_fs_is_persistent__sig: 'i', | ||||
| 	godot_js_os_fs_is_persistent: function () { | ||||
| 		return GodotFS.is_persistent(); | ||||
| 	}, | ||||
| 
 | ||||
| 	godot_js_os_fs_sync__sig: 'vi', | ||||
| 	godot_js_os_fs_sync: function (callback) { | ||||
| 		const func = GodotRuntime.get_func(callback); | ||||
| 		GodotOS._fs_sync_promise = GodotFS.sync(); | ||||
| 		GodotOS._fs_sync_promise.then(function (err) { | ||||
| 			func(); | ||||
| 		}); | ||||
| 	}, | ||||
| 
 | ||||
| 	godot_js_os_execute__sig: 'ii', | ||||
| 	godot_js_os_execute: function (p_json) { | ||||
| 		const json_args = GodotRuntime.parseString(p_json); | ||||
| 		const args = JSON.parse(json_args); | ||||
| 		if (GodotConfig.on_execute) { | ||||
| 			GodotConfig.on_execute(args); | ||||
| 			return 0; | ||||
| 		} | ||||
| 		return 1; | ||||
| 	}, | ||||
| 
 | ||||
| 	godot_js_os_shell_open__sig: 'vi', | ||||
| 	godot_js_os_shell_open: function (p_uri) { | ||||
| 		window.open(GodotRuntime.parseString(p_uri), '_blank'); | ||||
| 	}, | ||||
| 
 | ||||
| 	godot_js_os_hw_concurrency_get__sig: 'i', | ||||
| 	godot_js_os_hw_concurrency_get: function () { | ||||
| 		// TODO Godot core needs fixing to avoid spawning too many threads (> 24).
 | ||||
| 		const concurrency = navigator.hardwareConcurrency || 1; | ||||
| 		return concurrency < 2 ? concurrency : 2; | ||||
| 	}, | ||||
| 
 | ||||
| 	godot_js_os_download_buffer__sig: 'viiii', | ||||
| 	godot_js_os_download_buffer: function (p_ptr, p_size, p_name, p_mime) { | ||||
| 		const buf = GodotRuntime.heapSlice(HEAP8, p_ptr, p_size); | ||||
| 		const name = GodotRuntime.parseString(p_name); | ||||
| 		const mime = GodotRuntime.parseString(p_mime); | ||||
| 		const blob = new Blob([buf], { type: mime }); | ||||
| 		const url = window.URL.createObjectURL(blob); | ||||
| 		const a = document.createElement('a'); | ||||
| 		a.href = url; | ||||
| 		a.download = name; | ||||
| 		a.style.display = 'none'; | ||||
| 		document.body.appendChild(a); | ||||
| 		a.click(); | ||||
| 		a.remove(); | ||||
| 		window.URL.revokeObjectURL(url); | ||||
| 	}, | ||||
| }; | ||||
| 
 | ||||
| autoAddDeps(GodotOS, '$GodotOS'); | ||||
| mergeInto(LibraryManager.library, GodotOS); | ||||
| 
 | ||||
| /* | ||||
|  * Godot event listeners. | ||||
|  * Keeps track of registered event listeners so it can remove them on shutdown. | ||||
|  */ | ||||
| const GodotEventListeners = { | ||||
| 	$GodotEventListeners__deps: ['$GodotOS'], | ||||
| 	$GodotEventListeners__postset: 'GodotOS.atexit(function(resolve, reject) { GodotEventListeners.clear(); resolve(); });', | ||||
| 	$GodotEventListeners: { | ||||
| 		handlers: [], | ||||
| 
 | ||||
| 		has: function (target, event, method, capture) { | ||||
| 			return GodotEventListeners.handlers.findIndex(function (e) { | ||||
| 				return e.target === target && e.event === event && e.method === method && e.capture === capture; | ||||
| 			}) !== -1; | ||||
| 		}, | ||||
| 
 | ||||
| 		add: function (target, event, method, capture) { | ||||
| 			if (GodotEventListeners.has(target, event, method, capture)) { | ||||
| 				return; | ||||
| 			} | ||||
| 			function Handler(p_target, p_event, p_method, p_capture) { | ||||
| 				this.target = p_target; | ||||
| 				this.event = p_event; | ||||
| 				this.method = p_method; | ||||
| 				this.capture = p_capture; | ||||
| 			} | ||||
| 			GodotEventListeners.handlers.push(new Handler(target, event, method, capture)); | ||||
| 			target.addEventListener(event, method, capture); | ||||
| 		}, | ||||
| 
 | ||||
| 		clear: function () { | ||||
| 			GodotEventListeners.handlers.forEach(function (h) { | ||||
| 				h.target.removeEventListener(h.event, h.method, h.capture); | ||||
| 			}); | ||||
| 			GodotEventListeners.handlers.length = 0; | ||||
| 		}, | ||||
| 	}, | ||||
| }; | ||||
| mergeInto(LibraryManager.library, GodotEventListeners); | ||||
| 
 | ||||
| const GodotPWA = { | ||||
| 
 | ||||
| 	$GodotPWA__deps: ['$GodotRuntime', '$GodotEventListeners'], | ||||
| 	$GodotPWA: { | ||||
| 		hasUpdate: false, | ||||
| 
 | ||||
| 		updateState: function (cb, reg) { | ||||
| 			if (!reg) { | ||||
| 				return; | ||||
| 			} | ||||
| 			if (!reg.active) { | ||||
| 				return; | ||||
| 			} | ||||
| 			if (reg.waiting) { | ||||
| 				GodotPWA.hasUpdate = true; | ||||
| 				cb(); | ||||
| 			} | ||||
| 			GodotEventListeners.add(reg, 'updatefound', function () { | ||||
| 				const installing = reg.installing; | ||||
| 				GodotEventListeners.add(installing, 'statechange', function () { | ||||
| 					if (installing.state === 'installed') { | ||||
| 						GodotPWA.hasUpdate = true; | ||||
| 						cb(); | ||||
| 					} | ||||
| 				}); | ||||
| 			}); | ||||
| 		}, | ||||
| 	}, | ||||
| 
 | ||||
| 	godot_js_pwa_cb__sig: 'vi', | ||||
| 	godot_js_pwa_cb: function (p_update_cb) { | ||||
| 		if ('serviceWorker' in navigator) { | ||||
| 			const cb = GodotRuntime.get_func(p_update_cb); | ||||
| 			navigator.serviceWorker.getRegistration().then(GodotPWA.updateState.bind(null, cb)); | ||||
| 		} | ||||
| 	}, | ||||
| 
 | ||||
| 	godot_js_pwa_update__sig: 'i', | ||||
| 	godot_js_pwa_update: function () { | ||||
| 		if ('serviceWorker' in navigator && GodotPWA.hasUpdate) { | ||||
| 			navigator.serviceWorker.getRegistration().then(function (reg) { | ||||
| 				if (!reg || !reg.waiting) { | ||||
| 					return; | ||||
| 				} | ||||
| 				reg.waiting.postMessage('update'); | ||||
| 			}); | ||||
| 			return 0; | ||||
| 		} | ||||
| 		return 1; | ||||
| 	}, | ||||
| }; | ||||
| 
 | ||||
| autoAddDeps(GodotPWA, '$GodotPWA'); | ||||
| mergeInto(LibraryManager.library, GodotPWA); | ||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue
	
	 Fabio Alessandrelli
						Fabio Alessandrelli