Browse Source

Merge pull request #33387 from nekomatata/faster-create-dialog-filter

Node create dialog filtering optimization
Rémi Verschelde 5 years ago
parent
commit
74c4543c4b
4 changed files with 33 additions and 11 deletions
  1. 18 3
      editor/create_dialog.cpp
  2. 1 0
      editor/create_dialog.h
  3. 12 8
      editor/editor_data.cpp
  4. 2 0
      editor/editor_data.h

+ 18 - 3
editor/create_dialog.cpp

@@ -151,6 +151,10 @@ void CreateDialog::add_type(const String &p_type, HashMap<String, TreeItem *> &p
 		if (!ClassDB::is_parent_class(p_type, base_type))
 			return;
 	} else {
+		if (!search_loaded_scripts.has(p_type)) {
+			search_loaded_scripts[p_type] = ed.script_class_load_script(p_type);
+		}
+
 		if (!ScriptServer::is_global_class(p_type) || !ed.script_class_is_parent(p_type, base_type))
 			return;
 
@@ -352,7 +356,12 @@ void CreateDialog::_update_search() {
 		} else {
 
 			bool found = false;
-			String type2 = I->get();
+			String type2 = type;
+
+			if (!cpp_type && !search_loaded_scripts.has(type)) {
+				search_loaded_scripts[type] = ed.script_class_load_script(type);
+			}
+
 			while (type2 != "" && (cpp_type ? ClassDB::is_parent_class(type2, base_type) : ed.script_class_is_parent(type2, base_type)) && type2 != base_type) {
 				if (search_box->get_text().is_subsequence_ofi(type2)) {
 
@@ -361,10 +370,15 @@ void CreateDialog::_update_search() {
 				}
 
 				type2 = cpp_type ? ClassDB::get_parent_class(type2) : ed.script_class_get_base(type2);
+
+				if (!cpp_type && !search_loaded_scripts.has(type2)) {
+					search_loaded_scripts[type2] = ed.script_class_load_script(type2);
+				}
 			}
 
-			if (found)
-				add_type(I->get(), search_options_types, root, &to_select);
+			if (found) {
+				add_type(type, search_options_types, root, &to_select);
+			}
 		}
 
 		if (EditorNode::get_editor_data().get_custom_types().has(type) && ClassDB::is_parent_class(type, base_type)) {
@@ -470,6 +484,7 @@ void CreateDialog::_notification(int p_what) {
 		} break;
 		case NOTIFICATION_POPUP_HIDE: {
 			EditorSettings::get_singleton()->get_project_metadata("dialog_bounds", "create_new_node", get_rect());
+			search_loaded_scripts.clear();
 		} break;
 	}
 }

+ 1 - 0
editor/create_dialog.h

@@ -51,6 +51,7 @@ class CreateDialog : public ConfirmationDialog {
 	LineEdit *search_box;
 	Tree *search_options;
 	HashMap<String, TreeItem *> search_options_types;
+	HashMap<String, RES> search_loaded_scripts;
 	bool is_replace_mode;
 	String base_type;
 	String preferred_search_result_type;

+ 12 - 8
editor/editor_data.cpp

@@ -870,7 +870,7 @@ bool EditorData::script_class_is_parent(const String &p_class, const String &p_i
 	if (!ScriptServer::is_global_class(p_class))
 		return false;
 	String base = script_class_get_base(p_class);
-	Ref<Script> script = ResourceLoader::load(ScriptServer::get_global_class_path(p_class), "Script");
+	Ref<Script> script = script_class_load_script(p_class);
 	Ref<Script> base_script = script->get_base_script();
 
 	while (p_inherits != base) {
@@ -889,12 +889,7 @@ bool EditorData::script_class_is_parent(const String &p_class, const String &p_i
 
 StringName EditorData::script_class_get_base(const String &p_class) const {
 
-	if (!ScriptServer::is_global_class(p_class))
-		return StringName();
-
-	String path = ScriptServer::get_global_class_path(p_class);
-
-	Ref<Script> script = ResourceLoader::load(path, "Script");
+	Ref<Script> script = script_class_load_script(p_class);
 	if (script.is_null())
 		return StringName();
 
@@ -910,7 +905,7 @@ Object *EditorData::script_class_instance(const String &p_class) {
 	if (ScriptServer::is_global_class(p_class)) {
 		Object *obj = ClassDB::instance(ScriptServer::get_global_class_native_base(p_class));
 		if (obj) {
-			RES script = ResourceLoader::load(ScriptServer::get_global_class_path(p_class));
+			Ref<Script> script = script_class_load_script(p_class);
 			if (script.is_valid())
 				obj->set_script(script.get_ref_ptr());
 			return obj;
@@ -919,6 +914,15 @@ Object *EditorData::script_class_instance(const String &p_class) {
 	return NULL;
 }
 
+Ref<Script> EditorData::script_class_load_script(const String &p_class) const {
+
+	if (!ScriptServer::is_global_class(p_class))
+		return Ref<Script>();
+
+	String path = ScriptServer::get_global_class_path(p_class);
+	return ResourceLoader::load(path, "Script");
+}
+
 void EditorData::script_class_set_icon_path(const String &p_class, const String &p_icon_path) {
 	_script_class_icon_paths[p_class] = p_icon_path;
 }

+ 2 - 0
editor/editor_data.h

@@ -219,6 +219,8 @@ public:
 	StringName script_class_get_base(const String &p_class) const;
 	Object *script_class_instance(const String &p_class);
 
+	Ref<Script> script_class_load_script(const String &p_class) const;
+
 	StringName script_class_get_name(const String &p_path) const;
 	void script_class_set_name(const String &p_path, const StringName &p_class);