mirror of
https://github.com/godotengine/godot.git
synced 2025-10-23 18:03:35 +00:00
JS synchronous start, better persistent FS sync.
The engine now expects to emscripten FS to be setup and sync-ed before main is called. This is exposed via `Module["initFS"]` which also allows to setup multiple persistence paths (internal use only for now). Additionally, FS syncing is done **once** for every loop if at least one file in a persistent path was open for writing and closed, and if the FS is not syncing already. This should potentially fix issues reported by users where "autosave" would not work on the web (never calling `syncfs` because of too many writes).
This commit is contained in:
parent
e7d00d08f5
commit
35fcc1835c
5 changed files with 103 additions and 66 deletions
|
@ -94,12 +94,27 @@ void main_loop_callback() {
|
|||
/* clang-format on */
|
||||
os->get_main_loop()->finish();
|
||||
os->finalize_async(); // Will add all the async finish functions.
|
||||
/* clang-format off */
|
||||
EM_ASM({
|
||||
Promise.all(Module.async_finish).then(function() {
|
||||
Module.async_finish = [];
|
||||
return new Promise(function(accept, reject) {
|
||||
if (!Module.idbfs) {
|
||||
accept();
|
||||
return;
|
||||
}
|
||||
FS.syncfs(function(error) {
|
||||
if (error) {
|
||||
err('Failed to save IDB file system: ' + error.message);
|
||||
}
|
||||
accept();
|
||||
});
|
||||
});
|
||||
}).then(function() {
|
||||
ccall("cleanup_after_sync", null, []);
|
||||
});
|
||||
});
|
||||
/* clang-format on */
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -107,13 +122,8 @@ 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) {
|
||||
// Set IDBFS status
|
||||
String idbfs_err = String::utf8(p_idbfs_err);
|
||||
if (!idbfs_err.empty()) {
|
||||
print_line("IndexedDB not available: " + idbfs_err);
|
||||
}
|
||||
os->set_idb_available(idbfs_err.empty());
|
||||
int main(int argc, char *argv[]) {
|
||||
os = new OS_JavaScript(argc, argv);
|
||||
|
||||
// Set canvas ID
|
||||
char canvas_ptr[256];
|
||||
|
@ -133,7 +143,10 @@ extern "C" EMSCRIPTEN_KEEPALIVE void main_after_fs_sync(char *p_idbfs_err) {
|
|||
/* clang-format on */
|
||||
setenv("LANG", locale_ptr, true);
|
||||
|
||||
Main::setup2();
|
||||
// Set IDBFS status
|
||||
os->set_idb_available((bool)EM_ASM_INT({ return Module.idbfs }));
|
||||
|
||||
Main::setup(argv[0], argc - 1, &argv[1]);
|
||||
// Ease up compatibility.
|
||||
ResourceLoader::set_abort_on_missing_resources(false);
|
||||
Main::start();
|
||||
|
@ -144,35 +157,8 @@ extern "C" EMSCRIPTEN_KEEPALIVE void main_after_fs_sync(char *p_idbfs_err) {
|
|||
ccall("_request_quit_callback", null, []);
|
||||
};
|
||||
});
|
||||
emscripten_set_main_loop(main_loop_callback, -1, false);
|
||||
// Immediately run the first iteration.
|
||||
// We are inside an animation frame, we want to immediately draw on the newly setup canvas.
|
||||
main_loop_callback();
|
||||
emscripten_resume_main_loop();
|
||||
}
|
||||
|
||||
int main(int argc, char *argv[]) {
|
||||
// Create and mount userfs immediately.
|
||||
EM_ASM({
|
||||
FS.mkdir('/userfs');
|
||||
FS.mount(IDBFS, {}, '/userfs');
|
||||
});
|
||||
os = new OS_JavaScript(argc, argv);
|
||||
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.
|
||||
/* clang-format off */
|
||||
EM_ASM({
|
||||
FS.syncfs(true, function(err) {
|
||||
requestAnimationFrame(function() {
|
||||
ccall('main_after_fs_sync', null, ['string'], [err ? err.message : ""]);
|
||||
});
|
||||
});
|
||||
});
|
||||
/* clang-format on */
|
||||
|
||||
return 0;
|
||||
// Continued async in main_after_fs_sync() from the syncfs() callback.
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue