Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix loss of gdextension on editor startup #98041

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions core/io/resource_format_binary.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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<String> extensions;
ClassDB::get_extensions_for_type(p_type, &extensions);

Expand Down
46 changes: 28 additions & 18 deletions editor/editor_file_system.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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<String> 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);
Expand All @@ -276,41 +281,46 @@ 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<String> &p_existing_class_names, HashSet<String> &p_extensions) {
void EditorFileSystem::_first_scan_process_scripts(const ScannedDirectory *p_scan_dir, List<String> &p_gdextension_extensions, HashSet<String> &p_existing_class_names, HashSet<String> &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) {
is_script = true;
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);

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 (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);
}
}
}

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);
}
}
}
Expand Down
2 changes: 1 addition & 1 deletion editor/editor_file_system.h
Original file line number Diff line number Diff line change
Expand Up @@ -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<String> &p_existing_class_names, HashSet<String> &p_extensions);
void _first_scan_process_scripts(const ScannedDirectory *p_scan_dir, List<String> &p_gdextension_extensions, HashSet<String> &p_existing_class_names, HashSet<String> &p_extensions);

HashSet<String> late_update_files;

Expand Down
4 changes: 2 additions & 2 deletions scene/resources/resource_format_text.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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");
}
}
Expand Down
Loading