mirror of
https://github.com/godotengine/godot.git
synced 2025-10-20 08:23:29 +00:00
[HTML5] Refactor JS, threads support, closures.
- Refactored the Engine code, splitted across files. - Use MODULARIZE option to build emscripten code into it's own closure. - Optional closure compiler run for JS and generated code. - Enable lto support (saves ~2MiB in release). - Can now build with tools=yes (not much to see yet). - Dropped some deprecated code for older toolchains. - Add onExit, and onExecute JS function. - Add files drag and drop support. - Add support for low precessor usage mode (via offscreen render, swap).
This commit is contained in:
parent
93e20a4cd4
commit
21c9f37757
18 changed files with 1097 additions and 627 deletions
|
@ -34,27 +34,98 @@
|
|||
|
||||
#include <emscripten/emscripten.h>
|
||||
|
||||
static OS_JavaScript *os = NULL;
|
||||
|
||||
// Files drop (implemented in JS for now).
|
||||
extern "C" EMSCRIPTEN_KEEPALIVE void _drop_files_callback(char *p_filev[], int p_filec) {
|
||||
if (!os || !os->get_main_loop()) {
|
||||
ERR_FAIL_MSG("Unable to drop files because the OS or MainLoop are not active");
|
||||
}
|
||||
Vector<String> files;
|
||||
for (int i = 0; i < p_filec; i++) {
|
||||
files.push_back(String::utf8(p_filev[i]));
|
||||
}
|
||||
os->get_main_loop()->drop_files(files);
|
||||
}
|
||||
|
||||
void exit_callback() {
|
||||
emscripten_cancel_main_loop(); // After this, we can exit!
|
||||
Main::cleanup();
|
||||
int exit_code = OS_JavaScript::get_singleton()->get_exit_code();
|
||||
memdelete(os);
|
||||
os = NULL;
|
||||
emscripten_force_exit(exit_code); // No matter that we call cancel_main_loop, regular "exit" will not work, forcing.
|
||||
}
|
||||
|
||||
void main_loop_callback() {
|
||||
|
||||
if (os->main_loop_iterate()) {
|
||||
emscripten_cancel_main_loop(); // Cancel current loop and wait for finalize_async.
|
||||
EM_ASM({
|
||||
// This will contain the list of operations that need to complete before cleanup.
|
||||
Module.async_finish = [];
|
||||
});
|
||||
os->get_main_loop()->finish();
|
||||
os->finalize_async(); // Will add all the async finish functions.
|
||||
EM_ASM({
|
||||
Promise.all(Module.async_finish).then(function() {
|
||||
Module.async_finish = [];
|
||||
ccall("cleanup_after_sync", null, []);
|
||||
});
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
extern "C" EMSCRIPTEN_KEEPALIVE void cleanup_after_sync() {
|
||||
emscripten_set_main_loop(exit_callback, -1, false);
|
||||
}
|
||||
|
||||
extern "C" EMSCRIPTEN_KEEPALIVE void main_after_fs_sync(char *p_idbfs_err) {
|
||||
|
||||
OS_JavaScript *os = OS_JavaScript::get_singleton();
|
||||
|
||||
// Set IDBFS status
|
||||
String idbfs_err = String::utf8(p_idbfs_err);
|
||||
if (!idbfs_err.empty()) {
|
||||
print_line("IndexedDB not available: " + idbfs_err);
|
||||
}
|
||||
OS_JavaScript *os = OS_JavaScript::get_singleton();
|
||||
os->set_idb_available(idbfs_err.empty());
|
||||
|
||||
// Set canvas ID
|
||||
char canvas_ptr[256];
|
||||
/* clang-format off */
|
||||
EM_ASM({
|
||||
stringToUTF8("#" + Module['canvas'].id, $0, 255);
|
||||
}, canvas_ptr);
|
||||
/* clang-format on */
|
||||
os->canvas_id.parse_utf8(canvas_ptr, 255);
|
||||
|
||||
// Set locale
|
||||
char locale_ptr[16];
|
||||
/* clang-format off */
|
||||
EM_ASM({
|
||||
stringToUTF8(Module['locale'], $0, 16);
|
||||
}, locale_ptr);
|
||||
|
||||
/* clang-format on */
|
||||
setenv("LANG", locale_ptr, true);
|
||||
|
||||
Main::setup2();
|
||||
// Ease up compatibility.
|
||||
ResourceLoader::set_abort_on_missing_resources(false);
|
||||
Main::start();
|
||||
os->run_async();
|
||||
os->main_loop_iterate();
|
||||
os->get_main_loop()->init();
|
||||
main_loop_callback();
|
||||
emscripten_resume_main_loop();
|
||||
}
|
||||
|
||||
int main(int argc, char *argv[]) {
|
||||
|
||||
new OS_JavaScript(argc, argv);
|
||||
os = new OS_JavaScript(argc, argv);
|
||||
// TODO: Check error return value.
|
||||
Main::setup(argv[0], argc - 1, &argv[1], false);
|
||||
emscripten_set_main_loop(main_loop_callback, -1, false);
|
||||
emscripten_pause_main_loop(); // Will need to wait for FS sync.
|
||||
|
||||
// Sync from persistent state into memory and then
|
||||
// run the 'main_after_fs_sync' function.
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue