Browse Source

Fix freeze after building C#

Hilderin 1 year ago
parent
commit
cc990efddf

+ 86 - 79
editor/editor_file_system.cpp

@@ -1714,105 +1714,112 @@ HashSet<StringName> EditorFileSystem::_get_scene_groups(const String &p_path) {
 
 void EditorFileSystem::update_file(const String &p_file) {
 	ERR_FAIL_COND(p_file.is_empty());
-	EditorFileSystemDirectory *fs = nullptr;
-	int cpos = -1;
+	update_files({ p_file });
+}
 
-	if (!_find_file(p_file, &fs, cpos)) {
-		if (!fs) {
-			return;
+void EditorFileSystem::update_files(const Vector<String> &p_script_paths) {
+	for (const String &file : p_script_paths) {
+		ERR_CONTINUE(file.is_empty());
+		EditorFileSystemDirectory *fs = nullptr;
+		int cpos = -1;
+
+		if (!_find_file(file, &fs, cpos)) {
+			if (!fs) {
+				return;
+			}
 		}
-	}
 
-	if (!FileAccess::exists(p_file)) {
-		//was removed
-		_delete_internal_files(p_file);
-		if (cpos != -1) { // Might've never been part of the editor file system (*.* files deleted in Open dialog).
-			if (fs->files[cpos]->uid != ResourceUID::INVALID_ID) {
-				if (ResourceUID::get_singleton()->has_id(fs->files[cpos]->uid)) {
-					ResourceUID::get_singleton()->remove_id(fs->files[cpos]->uid);
+		if (!FileAccess::exists(file)) {
+			//was removed
+			_delete_internal_files(file);
+			if (cpos != -1) { // Might've never been part of the editor file system (*.* files deleted in Open dialog).
+				if (fs->files[cpos]->uid != ResourceUID::INVALID_ID) {
+					if (ResourceUID::get_singleton()->has_id(fs->files[cpos]->uid)) {
+						ResourceUID::get_singleton()->remove_id(fs->files[cpos]->uid);
+					}
 				}
-			}
-			if (ClassDB::is_parent_class(fs->files[cpos]->type, SNAME("Script"))) {
-				_queue_update_script_class(p_file);
-			}
-			if (fs->files[cpos]->type == SNAME("PackedScene")) {
-				_queue_update_scene_groups(p_file);
+				if (ClassDB::is_parent_class(fs->files[cpos]->type, SNAME("Script"))) {
+					_queue_update_script_class(file);
+				}
+				if (fs->files[cpos]->type == SNAME("PackedScene")) {
+					_queue_update_scene_groups(file);
+				}
+
+				memdelete(fs->files[cpos]);
+				fs->files.remove_at(cpos);
 			}
 
-			memdelete(fs->files[cpos]);
-			fs->files.remove_at(cpos);
+			_update_pending_script_classes();
+			_update_pending_scene_groups();
+			call_deferred(SNAME("emit_signal"), "filesystem_changed"); //update later
+			return;
 		}
 
-		_update_pending_script_classes();
-		_update_pending_scene_groups();
-		call_deferred(SNAME("emit_signal"), "filesystem_changed"); //update later
-		return;
-	}
-
-	String type = ResourceLoader::get_resource_type(p_file);
-	if (type.is_empty() && textfile_extensions.has(p_file.get_extension())) {
-		type = "TextFile";
-	}
-	String script_class = ResourceLoader::get_resource_script_class(p_file);
+		String type = ResourceLoader::get_resource_type(file);
+		if (type.is_empty() && textfile_extensions.has(file.get_extension())) {
+			type = "TextFile";
+		}
+		String script_class = ResourceLoader::get_resource_script_class(file);
 
-	ResourceUID::ID uid = ResourceLoader::get_resource_uid(p_file);
+		ResourceUID::ID uid = ResourceLoader::get_resource_uid(file);
 
-	if (cpos == -1) {
-		// The file did not exist, it was added.
-		int idx = 0;
-		String file_name = p_file.get_file();
+		if (cpos == -1) {
+			// The file did not exist, it was added.
+			int idx = 0;
+			String file_name = file.get_file();
 
-		for (int i = 0; i < fs->files.size(); i++) {
-			if (p_file.filenocasecmp_to(fs->files[i]->file) < 0) {
-				break;
+			for (int i = 0; i < fs->files.size(); i++) {
+				if (file.filenocasecmp_to(fs->files[i]->file) < 0) {
+					break;
+				}
+				idx++;
 			}
-			idx++;
-		}
 
-		EditorFileSystemDirectory::FileInfo *fi = memnew(EditorFileSystemDirectory::FileInfo);
-		fi->file = file_name;
-		fi->import_modified_time = 0;
-		fi->import_valid = type == "TextFile" ? true : ResourceLoader::is_import_valid(p_file);
+			EditorFileSystemDirectory::FileInfo *fi = memnew(EditorFileSystemDirectory::FileInfo);
+			fi->file = file_name;
+			fi->import_modified_time = 0;
+			fi->import_valid = type == "TextFile" ? true : ResourceLoader::is_import_valid(file);
 
-		if (idx == fs->files.size()) {
-			fs->files.push_back(fi);
+			if (idx == fs->files.size()) {
+				fs->files.push_back(fi);
+			} else {
+				fs->files.insert(idx, fi);
+			}
+			cpos = idx;
 		} else {
-			fs->files.insert(idx, fi);
+			//the file exists and it was updated, and was not added in this step.
+			//this means we must force upon next restart to scan it again, to get proper type and dependencies
+			late_update_files.insert(file);
+			_save_late_updated_files(); //files need to be updated in the re-scan
 		}
-		cpos = idx;
-	} else {
-		//the file exists and it was updated, and was not added in this step.
-		//this means we must force upon next restart to scan it again, to get proper type and dependencies
-		late_update_files.insert(p_file);
-		_save_late_updated_files(); //files need to be updated in the re-scan
-	}
 
-	fs->files[cpos]->type = type;
-	fs->files[cpos]->resource_script_class = script_class;
-	fs->files[cpos]->uid = uid;
-	fs->files[cpos]->script_class_name = _get_global_script_class(type, p_file, &fs->files[cpos]->script_class_extends, &fs->files[cpos]->script_class_icon_path);
-	fs->files[cpos]->import_group_file = ResourceLoader::get_import_group_file(p_file);
-	fs->files[cpos]->modified_time = FileAccess::get_modified_time(p_file);
-	fs->files[cpos]->deps = _get_dependencies(p_file);
-	fs->files[cpos]->import_valid = type == "TextFile" ? true : ResourceLoader::is_import_valid(p_file);
+		fs->files[cpos]->type = type;
+		fs->files[cpos]->resource_script_class = script_class;
+		fs->files[cpos]->uid = uid;
+		fs->files[cpos]->script_class_name = _get_global_script_class(type, file, &fs->files[cpos]->script_class_extends, &fs->files[cpos]->script_class_icon_path);
+		fs->files[cpos]->import_group_file = ResourceLoader::get_import_group_file(file);
+		fs->files[cpos]->modified_time = FileAccess::get_modified_time(file);
+		fs->files[cpos]->deps = _get_dependencies(file);
+		fs->files[cpos]->import_valid = type == "TextFile" ? true : ResourceLoader::is_import_valid(file);
 
-	if (uid != ResourceUID::INVALID_ID) {
-		if (ResourceUID::get_singleton()->has_id(uid)) {
-			ResourceUID::get_singleton()->set_id(uid, p_file);
-		} else {
-			ResourceUID::get_singleton()->add_id(uid, p_file);
-		}
+		if (uid != ResourceUID::INVALID_ID) {
+			if (ResourceUID::get_singleton()->has_id(uid)) {
+				ResourceUID::get_singleton()->set_id(uid, file);
+			} else {
+				ResourceUID::get_singleton()->add_id(uid, file);
+			}
 
-		ResourceUID::get_singleton()->update_cache();
-	}
-	// Update preview
-	EditorResourcePreview::get_singleton()->check_for_invalidation(p_file);
+			ResourceUID::get_singleton()->update_cache();
+		}
+		// Update preview
+		EditorResourcePreview::get_singleton()->check_for_invalidation(file);
 
-	if (ClassDB::is_parent_class(fs->files[cpos]->type, SNAME("Script"))) {
-		_queue_update_script_class(p_file);
-	}
-	if (fs->files[cpos]->type == SNAME("PackedScene")) {
-		_queue_update_scene_groups(p_file);
+		if (ClassDB::is_parent_class(fs->files[cpos]->type, SNAME("Script"))) {
+			_queue_update_script_class(file);
+		}
+		if (fs->files[cpos]->type == SNAME("PackedScene")) {
+			_queue_update_scene_groups(file);
+		}
 	}
 
 	_update_pending_script_classes();

+ 1 - 0
editor/editor_file_system.h

@@ -310,6 +310,7 @@ public:
 	void scan();
 	void scan_changes();
 	void update_file(const String &p_file);
+	void update_files(const Vector<String> &p_script_paths);
 	HashSet<String> get_valid_extensions() const;
 	void register_global_class_script(const String &p_search_path, const String &p_target_path);
 

+ 4 - 3
modules/mono/glue/GodotSharp/GodotSharp/Core/Bridge/ScriptManagerBridge.cs

@@ -427,10 +427,11 @@ namespace Godot.Bridge
             // This method may be called before initialization.
             if (NativeFuncs.godotsharp_dotnet_module_is_initialized().ToBool() && Engine.IsEditorHint())
             {
-                foreach (var scriptPath in _pathTypeBiMap.Paths)
+                if (_pathTypeBiMap.Paths.Count > 0)
                 {
-                    using godot_string nativeScriptPath = Marshaling.ConvertStringToNative(scriptPath);
-                    NativeFuncs.godotsharp_internal_editor_file_system_update_file(nativeScriptPath);
+                    string[] scriptPaths = _pathTypeBiMap.Paths.ToArray();
+                    using godot_packed_string_array scriptPathsNative = Marshaling.ConvertSystemArrayToNativePackedStringArray(scriptPaths);
+                    NativeFuncs.godotsharp_internal_editor_file_system_update_files(scriptPathsNative);
                 }
             }
         }

+ 2 - 1
modules/mono/glue/GodotSharp/GodotSharp/Core/Bridge/ScriptManagerBridge.types.cs

@@ -1,4 +1,5 @@
 using System;
+using System.Collections.Generic;
 using System.Diagnostics;
 using System.Diagnostics.CodeAnalysis;
 using System.Linq;
@@ -64,7 +65,7 @@ public static partial class ScriptManagerBridge
         private System.Collections.Generic.Dictionary<string, Type> _pathTypeMap = new();
         private System.Collections.Generic.Dictionary<Type, string> _typePathMap = new();
 
-        public System.Collections.Generic.IEnumerable<string> Paths => _pathTypeMap.Keys;
+        public IReadOnlyCollection<string> Paths => _pathTypeMap.Keys;
 
         public void Add(string scriptPath, Type scriptType)
         {

+ 1 - 1
modules/mono/glue/GodotSharp/GodotSharp/Core/NativeInterop/NativeFuncs.cs

@@ -59,7 +59,7 @@ namespace Godot.NativeInterop
         internal static partial void godotsharp_stack_info_vector_destroy(
             ref DebuggingUtils.godot_stack_info_vector p_stack_info_vector);
 
-        internal static partial void godotsharp_internal_editor_file_system_update_file(in godot_string p_script_path);
+        internal static partial void godotsharp_internal_editor_file_system_update_files(in godot_packed_string_array p_script_paths);
 
         internal static partial void godotsharp_internal_script_debugger_send_error(in godot_string p_func,
             in godot_string p_file, int p_line, in godot_string p_err, in godot_string p_descr,

+ 3 - 3
modules/mono/glue/runtime_interop.cpp

@@ -315,13 +315,13 @@ void godotsharp_internal_new_csharp_script(Ref<CSharpScript> *r_dest) {
 	memnew_placement(r_dest, Ref<CSharpScript>(memnew(CSharpScript)));
 }
 
-void godotsharp_internal_editor_file_system_update_file(const String *p_script_path) {
+void godotsharp_internal_editor_file_system_update_files(const PackedStringArray &p_script_paths) {
 #ifdef TOOLS_ENABLED
 	// If the EditorFileSystem singleton is available, update the file;
 	// otherwise, the file will be updated when the singleton becomes available.
 	EditorFileSystem *efs = EditorFileSystem::get_singleton();
 	if (efs) {
-		efs->update_file(*p_script_path);
+		efs->update_files(p_script_paths);
 	}
 #else
 	// EditorFileSystem is only available when running in the Godot editor.
@@ -1450,7 +1450,7 @@ static const void *unmanaged_callbacks[]{
 	(void *)godotsharp_engine_get_singleton,
 	(void *)godotsharp_stack_info_vector_resize,
 	(void *)godotsharp_stack_info_vector_destroy,
-	(void *)godotsharp_internal_editor_file_system_update_file,
+	(void *)godotsharp_internal_editor_file_system_update_files,
 	(void *)godotsharp_internal_script_debugger_send_error,
 	(void *)godotsharp_internal_script_debugger_is_active,
 	(void *)godotsharp_internal_object_get_associated_gchandle,