From 06296369434a2ffe17f8d3103522f85b339a0dc0 Mon Sep 17 00:00:00 2001 From: Alexander Montag Date: Sun, 29 Sep 2024 02:40:31 +0200 Subject: [PATCH] Improve TreeSearch performance. This commit vastly improves performance by not updating the tree for search mask. From this commit onward, we are in very unstable territory. Relates to: https://github.com/limbonaut/limboai/pull/229 --- editor/task_tree.cpp | 4 +-- editor/tree_search.cpp | 71 ++++++++++++++++++++++-------------------- editor/tree_search.h | 4 ++- 3 files changed, 42 insertions(+), 37 deletions(-) diff --git a/editor/task_tree.cpp b/editor/task_tree.cpp index 7a4c5bc7..a976ca0a 100644 --- a/editor/task_tree.cpp +++ b/editor/task_tree.cpp @@ -538,8 +538,8 @@ void TaskTree::_notification(int p_what) { tree->connect("multi_selected", callable_mp(this, &TaskTree::_on_item_selected).unbind(3), CONNECT_DEFERRED); tree->connect("item_activated", callable_mp(this, &TaskTree::_on_item_activated)); tree->connect("item_collapsed", callable_mp(this, &TaskTree::_on_item_collapsed)); - tree_search_panel->connect("update_requested", callable_mp(this, &TaskTree::_update_tree)); - tree_search_panel->connect("visibility_changed", callable_mp(this, &TaskTree::_update_tree)); + tree_search_panel->connect("update_requested", callable_mp(tree_search.ptr(), &TreeSearch::update_search).bind(tree)); + tree_search_panel->connect("visibility_changed", callable_mp(tree_search.ptr(), &TreeSearch::update_search).bind(tree)); } break; case NOTIFICATION_THEME_CHANGED: { _do_update_theme_item_cache(); diff --git a/editor/tree_search.cpp b/editor/tree_search.cpp index 3fafd38c..e862c384 100644 --- a/editor/tree_search.cpp +++ b/editor/tree_search.cpp @@ -63,40 +63,47 @@ void TreeSearch::_filter_tree(const String &p_search_mask) { } } -void TreeSearch::_highlight_tree(const String &p_search_mask) { - callable_cache.clear(); +void TreeSearch::_highlight_tree() { for (int i = 0; i < ordered_tree_items.size(); i++) { - TreeItem *entry = ordered_tree_items[i]; - - int num_m = number_matches.has(entry) ? number_matches.get(entry) : 0; - if (num_m == 0) { - continue; - } - - // make sure to also call any draw method already defined. - Callable parent_draw_method; - if (entry->get_cell_mode(0) == TreeItem::CELL_MODE_CUSTOM) { - parent_draw_method = entry->get_custom_draw_callback(0); - } + TreeItem *tree_item = ordered_tree_items[i]; + _highlight_tree_item(tree_item); + } +} - Callable draw_callback = callable_mp(this, &TreeSearch::_draw_highlight_item).bind(parent_draw_method); +void TreeSearch::_highlight_tree_item(TreeItem *p_tree_item) { + int num_m = number_matches.has(p_tree_item) ? number_matches.get(p_tree_item) : 0; + if (num_m == 0 && !callable_cache.has(p_tree_item)) { + return; + } - // -- this is necessary because of the modularity of this implementation - // cache render properties of entry - String cached_text = entry->get_text(0); - Ref cached_icon = entry->get_icon(0); - int cached_max_width = entry->get_icon_max_width(0); - callable_cache[entry] = draw_callback; + // make sure to also call any draw method already defined. + Callable parent_draw_method; + if (p_tree_item->get_cell_mode(0) == TreeItem::CELL_MODE_CUSTOM) { + parent_draw_method = p_tree_item->get_custom_draw_callback(0); + } - // this removes render properties in entry - entry->set_custom_draw_callback(0, draw_callback); - entry->set_cell_mode(0, TreeItem::CELL_MODE_CUSTOM); + Callable draw_callback = callable_mp(this, &TreeSearch::_draw_highlight_item).bind(parent_draw_method); - // restore render properties - entry->set_text(0, cached_text); - entry->set_icon(0, cached_icon); - entry->set_icon_max_width(0, cached_max_width); + // make sure we don't create deep callable chains. + if (callable_cache.has(p_tree_item) && parent_draw_method == callable_cache.get(p_tree_item)) { + draw_callback = callable_cache.get(p_tree_item); } + + // -- this is necessary because of the modularity of this implementation + // cache render properties of entry + String cached_text = p_tree_item->get_text(0); + Ref cached_icon = p_tree_item->get_icon(0); + int cached_max_width = p_tree_item->get_icon_max_width(0); + callable_cache[p_tree_item] = draw_callback; + + // this removes render properties in entry + p_tree_item->set_custom_draw_callback(0, draw_callback); + p_tree_item->set_cell_mode(0, TreeItem::CELL_MODE_CUSTOM); + + // restore render properties + p_tree_item->set_text(0, cached_text); + p_tree_item->set_icon(0, cached_icon); + p_tree_item->set_icon_max_width(0, cached_max_width); } // custom draw callback for highlighting (bind the parent_drw_method to this) @@ -354,12 +361,7 @@ void TreeSearch::notify_item_edited(TreeItem *item) { if (item->get_cell_mode(0) != TreeItem::CELL_MODE_CUSTOM) { return; } - - if (!callable_cache.has(item) || item->get_custom_draw_callback(0) == callable_cache.get(item)) { - return; - } - - item->set_custom_draw_callback(0, callable_cache.get(item)); + _highlight_tree_item(item); } // Call this as a post-processing step for the already constructed tree. @@ -385,6 +387,7 @@ void TreeSearch::update_search(Tree *p_tree) { if (search_mode == TreeSearchMode::FILTER) { _filter_tree(search_mask); } + } TreeSearch::TreeSearch(TreeSearchPanel *p_search_panel) { diff --git a/editor/tree_search.h b/editor/tree_search.h index 3c1174ea..4a343b51 100644 --- a/editor/tree_search.h +++ b/editor/tree_search.h @@ -60,7 +60,9 @@ class TreeSearch : public RefCounted { // Update_search() calls these void _filter_tree(const String &p_search_mask); - void _highlight_tree(const String &p_search_mask); + void _highlight_tree(); + + void _highlight_tree_item(TreeItem *p_tree_item); // Custom draw-Callback (bind inherited Callable). void _draw_highlight_item(TreeItem *p_tree_item, Rect2 p_rect, Callable p_parent_draw_method);