[Web] Improve Godot shutdown and cleanup.

This commit is contained in:
Fabio Alessandrelli 2022-11-03 14:00:52 +01:00
parent 6882890a34
commit cece83fdf2
2 changed files with 19 additions and 19 deletions

View File

@ -275,7 +275,7 @@ const InternalConfig = function (initConfig) { // eslint-disable-line no-unused-
'print': this.onPrint, 'print': this.onPrint,
'printErr': this.onPrintError, 'printErr': this.onPrintError,
'thisProgram': this.executable, 'thisProgram': this.executable,
'noExitRuntime': true, 'noExitRuntime': false,
'dynamicLibraries': [`${loadPath}.side.wasm`], 'dynamicLibraries': [`${loadPath}.side.wasm`],
'instantiateWasm': function (imports, onSuccess) { 'instantiateWasm': function (imports, onSuccess) {
function done(result) { function done(result) {

View File

@ -41,30 +41,25 @@
static OS_Web *os = nullptr; static OS_Web *os = nullptr;
static uint64_t target_ticks = 0; static uint64_t target_ticks = 0;
static bool main_started = false;
static bool shutdown_complete = false;
void exit_callback() { void exit_callback() {
emscripten_cancel_main_loop(); // After this, we can exit! if (!shutdown_complete) {
Main::cleanup(); return; // Still waiting.
}
if (main_started) {
Main::cleanup();
main_started = false;
}
int exit_code = OS_Web::get_singleton()->get_exit_code(); int exit_code = OS_Web::get_singleton()->get_exit_code();
memdelete(os); memdelete(os);
os = nullptr; os = nullptr;
emscripten_force_exit(exit_code); // No matter that we call cancel_main_loop, regular "exit" will not work, forcing. emscripten_force_exit(exit_code); // Exit runtime.
} }
void cleanup_after_sync() { void cleanup_after_sync() {
emscripten_set_main_loop(exit_callback, -1, false); shutdown_complete = true;
}
void early_cleanup() {
emscripten_cancel_main_loop(); // After this, we can exit!
int exit_code = OS_Web::get_singleton()->get_exit_code();
memdelete(os);
os = nullptr;
emscripten_force_exit(exit_code); // No matter that we call cancel_main_loop, regular "exit" will not work, forcing.
}
void early_cleanup_sync() {
emscripten_set_main_loop(early_cleanup, -1, false);
} }
void main_loop_callback() { void main_loop_callback() {
@ -87,7 +82,8 @@ void main_loop_callback() {
target_ticks += (uint64_t)(1000000 / max_fps); target_ticks += (uint64_t)(1000000 / max_fps);
} }
if (os->main_loop_iterate()) { if (os->main_loop_iterate()) {
emscripten_cancel_main_loop(); // Cancel current loop and wait for cleanup_after_sync. emscripten_cancel_main_loop(); // Cancel current loop and set the cleanup one.
emscripten_set_main_loop(exit_callback, -1, false);
godot_js_os_finish_async(cleanup_after_sync); godot_js_os_finish_async(cleanup_after_sync);
} }
} }
@ -109,10 +105,14 @@ extern EMSCRIPTEN_KEEPALIVE int godot_web_main(int argc, char *argv[]) {
} }
os->set_exit_code(exit_code); os->set_exit_code(exit_code);
// Will only exit after sync. // Will only exit after sync.
godot_js_os_finish_async(early_cleanup_sync); emscripten_set_main_loop(exit_callback, -1, false);
godot_js_os_finish_async(cleanup_after_sync);
return exit_code; return exit_code;
} }
os->set_exit_code(0);
main_started = true;
// Ease up compatibility. // Ease up compatibility.
ResourceLoader::set_abort_on_missing_resources(false); ResourceLoader::set_abort_on_missing_resources(false);