diff --git a/core/bind/core_bind.cpp b/core/bind/core_bind.cpp index 2477b1b1879..3cc5489dd53 100644 --- a/core/bind/core_bind.cpp +++ b/core/bind/core_bind.cpp @@ -755,6 +755,11 @@ bool _OS::can_draw() const { return OS::get_singleton()->can_draw(); } +bool _OS::is_userfs_persistent() const { + + return OS::get_singleton()->is_userfs_persistent(); +} + int _OS::get_processor_count() const { return OS::get_singleton()->get_processor_count(); @@ -1051,6 +1056,7 @@ void _OS::_bind_methods() { ClassDB::bind_method(D_METHOD("get_model_name"), &_OS::get_model_name); ClassDB::bind_method(D_METHOD("can_draw"), &_OS::can_draw); + ClassDB::bind_method(D_METHOD("is_userfs_persistent"), &_OS::is_userfs_persistent); ClassDB::bind_method(D_METHOD("is_stdout_verbose"), &_OS::is_stdout_verbose); ClassDB::bind_method(D_METHOD("can_use_threads"), &_OS::can_use_threads); diff --git a/core/bind/core_bind.h b/core/bind/core_bind.h index 1a22d45932b..e0985383c29 100644 --- a/core/bind/core_bind.h +++ b/core/bind/core_bind.h @@ -266,6 +266,8 @@ public: bool can_draw() const; + bool is_userfs_persistent() const; + bool is_stdout_verbose() const; int get_processor_count() const; diff --git a/core/os/os.h b/core/os/os.h index 38bbbc0a575..954cc61b2cd 100644 --- a/core/os/os.h +++ b/core/os/os.h @@ -284,6 +284,8 @@ public: virtual bool can_draw() const = 0; + virtual bool is_userfs_persistent() const { return true; } + bool is_stdout_verbose() const; virtual void disable_crash_handler() {} diff --git a/doc/classes/OS.xml b/doc/classes/OS.xml index 65200c47697..468ccfb8f44 100644 --- a/doc/classes/OS.xml +++ b/doc/classes/OS.xml @@ -472,6 +472,13 @@ Return true if the engine was executed with -v (verbose stdout). + + + + + If [code]true[/code], the [code]user://[/code] file system is persistent, so that its state is the same after a player quits and starts the game again. Relevant to the HTML5 platform, where this persistence may be unavailable. + + diff --git a/platform/javascript/javascript_main.cpp b/platform/javascript/javascript_main.cpp index 4c948bf181b..ed4f416cfd6 100644 --- a/platform/javascript/javascript_main.cpp +++ b/platform/javascript/javascript_main.cpp @@ -39,8 +39,13 @@ static void main_loop() { os->main_loop_iterate(); } -extern "C" void main_after_fs_sync() { +extern "C" void main_after_fs_sync(char *p_idbfs_err) { + String idbfs_err = String::utf8(p_idbfs_err); + if (!idbfs_err.empty()) { + print_line("IndexedDB not available: " + idbfs_err); + } + os->set_idbfs_available(idbfs_err.empty()); // Ease up compatibility ResourceLoader::set_abort_on_missing_resources(false); Main::start(); @@ -60,14 +65,7 @@ int main(int argc, char *argv[]) { FS.mkdir('/userfs'); FS.mount(IDBFS, {}, '/userfs'); FS.syncfs(true, function(err) { - if (err) { - Module.setStatus('Failed to load persistent data\nPlease allow (third-party) cookies'); - Module.printErr('Failed to populate IDB file system: ' + err.message); - Module.noExitRuntime = false; - } else { - Module.print('Successfully populated IDB file system'); - ccall('main_after_fs_sync', null); - } + Module['ccall']('main_after_fs_sync', null, ['string'], [err ? err.message : ""]) }); ); /* clang-format on */ diff --git a/platform/javascript/os_javascript.cpp b/platform/javascript/os_javascript.cpp index f103035b276..4bb231084d4 100644 --- a/platform/javascript/os_javascript.cpp +++ b/platform/javascript/os_javascript.cpp @@ -821,7 +821,7 @@ bool OS_JavaScript::main_loop_iterate() { if (!main_loop) return false; - if (time_to_save_sync >= 0) { + if (idbfs_available && time_to_save_sync >= 0) { int64_t newtime = get_ticks_msec(); int64_t elapsed = newtime - last_sync_time; last_sync_time = newtime; @@ -911,10 +911,10 @@ String OS_JavaScript::get_executable_path() const { void OS_JavaScript::_close_notification_funcs(const String &p_file, int p_flags) { - print_line("close " + p_file + " flags " + itos(p_flags)); - if (p_file.begins_with("/userfs") && p_flags & FileAccess::WRITE) { - static_cast(get_singleton())->last_sync_time = OS::get_singleton()->get_ticks_msec(); - static_cast(get_singleton())->time_to_save_sync = 5000; //five seconds since last save + OS_JavaScript *os = static_cast(get_singleton()); + if (os->idbfs_available && p_file.begins_with("/userfs") && p_flags & FileAccess::WRITE) { + os->last_sync_time = OS::get_singleton()->get_ticks_msec(); + os->time_to_save_sync = 5000; //five seconds since last save } } @@ -989,6 +989,16 @@ bool OS_JavaScript::_check_internal_feature_support(const String &p_feature) { return p_feature == "web" || p_feature == "s3tc"; // TODO check for these features really being available } +void OS_JavaScript::set_idbfs_available(bool p_idbfs_available) { + + idbfs_available = p_idbfs_available; +} + +bool OS_JavaScript::is_userfs_persistent() const { + + return idbfs_available; +} + OS_JavaScript::OS_JavaScript(const char *p_execpath, GetDataDirFunc p_get_data_dir_func) { set_cmdline(p_execpath, get_cmdline_args()); main_loop = NULL; @@ -1000,6 +1010,7 @@ OS_JavaScript::OS_JavaScript(const char *p_execpath, GetDataDirFunc p_get_data_d get_data_dir_func = p_get_data_dir_func; FileAccessUnix::close_notification_func = _close_notification_funcs; + idbfs_available = false; time_to_save_sync = -1; } diff --git a/platform/javascript/os_javascript.h b/platform/javascript/os_javascript.h index 4c6469cb589..ff89f96e6dc 100644 --- a/platform/javascript/os_javascript.h +++ b/platform/javascript/os_javascript.h @@ -49,6 +49,7 @@ typedef String (*GetDataDirFunc)(); class OS_JavaScript : public OS_Unix { + bool idbfs_available; int64_t time_to_save_sync; int64_t last_sync_time; @@ -140,6 +141,8 @@ public: virtual bool can_draw() const; + virtual bool is_userfs_persistent() const; + virtual void set_cursor_shape(CursorShape p_shape); void main_loop_begin(); @@ -171,6 +174,8 @@ public: virtual bool _check_internal_feature_support(const String &p_feature); + void set_idbfs_available(bool p_idbfs_available); + OS_JavaScript(const char *p_execpath, GetDataDirFunc p_get_data_dir_func); ~OS_JavaScript(); };