summaryrefslogtreecommitdiffstats
path: root/editor/editor_file_system.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'editor/editor_file_system.cpp')
-rw-r--r--editor/editor_file_system.cpp147
1 files changed, 53 insertions, 94 deletions
diff --git a/editor/editor_file_system.cpp b/editor/editor_file_system.cpp
index 474a45cf2b..bae9062ff1 100644
--- a/editor/editor_file_system.cpp
+++ b/editor/editor_file_system.cpp
@@ -243,18 +243,27 @@ void EditorFileSystem::_first_scan_filesystem() {
first_scan_root_dir = memnew(ScannedDirectory);
first_scan_root_dir->full_path = "res://";
HashSet<String> existing_class_names;
+ HashSet<String> extensions;
ep.step(TTR("Scanning file structure..."), 0, true);
nb_files_total = _scan_new_dir(first_scan_root_dir, d);
// 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);
+ _first_scan_process_scripts(first_scan_root_dir, existing_class_names, extensions);
// Removing invalid global class to prevent having invalid paths in ScriptServer.
_remove_invalid_global_class_names(existing_class_names);
+ // Processing extensions to add new extensions or remove invalid ones.
+ // Important to do it in the first scan so custom types, new class names, custom importers, etc...
+ // from extensions are ready to go before plugins, autoloads and resources validation/importation.
+ // At this point, a restart of the editor should not be needed so we don't use the return value.
+ ep.step(TTR("Verifying GDExtensions..."), 2, true);
+ GDExtensionManager::get_singleton()->ensure_extensions_loaded(extensions);
+
// Now that all the global class names should be loaded, create autoloads and plugins.
// This is done after loading the global class names because autoloads and plugins can use
// global class names.
@@ -267,9 +276,9 @@ 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) {
+void EditorFileSystem::_first_scan_process_scripts(const ScannedDirectory *p_scan_dir, 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);
+ _first_scan_process_scripts(scan_sub_dir, p_existing_class_names, p_extensions);
}
for (const String &scan_file : p_scan_dir->files) {
@@ -285,6 +294,8 @@ void EditorFileSystem::_first_scan_process_scripts(const ScannedDirectory *p_sca
if (!script_class_name.is_empty()) {
p_existing_class_names.insert(script_class_name);
}
+ } else if (type == SNAME("GDExtension")) {
+ p_extensions.insert(path);
}
}
}
@@ -1855,25 +1866,26 @@ void EditorFileSystem::_update_script_classes() {
return;
}
- update_script_mutex.lock();
+ {
+ MutexLock update_script_lock(update_script_mutex);
- EditorProgress *ep = nullptr;
- if (update_script_paths.size() > 1) {
- ep = memnew(EditorProgress("update_scripts_classes", TTR("Registering global classes..."), update_script_paths.size()));
- }
+ EditorProgress *ep = nullptr;
+ if (update_script_paths.size() > 1) {
+ ep = memnew(EditorProgress("update_scripts_classes", TTR("Registering global classes..."), update_script_paths.size()));
+ }
- int step_count = 0;
- for (const KeyValue<String, ScriptInfo> &E : update_script_paths) {
- _register_global_class_script(E.key, E.key, E.value.type, E.value.script_class_name, E.value.script_class_extends, E.value.script_class_icon_path);
- if (ep) {
- ep->step(E.value.script_class_name, step_count++, false);
+ int step_count = 0;
+ for (const KeyValue<String, ScriptInfo> &E : update_script_paths) {
+ _register_global_class_script(E.key, E.key, E.value.type, E.value.script_class_name, E.value.script_class_extends, E.value.script_class_icon_path);
+ if (ep) {
+ ep->step(E.value.script_class_name, step_count++, false);
+ }
}
- }
- memdelete_notnull(ep);
+ memdelete_notnull(ep);
- update_script_paths.clear();
- update_script_mutex.unlock();
+ update_script_paths.clear();
+ }
ScriptServer::save_global_classes();
EditorNode::get_editor_data().script_class_save_icon_paths();
@@ -1894,7 +1906,7 @@ void EditorFileSystem::_update_script_documentation() {
return;
}
- update_script_mutex.lock();
+ MutexLock update_script_lock(update_script_mutex);
EditorProgress *ep = nullptr;
if (update_script_paths_documentation.size() > 1) {
@@ -1933,7 +1945,6 @@ void EditorFileSystem::_update_script_documentation() {
memdelete_notnull(ep);
update_script_paths_documentation.clear();
- update_script_mutex.unlock();
}
void EditorFileSystem::_process_update_pending() {
@@ -1945,7 +1956,7 @@ void EditorFileSystem::_process_update_pending() {
}
void EditorFileSystem::_queue_update_script_class(const String &p_path, const String &p_type, const String &p_script_class_name, const String &p_script_class_extends, const String &p_script_class_icon_path) {
- update_script_mutex.lock();
+ MutexLock update_script_lock(update_script_mutex);
ScriptInfo si;
si.type = p_type;
@@ -1955,8 +1966,6 @@ void EditorFileSystem::_queue_update_script_class(const String &p_path, const St
update_script_paths.insert(p_path, si);
update_script_paths_documentation.insert(p_path);
-
- update_script_mutex.unlock();
}
void EditorFileSystem::_update_scene_groups() {
@@ -1970,31 +1979,32 @@ void EditorFileSystem::_update_scene_groups() {
}
int step_count = 0;
- update_scene_mutex.lock();
- for (const String &path : update_scene_paths) {
- ProjectSettings::get_singleton()->remove_scene_groups_cache(path);
+ {
+ MutexLock update_scene_lock(update_scene_mutex);
+ for (const String &path : update_scene_paths) {
+ ProjectSettings::get_singleton()->remove_scene_groups_cache(path);
- int index = -1;
- EditorFileSystemDirectory *efd = find_file(path, &index);
+ int index = -1;
+ EditorFileSystemDirectory *efd = find_file(path, &index);
- if (!efd || index < 0) {
- // The file was removed.
- continue;
- }
+ if (!efd || index < 0) {
+ // The file was removed.
+ continue;
+ }
- const HashSet<StringName> scene_groups = PackedScene::get_scene_groups(path);
- if (!scene_groups.is_empty()) {
- ProjectSettings::get_singleton()->add_scene_groups_cache(path, scene_groups);
- }
+ const HashSet<StringName> scene_groups = PackedScene::get_scene_groups(path);
+ if (!scene_groups.is_empty()) {
+ ProjectSettings::get_singleton()->add_scene_groups_cache(path, scene_groups);
+ }
- if (ep) {
- ep->step(efd->files[index]->file, step_count++, false);
+ if (ep) {
+ ep->step(efd->files[index]->file, step_count++, false);
+ }
}
- }
- memdelete_notnull(ep);
- update_scene_paths.clear();
- update_scene_mutex.unlock();
+ memdelete_notnull(ep);
+ update_scene_paths.clear();
+ }
ProjectSettings::get_singleton()->save_scene_groups_cache();
}
@@ -2009,9 +2019,8 @@ void EditorFileSystem::_update_pending_scene_groups() {
}
void EditorFileSystem::_queue_update_scene_groups(const String &p_path) {
- update_scene_mutex.lock();
+ MutexLock update_scene_lock(update_scene_mutex);
update_scene_paths.insert(p_path);
- update_scene_mutex.unlock();
}
void EditorFileSystem::_get_all_scenes(EditorFileSystemDirectory *p_dir, HashSet<String> &r_list) {
@@ -3016,57 +3025,7 @@ bool EditorFileSystem::_scan_extensions() {
_scan_extensions_dir(d, extensions);
- //verify against loaded extensions
-
- Vector<String> extensions_added;
- Vector<String> extensions_removed;
-
- for (const String &E : extensions) {
- if (!GDExtensionManager::get_singleton()->is_extension_loaded(E)) {
- extensions_added.push_back(E);
- }
- }
-
- Vector<String> loaded_extensions = GDExtensionManager::get_singleton()->get_loaded_extensions();
- for (int i = 0; i < loaded_extensions.size(); i++) {
- if (!extensions.has(loaded_extensions[i])) {
- // The extension may not have a .gdextension file.
- if (!FileAccess::exists(loaded_extensions[i])) {
- extensions_removed.push_back(loaded_extensions[i]);
- }
- }
- }
-
- String extension_list_config_file = GDExtension::get_extension_list_config_file();
- if (extensions.size()) {
- if (extensions_added.size() || extensions_removed.size()) { //extensions were added or removed
- Ref<FileAccess> f = FileAccess::open(extension_list_config_file, FileAccess::WRITE);
- for (const String &E : extensions) {
- f->store_line(E);
- }
- }
- } else {
- if (loaded_extensions.size() || FileAccess::exists(extension_list_config_file)) { //extensions were removed
- Ref<DirAccess> da = DirAccess::create(DirAccess::ACCESS_RESOURCES);
- da->remove(extension_list_config_file);
- }
- }
-
- bool needs_restart = false;
- for (int i = 0; i < extensions_added.size(); i++) {
- GDExtensionManager::LoadStatus st = GDExtensionManager::get_singleton()->load_extension(extensions_added[i]);
- if (st == GDExtensionManager::LOAD_STATUS_NEEDS_RESTART) {
- needs_restart = true;
- }
- }
- for (int i = 0; i < extensions_removed.size(); i++) {
- GDExtensionManager::LoadStatus st = GDExtensionManager::get_singleton()->unload_extension(extensions_removed[i]);
- if (st == GDExtensionManager::LOAD_STATUS_NEEDS_RESTART) {
- needs_restart = true;
- }
- }
-
- return needs_restart;
+ return GDExtensionManager::get_singleton()->ensure_extensions_loaded(extensions);
}
void EditorFileSystem::_bind_methods() {