Browse Source

Clean up EditorFileSystem script parsing

* Optimize only update modified/added/removed files.
* Clean up documentation parsing.
Juan Linietsky 2 years ago
parent
commit
5bdc0d97d3

+ 9 - 0
core/object/script_language.cpp

@@ -263,6 +263,15 @@ void ScriptServer::remove_global_class(const StringName &p_class) {
 	global_classes.erase(p_class);
 	global_classes.erase(p_class);
 }
 }
 
 
+void ScriptServer::remove_global_class_by_path(const String &p_path) {
+	for (const KeyValue<StringName, GlobalScriptClass> &kv : global_classes) {
+		if (kv.value.path == p_path) {
+			global_classes.erase(kv.key);
+			return;
+		}
+	}
+}
+
 bool ScriptServer::is_global_class(const StringName &p_class) {
 bool ScriptServer::is_global_class(const StringName &p_class) {
 	return global_classes.has(p_class);
 	return global_classes.has(p_class);
 }
 }

+ 1 - 0
core/object/script_language.h

@@ -80,6 +80,7 @@ public:
 	static void global_classes_clear();
 	static void global_classes_clear();
 	static void add_global_class(const StringName &p_class, const StringName &p_base, const StringName &p_language, const String &p_path);
 	static void add_global_class(const StringName &p_class, const StringName &p_base, const StringName &p_language, const String &p_path);
 	static void remove_global_class(const StringName &p_class);
 	static void remove_global_class(const StringName &p_class);
+	static void remove_global_class_by_path(const String &p_path);
 	static bool is_global_class(const StringName &p_class);
 	static bool is_global_class(const StringName &p_class);
 	static StringName get_global_class_language(const StringName &p_class);
 	static StringName get_global_class_language(const StringName &p_class);
 	static String get_global_class_path(const String &p_class);
 	static String get_global_class_path(const String &p_class);

+ 0 - 6
doc/classes/EditorFileSystem.xml

@@ -71,12 +71,6 @@
 				This will not import the file. To reimport, call [method reimport_files] or [method scan] methods.
 				This will not import the file. To reimport, call [method reimport_files] or [method scan] methods.
 			</description>
 			</description>
 		</method>
 		</method>
-		<method name="update_script_classes">
-			<return type="void" />
-			<description>
-				Scans the script files and updates the list of custom class names.
-			</description>
-		</method>
 	</methods>
 	</methods>
 	<signals>
 	<signals>
 		<signal name="filesystem_changed">
 		<signal name="filesystem_changed">

+ 65 - 52
editor/editor_file_system.cpp

@@ -602,10 +602,19 @@ bool EditorFileSystem::_update_scan_actions() {
 
 
 				fs_changed = true;
 				fs_changed = true;
 
 
+				if (ClassDB::is_parent_class(ia.new_file->type, SNAME("Script"))) {
+					_queue_update_script_class(ia.dir->get_file_path(idx));
+				}
+
 			} break;
 			} break;
 			case ItemAction::ACTION_FILE_REMOVE: {
 			case ItemAction::ACTION_FILE_REMOVE: {
 				int idx = ia.dir->find_file_index(ia.file);
 				int idx = ia.dir->find_file_index(ia.file);
 				ERR_CONTINUE(idx == -1);
 				ERR_CONTINUE(idx == -1);
+
+				if (ClassDB::is_parent_class(ia.dir->files[idx]->type, SNAME("Script"))) {
+					_queue_update_script_class(ia.dir->get_file_path(idx));
+				}
+
 				_delete_internal_files(ia.dir->files[idx]->file);
 				_delete_internal_files(ia.dir->files[idx]->file);
 				memdelete(ia.dir->files[idx]);
 				memdelete(ia.dir->files[idx]);
 				ia.dir->files.remove_at(idx);
 				ia.dir->files.remove_at(idx);
@@ -640,6 +649,10 @@ bool EditorFileSystem::_update_scan_actions() {
 				ERR_CONTINUE(idx == -1);
 				ERR_CONTINUE(idx == -1);
 				String full_path = ia.dir->get_file_path(idx);
 				String full_path = ia.dir->get_file_path(idx);
 
 
+				if (ClassDB::is_parent_class(ia.dir->files[idx]->type, SNAME("Script"))) {
+					_queue_update_script_class(full_path);
+				}
+
 				reloads.push_back(full_path);
 				reloads.push_back(full_path);
 
 
 			} break;
 			} break;
@@ -710,7 +723,6 @@ void EditorFileSystem::scan() {
 		scanning = false;
 		scanning = false;
 		emit_signal(SNAME("filesystem_changed"));
 		emit_signal(SNAME("filesystem_changed"));
 		emit_signal(SNAME("sources_changed"), sources_changed.size() > 0);
 		emit_signal(SNAME("sources_changed"), sources_changed.size() > 0);
-		_queue_update_script_classes();
 		first_scan = false;
 		first_scan = false;
 	} else {
 	} else {
 		ERR_FAIL_COND(thread.is_started());
 		ERR_FAIL_COND(thread.is_started());
@@ -922,20 +934,6 @@ void EditorFileSystem::_scan_new_dir(EditorFileSystemDirectory *p_dir, Ref<DirAc
 			}
 			}
 		}
 		}
 
 
-		for (int i = 0; i < ScriptServer::get_language_count(); i++) {
-			ScriptLanguage *lang = ScriptServer::get_language(i);
-			if (lang->supports_documentation() && fi->type == lang->get_type()) {
-				Ref<Script> scr = ResourceLoader::load(path);
-				if (scr == nullptr) {
-					continue;
-				}
-				Vector<DocData::ClassDoc> docs = scr->get_documentation();
-				for (int j = 0; j < docs.size(); j++) {
-					EditorHelp::get_doc_data()->add_doc(docs[j]);
-				}
-			}
-		}
-
 		p_dir->files.push_back(fi);
 		p_dir->files.push_back(fi);
 		p_progress.update(idx, total);
 		p_progress.update(idx, total);
 	}
 	}
@@ -1229,7 +1227,6 @@ void EditorFileSystem::_notification(int p_what) {
 							emit_signal(SNAME("filesystem_changed"));
 							emit_signal(SNAME("filesystem_changed"));
 						}
 						}
 						emit_signal(SNAME("sources_changed"), sources_changed.size() > 0);
 						emit_signal(SNAME("sources_changed"), sources_changed.size() > 0);
-						_queue_update_script_classes();
 						first_scan = false;
 						first_scan = false;
 					}
 					}
 				} else if (!scanning && thread.is_started()) {
 				} else if (!scanning && thread.is_started()) {
@@ -1244,7 +1241,6 @@ void EditorFileSystem::_notification(int p_what) {
 					_update_scan_actions();
 					_update_scan_actions();
 					emit_signal(SNAME("filesystem_changed"));
 					emit_signal(SNAME("filesystem_changed"));
 					emit_signal(SNAME("sources_changed"), sources_changed.size() > 0);
 					emit_signal(SNAME("sources_changed"), sources_changed.size() > 0);
-					_queue_update_script_classes();
 					first_scan = false;
 					first_scan = false;
 				}
 				}
 
 
@@ -1491,39 +1487,50 @@ String EditorFileSystem::_get_global_script_class(const String &p_type, const St
 	return String();
 	return String();
 }
 }
 
 
-void EditorFileSystem::_scan_script_classes(EditorFileSystemDirectory *p_dir) {
-	int filecount = p_dir->files.size();
-	const EditorFileSystemDirectory::FileInfo *const *files = p_dir->files.ptr();
-	for (int i = 0; i < filecount; i++) {
-		if (files[i]->script_class_name.is_empty()) {
+void EditorFileSystem::_update_script_classes() {
+	update_script_mutex.lock();
+
+	for (const String &path : update_script_paths) {
+		ScriptServer::remove_global_class_by_path(path); // First remove, just in case it changed
+
+		int index = -1;
+		EditorFileSystemDirectory *efd = find_file(path, &index);
+
+		if (!efd || index < 0) {
+			// The file was removed
 			continue;
 			continue;
 		}
 		}
 
 
-		String lang;
-		for (int j = 0; j < ScriptServer::get_language_count(); j++) {
-			if (ScriptServer::get_language(j)->handles_global_class_type(files[i]->type)) {
-				lang = ScriptServer::get_language(j)->get_name();
+		if (!efd->files[index]->script_class_name.is_empty()) {
+			String lang;
+			for (int j = 0; j < ScriptServer::get_language_count(); j++) {
+				if (ScriptServer::get_language(j)->handles_global_class_type(efd->files[index]->type)) {
+					lang = ScriptServer::get_language(j)->get_name();
+				}
 			}
 			}
+
+			ScriptServer::add_global_class(efd->files[index]->script_class_name, efd->files[index]->script_class_extends, lang, path);
+			EditorNode::get_editor_data().script_class_set_icon_path(efd->files[index]->script_class_name, efd->files[index]->script_class_icon_path);
+			EditorNode::get_editor_data().script_class_set_name(efd->files[index]->file, efd->files[index]->script_class_name);
 		}
 		}
-		ScriptServer::add_global_class(files[i]->script_class_name, files[i]->script_class_extends, lang, p_dir->get_file_path(i));
-		EditorNode::get_editor_data().script_class_set_icon_path(files[i]->script_class_name, files[i]->script_class_icon_path);
-		EditorNode::get_editor_data().script_class_set_name(files[i]->file, files[i]->script_class_name);
-	}
-	for (int i = 0; i < p_dir->get_subdir_count(); i++) {
-		_scan_script_classes(p_dir->get_subdir(i));
-	}
-}
 
 
-void EditorFileSystem::update_script_classes() {
-	if (!update_script_classes_queued.is_set()) {
-		return;
+		for (int i = 0; i < ScriptServer::get_language_count(); i++) {
+			ScriptLanguage *lang = ScriptServer::get_language(i);
+			if (lang->supports_documentation() && efd->files[index]->type == lang->get_type()) {
+				Ref<Script> scr = ResourceLoader::load(path);
+				if (scr.is_null()) {
+					continue;
+				}
+				Vector<DocData::ClassDoc> docs = scr->get_documentation();
+				for (int j = 0; j < docs.size(); j++) {
+					EditorHelp::get_doc_data()->add_doc(docs[j]);
+				}
+			}
+		}
 	}
 	}
 
 
-	update_script_classes_queued.clear();
-	ScriptServer::global_classes_clear();
-	if (get_filesystem()) {
-		_scan_script_classes(get_filesystem());
-	}
+	update_script_paths.clear();
+	update_script_mutex.unlock();
 
 
 	ScriptServer::save_global_classes();
 	ScriptServer::save_global_classes();
 	EditorNode::get_editor_data().script_class_save_icon_paths();
 	EditorNode::get_editor_data().script_class_save_icon_paths();
@@ -1538,13 +1545,14 @@ void EditorFileSystem::update_script_classes() {
 	ResourceSaver::add_custom_savers();
 	ResourceSaver::add_custom_savers();
 }
 }
 
 
-void EditorFileSystem::_queue_update_script_classes() {
-	if (update_script_classes_queued.is_set()) {
-		return;
+void EditorFileSystem::_queue_update_script_class(const String &p_path) {
+	update_script_mutex.lock();
+	bool call_update = update_script_paths.is_empty();
+	update_script_paths.insert(p_path);
+	update_script_mutex.unlock();
+	if (call_update) {
+		call_deferred(SNAME("_update_script_classes"));
 	}
 	}
-
-	update_script_classes_queued.set();
-	call_deferred(SNAME("update_script_classes"));
 }
 }
 
 
 void EditorFileSystem::update_file(const String &p_file) {
 void EditorFileSystem::update_file(const String &p_file) {
@@ -1566,12 +1574,15 @@ void EditorFileSystem::update_file(const String &p_file) {
 					ResourceUID::get_singleton()->remove_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);
+			}
+
 			memdelete(fs->files[cpos]);
 			memdelete(fs->files[cpos]);
 			fs->files.remove_at(cpos);
 			fs->files.remove_at(cpos);
 		}
 		}
 
 
 		call_deferred(SNAME("emit_signal"), "filesystem_changed"); //update later
 		call_deferred(SNAME("emit_signal"), "filesystem_changed"); //update later
-		_queue_update_script_classes();
 		return;
 		return;
 	}
 	}
 
 
@@ -1631,8 +1642,11 @@ void EditorFileSystem::update_file(const String &p_file) {
 	// Update preview
 	// Update preview
 	EditorResourcePreview::get_singleton()->check_for_invalidation(p_file);
 	EditorResourcePreview::get_singleton()->check_for_invalidation(p_file);
 
 
+	if (ClassDB::is_parent_class(fs->files[cpos]->type, SNAME("Script"))) {
+		_queue_update_script_class(p_file);
+	}
+
 	call_deferred(SNAME("emit_signal"), "filesystem_changed"); //update later
 	call_deferred(SNAME("emit_signal"), "filesystem_changed"); //update later
-	_queue_update_script_classes();
 }
 }
 
 
 HashSet<String> EditorFileSystem::get_valid_extensions() const {
 HashSet<String> EditorFileSystem::get_valid_extensions() const {
@@ -2414,7 +2428,7 @@ void EditorFileSystem::_bind_methods() {
 	ClassDB::bind_method(D_METHOD("update_file", "path"), &EditorFileSystem::update_file);
 	ClassDB::bind_method(D_METHOD("update_file", "path"), &EditorFileSystem::update_file);
 	ClassDB::bind_method(D_METHOD("get_filesystem_path", "path"), &EditorFileSystem::get_filesystem_path);
 	ClassDB::bind_method(D_METHOD("get_filesystem_path", "path"), &EditorFileSystem::get_filesystem_path);
 	ClassDB::bind_method(D_METHOD("get_file_type", "path"), &EditorFileSystem::get_file_type);
 	ClassDB::bind_method(D_METHOD("get_file_type", "path"), &EditorFileSystem::get_file_type);
-	ClassDB::bind_method(D_METHOD("update_script_classes"), &EditorFileSystem::update_script_classes);
+	ClassDB::bind_method(D_METHOD("_update_script_classes"), &EditorFileSystem::_update_script_classes);
 	ClassDB::bind_method(D_METHOD("reimport_files", "files"), &EditorFileSystem::reimport_files);
 	ClassDB::bind_method(D_METHOD("reimport_files", "files"), &EditorFileSystem::reimport_files);
 
 
 	ADD_SIGNAL(MethodInfo("filesystem_changed"));
 	ADD_SIGNAL(MethodInfo("filesystem_changed"));
@@ -2474,7 +2488,6 @@ EditorFileSystem::EditorFileSystem() {
 	using_fat32_or_exfat = (da->get_filesystem_type() == "FAT32" || da->get_filesystem_type() == "exFAT");
 	using_fat32_or_exfat = (da->get_filesystem_type() == "FAT32" || da->get_filesystem_type() == "exFAT");
 
 
 	scan_total = 0;
 	scan_total = 0;
-	update_script_classes_queued.clear();
 	MessageQueue::get_singleton()->push_callable(callable_mp(ResourceUID::get_singleton(), &ResourceUID::clear)); // Will be updated on scan.
 	MessageQueue::get_singleton()->push_callable(callable_mp(ResourceUID::get_singleton(), &ResourceUID::clear)); // Will be updated on scan.
 	ResourceSaver::set_get_resource_id_for_path(_resource_saver_get_resource_id_for_path);
 	ResourceSaver::set_get_resource_id_for_path(_resource_saver_get_resource_id_for_path);
 }
 }

+ 4 - 5
editor/editor_file_system.h

@@ -257,9 +257,10 @@ class EditorFileSystem : public Node {
 		}
 		}
 	};
 	};
 
 
-	void _scan_script_classes(EditorFileSystemDirectory *p_dir);
-	SafeFlag update_script_classes_queued;
-	void _queue_update_script_classes();
+	Mutex update_script_mutex;
+	HashSet<String> update_script_paths;
+	void _queue_update_script_class(const String &p_path);
+	void _update_script_classes();
 
 
 	String _get_global_script_class(const String &p_type, const String &p_path, String *r_extends, String *r_icon_path) const;
 	String _get_global_script_class(const String &p_type, const String &p_path, String *r_extends, String *r_icon_path) const;
 
 
@@ -312,8 +313,6 @@ public:
 
 
 	void reimport_file_with_custom_parameters(const String &p_file, const String &p_importer, const HashMap<StringName, Variant> &p_custom_params);
 	void reimport_file_with_custom_parameters(const String &p_file, const String &p_importer, const HashMap<StringName, Variant> &p_custom_params);
 
 
-	void update_script_classes();
-
 	bool is_group_file(const String &p_path) const;
 	bool is_group_file(const String &p_path) const;
 	void move_group_file(const String &p_path, const String &p_new_path);
 	void move_group_file(const String &p_path, const String &p_new_path);
 
 

+ 2 - 1
editor/plugins/script_editor_plugin.cpp

@@ -2174,6 +2174,8 @@ Error ScriptEditor::_save_text_file(Ref<TextFile> p_text_file, const String &p_p
 		p_text_file->set_last_modified_time(FileAccess::get_modified_time(p_path));
 		p_text_file->set_last_modified_time(FileAccess::get_modified_time(p_path));
 	}
 	}
 
 
+	EditorFileSystem::get_singleton()->update_file(p_path);
+
 	_res_saved_callback(sqscr);
 	_res_saved_callback(sqscr);
 	return OK;
 	return OK;
 }
 }
@@ -2492,7 +2494,6 @@ void ScriptEditor::save_all_scripts() {
 	}
 	}
 
 
 	_update_script_names();
 	_update_script_names();
-	EditorFileSystem::get_singleton()->update_script_classes();
 }
 }
 
 
 void ScriptEditor::apply_scripts() const {
 void ScriptEditor::apply_scripts() const {