Browse Source

Merge pull request #11782 from eska014/persistent-userfs-test

Add OS::is_userfs_persistent, allow starting HTML5 platform in private mode
Hein-Pieter van Braam 7 years ago
parent
commit
2bece6bbd3

+ 6 - 0
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);

+ 2 - 0
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;

+ 2 - 0
core/os/os.h

@@ -283,6 +283,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() {}

+ 7 - 0
doc/classes/OS.xml

@@ -472,6 +472,13 @@
 				Return true if the engine was executed with -v (verbose stdout).
 			</description>
 		</method>
+		<method name="is_userfs_persistent" qualifiers="const">
+			<return type="bool">
+			</return>
+			<description>
+				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.
+			</description>
+		</method>
 		<method name="is_vsync_enabled" qualifiers="const">
 			<return type="bool">
 			</return>

+ 7 - 9
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 */

+ 16 - 5
platform/javascript/os_javascript.cpp

@@ -825,7 +825,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;
@@ -915,10 +915,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<OS_JavaScript *>(get_singleton())->last_sync_time = OS::get_singleton()->get_ticks_msec();
-		static_cast<OS_JavaScript *>(get_singleton())->time_to_save_sync = 5000; //five seconds since last save
+	OS_JavaScript *os = static_cast<OS_JavaScript *>(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
 	}
 }
 
@@ -993,6 +993,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;
@@ -1004,6 +1014,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;
 }
 

+ 5 - 0
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;
 
@@ -136,6 +137,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();
@@ -167,6 +170,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();
 };