From af6a4f300e7abafebb65f0ffafac5f4ff19f85dc Mon Sep 17 00:00:00 2001 From: Marius Hanl Date: Fri, 22 Dec 2023 17:18:14 +0100 Subject: [PATCH] Improve performance of the 'Create New Node' dialog - Merged 3 for loops into 1 and save Vector allocation - Use get_instance_base_type() or get_global_name() instead of get_language()->get_global_class_name() for performance considerations - Use StringName where appropriate --- editor/create_dialog.cpp | 105 ++++++++++++++++----------------------- editor/create_dialog.h | 7 ++- 2 files changed, 47 insertions(+), 65 deletions(-) diff --git a/editor/create_dialog.cpp b/editor/create_dialog.cpp index d3174ed215d7..2b36b9254cca 100644 --- a/editor/create_dialog.cpp +++ b/editor/create_dialog.cpp @@ -85,7 +85,7 @@ void CreateDialog::_fill_type_list() { EditorData &ed = EditorNode::get_editor_data(); for (List::Element *I = complete_type_list.front(); I; I = I->next()) { - String type = I->get(); + StringName type = I->get(); if (!_should_hide_type(type)) { type_list.push_back(type); @@ -118,12 +118,12 @@ bool CreateDialog::_is_class_disabled_by_feature_profile(const StringName &p_cla return !profile.is_null() && profile->is_class_disabled(p_class); } -bool CreateDialog::_should_hide_type(const String &p_type) const { +bool CreateDialog::_should_hide_type(const StringName &p_type) const { if (_is_class_disabled_by_feature_profile(p_type)) { return true; } - if (is_base_type_node && p_type.begins_with("Editor")) { + if (is_base_type_node && p_type.operator String().begins_with("Editor")) { return true; // Do not show editor nodes. } @@ -146,12 +146,12 @@ bool CreateDialog::_should_hide_type(const String &p_type) const { } } } else { - if (!EditorNode::get_editor_data().script_class_is_parent(p_type, base_type)) { - return true; // Wrong inheritance. - } if (!ScriptServer::is_global_class(p_type)) { return true; } + if (!EditorNode::get_editor_data().script_class_is_parent(p_type, base_type)) { + return true; // Wrong inheritance. + } StringName native_type = ScriptServer::get_global_class_native_base(p_type); if (ClassDB::class_exists(native_type) && !ClassDB::can_instantiate(native_type)) { @@ -182,24 +182,30 @@ void CreateDialog::_update_search() { const String search_text = search_box->get_text(); bool empty_search = search_text.is_empty(); - // Filter all candidate results. - Vector candidates; + float highest_score = 0.0f; + StringName best_match; + for (List::Element *I = type_list.front(); I; I = I->next()) { - if (empty_search || search_text.is_subsequence_ofn(I->get())) { - candidates.push_back(I->get()); + StringName candidate = I->get(); + if (empty_search || search_text.is_subsequence_ofn(candidate)) { + _add_type(candidate, ClassDB::class_exists(candidate) ? TypeCategory::CPP_TYPE : TypeCategory::OTHER_TYPE); + + // Determine the best match for an non-empty search. + if (!empty_search) { + float score = _score_type(candidate.operator String().get_slicec(' ', 0), search_text); + if (score > highest_score) { + highest_score = score; + best_match = candidate; + } + } } } - // Build the type tree. - for (int i = 0; i < candidates.size(); i++) { - _add_type(candidates[i], ClassDB::class_exists(candidates[i]) ? TypeCategory::CPP_TYPE : TypeCategory::OTHER_TYPE); - } - // Select the best result. if (empty_search) { select_type(base_type); - } else if (candidates.size() > 0) { - select_type(_top_result(candidates, search_text)); + } else if (best_match != StringName()) { + select_type(best_match); } else { favorite->set_disabled(true); help_bit->set_custom_text(String(), String(), vformat(TTR("No results for \"%s\"."), search_text.replace("[", "[lb]"))); @@ -208,52 +214,43 @@ void CreateDialog::_update_search() { } } -void CreateDialog::_add_type(const String &p_type, const TypeCategory p_type_category) { +void CreateDialog::_add_type(const StringName &p_type, TypeCategory p_type_category) { if (search_options_types.has(p_type)) { return; } - String inherits; - TypeCategory inherited_type = TypeCategory::OTHER_TYPE; + StringName inherits; if (p_type_category == TypeCategory::CPP_TYPE) { inherits = ClassDB::get_parent_class(p_type); inherited_type = TypeCategory::CPP_TYPE; - } else if (p_type_category == TypeCategory::PATH_TYPE) { - ERR_FAIL_COND(!ResourceLoader::exists(p_type, "Script")); - Ref