diff --git a/core/io/resource_format_binary.cpp b/core/io/resource_format_binary.cpp index 109999d6125..ecbb9c0104b 100644 --- a/core/io/resource_format_binary.cpp +++ b/core/io/resource_format_binary.cpp @@ -1268,6 +1268,11 @@ void ResourceFormatLoaderBinary::get_recognized_extensions_for_type(const String return; } + // res files not supported for GDExtension. + if (p_type == "GDExtension") { + return; + } + List extensions; ClassDB::get_extensions_for_type(p_type, &extensions); diff --git a/editor/editor_file_system.cpp b/editor/editor_file_system.cpp index 2d1a9141200..c6ed310a9a1 100644 --- a/editor/editor_file_system.cpp +++ b/editor/editor_file_system.cpp @@ -248,11 +248,16 @@ void EditorFileSystem::_first_scan_filesystem() { ep.step(TTR("Scanning file structure..."), 0, true); nb_files_total = _scan_new_dir(first_scan_root_dir, d); + // Preloading GDExtensions file extensions to prevent looping on all the resource loaders + // for each files in _first_scan_process_scripts. + List gdextension_extensions; + ResourceLoader::get_recognized_extensions_for_type("GDExtension", &gdextension_extensions); + // This loads the global class names from the scripts and ensures that even if the // global_script_class_cache.cfg was missing or invalid, the global class names are valid in ScriptServer. // At the same time, to prevent looping multiple times in all files, it looks for extensions. ep.step(TTR("Loading global class names..."), 1, true); - _first_scan_process_scripts(first_scan_root_dir, existing_class_names, extensions); + _first_scan_process_scripts(first_scan_root_dir, gdextension_extensions, existing_class_names, extensions); // Removing invalid global class to prevent having invalid paths in ScriptServer. _remove_invalid_global_class_names(existing_class_names); @@ -276,16 +281,16 @@ void EditorFileSystem::_first_scan_filesystem() { ep.step(TTR("Starting file scan..."), 5, true); } -void EditorFileSystem::_first_scan_process_scripts(const ScannedDirectory *p_scan_dir, HashSet &p_existing_class_names, HashSet &p_extensions) { +void EditorFileSystem::_first_scan_process_scripts(const ScannedDirectory *p_scan_dir, List &p_gdextension_extensions, HashSet &p_existing_class_names, HashSet &p_extensions) { for (ScannedDirectory *scan_sub_dir : p_scan_dir->subdirs) { - _first_scan_process_scripts(scan_sub_dir, p_existing_class_names, p_extensions); + _first_scan_process_scripts(scan_sub_dir, p_gdextension_extensions, p_existing_class_names, p_extensions); } for (const String &scan_file : p_scan_dir->files) { // Optimization to skip the ResourceLoader::get_resource_type for files // that are not scripts. Some loader get_resource_type methods read the file // which can be very slow on large projects. - String ext = scan_file.get_extension().to_lower(); + const String ext = scan_file.get_extension().to_lower(); bool is_script = false; for (int i = 0; i < ScriptServer::get_language_count(); i++) { if (ScriptServer::get_language(i)->get_extension() == ext) { @@ -293,24 +298,29 @@ void EditorFileSystem::_first_scan_process_scripts(const ScannedDirectory *p_sca break; } } - if (!is_script) { - continue; // Not a script. + if (is_script) { + const String path = p_scan_dir->full_path.path_join(scan_file); + const String type = ResourceLoader::get_resource_type(path); + + if (ClassDB::is_parent_class(type, SNAME("Script"))) { + String script_class_extends; + String script_class_icon_path; + String script_class_name = _get_global_script_class(type, path, &script_class_extends, &script_class_icon_path); + _register_global_class_script(path, path, type, script_class_name, script_class_extends, script_class_icon_path); + + if (!script_class_name.is_empty()) { + p_existing_class_names.insert(script_class_name); + } + } } - String path = p_scan_dir->full_path.path_join(scan_file); - String type = ResourceLoader::get_resource_type(path); - - if (ClassDB::is_parent_class(type, SNAME("Script"))) { - String script_class_extends; - String script_class_icon_path; - String script_class_name = _get_global_script_class(type, path, &script_class_extends, &script_class_icon_path); - _register_global_class_script(path, path, type, script_class_name, script_class_extends, script_class_icon_path); - - if (!script_class_name.is_empty()) { - p_existing_class_names.insert(script_class_name); + // Check for GDExtensions. + if (p_gdextension_extensions.find(ext)) { + const String path = p_scan_dir->full_path.path_join(scan_file); + const String type = ResourceLoader::get_resource_type(path); + if (type == SNAME("GDExtension")) { + p_extensions.insert(path); } - } else if (type == SNAME("GDExtension")) { - p_extensions.insert(path); } } } diff --git a/editor/editor_file_system.h b/editor/editor_file_system.h index 7aa0137f4ed..7120a68b398 100644 --- a/editor/editor_file_system.h +++ b/editor/editor_file_system.h @@ -191,7 +191,7 @@ class EditorFileSystem : public Node { void _scan_filesystem(); void _first_scan_filesystem(); - void _first_scan_process_scripts(const ScannedDirectory *p_scan_dir, HashSet &p_existing_class_names, HashSet &p_extensions); + void _first_scan_process_scripts(const ScannedDirectory *p_scan_dir, List &p_gdextension_extensions, HashSet &p_existing_class_names, HashSet &p_extensions); HashSet late_update_files; diff --git a/scene/resources/resource_format_text.cpp b/scene/resources/resource_format_text.cpp index e234a81c885..4a318a10f08 100644 --- a/scene/resources/resource_format_text.cpp +++ b/scene/resources/resource_format_text.cpp @@ -1431,8 +1431,8 @@ void ResourceFormatLoaderText::get_recognized_extensions_for_type(const String & p_extensions->push_back("tscn"); } - // Don't allow .tres for PackedScenes. - if (p_type != "PackedScene") { + // Don't allow .tres for PackedScenes or GDExtension. + if (p_type != "PackedScene" && p_type != "GDExtension") { p_extensions->push_back("tres"); } }