Skip to content

Commit

Permalink
Improve TreeSearch performance.
Browse files Browse the repository at this point in the history
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: limbonaut#229
  • Loading branch information
monxa committed Sep 29, 2024
1 parent cb163eb commit 0629636
Show file tree
Hide file tree
Showing 3 changed files with 42 additions and 37 deletions.
4 changes: 2 additions & 2 deletions editor/task_tree.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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();
Expand Down
71 changes: 37 additions & 34 deletions editor/tree_search.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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<Texture2D> 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<Texture2D> 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)
Expand Down Expand Up @@ -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.
Expand All @@ -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) {
Expand Down
4 changes: 3 additions & 1 deletion editor/tree_search.h
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down

0 comments on commit 0629636

Please sign in to comment.