From 4f898b498fab5dc2691a88934be78b78698c6401 Mon Sep 17 00:00:00 2001 From: Aaron Franke Date: Sat, 17 Jan 2026 16:38:08 -0800 Subject: [PATCH] Guard against non-main-thread emission of EditorFileSystem changed signal --- editor/docks/import_dock.cpp | 2 +- editor/editor_interface.cpp | 2 +- editor/file_system/editor_file_system.cpp | 22 +++++++++++++++++----- editor/file_system/editor_file_system.h | 4 +++- 4 files changed, 22 insertions(+), 8 deletions(-) diff --git a/editor/docks/import_dock.cpp b/editor/docks/import_dock.cpp index ae86cd22ac..d641dfebe4 100644 --- a/editor/docks/import_dock.cpp +++ b/editor/docks/import_dock.cpp @@ -691,7 +691,7 @@ void ImportDock::_reimport() { } EditorFileSystem::get_singleton()->reimport_files(params->paths); - EditorFileSystem::get_singleton()->emit_signal(SNAME("filesystem_changed")); //it changed, so force emitting the signal + EditorFileSystem::get_singleton()->filesystem_changed(); // It changed, so force emitting the signal. _set_dirty(false); } diff --git a/editor/editor_interface.cpp b/editor/editor_interface.cpp index c5191bdffe..dcb1c6151a 100644 --- a/editor/editor_interface.cpp +++ b/editor/editor_interface.cpp @@ -368,7 +368,7 @@ void EditorInterface::make_scene_preview(const String &p_path, Node *p_scene, in } EditorResourcePreview::get_singleton()->check_for_invalidation(p_path); - EditorFileSystem::get_singleton()->emit_signal(SNAME("filesystem_changed")); + EditorFileSystem::get_singleton()->filesystem_changed(); } void EditorInterface::add_root_node(Node *p_node) { diff --git a/editor/file_system/editor_file_system.cpp b/editor/file_system/editor_file_system.cpp index 9b3448d65e..1a9e609fb0 100644 --- a/editor/file_system/editor_file_system.cpp +++ b/editor/file_system/editor_file_system.cpp @@ -2552,16 +2552,16 @@ void EditorFileSystem::update_files(const Vector &p_script_paths) { if (!is_scanning()) { _process_update_pending(); } - if (!filesystem_changed_queued) { - filesystem_changed_queued = true; + if (!filesystem_changed_queued.is_set()) { + filesystem_changed_queued.set(); callable_mp(this, &EditorFileSystem::_notify_filesystem_changed).call_deferred(); } } } void EditorFileSystem::_notify_filesystem_changed() { - emit_signal("filesystem_changed"); - filesystem_changed_queued = false; + emit_signal(SNAME("filesystem_changed")); + filesystem_changed_queued.clear(); } HashSet EditorFileSystem::get_valid_extensions() const { @@ -2602,6 +2602,18 @@ void EditorFileSystem::register_global_class_script(const String &p_search_path, } } +void EditorFileSystem::filesystem_changed() { + if (Thread::is_main_thread()) { + _notify_filesystem_changed(); + return; + } + // If not already queued, queue a deferred call to notify about filesystem changes. + if (!filesystem_changed_queued.is_set()) { + filesystem_changed_queued.set(); + callable_mp(this, &EditorFileSystem::_notify_filesystem_changed).call_deferred(); + } +} + Error EditorFileSystem::_reimport_group(const String &p_group_file, const Vector &p_files) { String importer_name; @@ -3720,7 +3732,7 @@ void EditorFileSystem::_bind_methods() { ClassDB::bind_method(D_METHOD("get_file_type", "path"), &EditorFileSystem::get_file_type); ClassDB::bind_method(D_METHOD("reimport_files", "files"), &EditorFileSystem::reimport_files); - ADD_SIGNAL(MethodInfo("filesystem_changed")); + ADD_SIGNAL(MethodInfo("filesystem_changed")); // May only be emitted on the main thread. ADD_SIGNAL(MethodInfo("script_classes_updated")); ADD_SIGNAL(MethodInfo("sources_changed", PropertyInfo(Variant::BOOL, "exist"))); ADD_SIGNAL(MethodInfo("resources_reimporting", PropertyInfo(Variant::PACKED_STRING_ARRAY, "resources"))); diff --git a/editor/file_system/editor_file_system.h b/editor/file_system/editor_file_system.h index 42fd6c994a..e4924ef89b 100644 --- a/editor/file_system/editor_file_system.h +++ b/editor/file_system/editor_file_system.h @@ -182,7 +182,7 @@ class EditorFileSystem : public Node { EditorFileSystemDirectory *new_filesystem = nullptr; static ScannedDirectory *first_scan_root_dir; - bool filesystem_changed_queued = false; + SafeFlag filesystem_changed_queued; bool scanning = false; bool importing = false; bool first_scan = true; @@ -392,6 +392,8 @@ public: HashSet get_valid_extensions() const; void register_global_class_script(const String &p_search_path, const String &p_target_path); + void filesystem_changed(); + EditorFileSystemDirectory *get_filesystem_path(const String &p_path); String get_file_type(const String &p_file) const; EditorFileSystemDirectory *find_file(const String &p_file, int *r_index) const;