Skip to content

Commit 1ad3b99

Browse files
committed
Speed up deletion in large trees via the Scene Tree Dock
1 parent 5950fca commit 1ad3b99

File tree

4 files changed

+34
-21
lines changed

4 files changed

+34
-21
lines changed

editor/scene/scene_tree_editor.cpp

Lines changed: 22 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -770,20 +770,24 @@ void SceneTreeEditor::_node_script_changed(Node *p_node) {
770770

771771
void SceneTreeEditor::_move_node_children(HashMap<Node *, CachedNode>::Iterator &p_I) {
772772
TreeItem *item = p_I->value.item;
773+
TreeItem *previous_item = nullptr;
773774
Node *node = p_I->key;
774775
int cc = node->get_child_count(false);
775776

776777
for (int i = 0; i < cc; i++) {
777778
HashMap<Node *, CachedNode>::Iterator CI = node_cache.get(node->get_child(i, false));
778779
if (CI) {
779-
_move_node_item(item, CI);
780+
_move_node_item(item, CI, previous_item);
781+
previous_item = CI->value.item;
782+
} else {
783+
previous_item = nullptr;
780784
}
781785
}
782786

783787
p_I->value.has_moved_children = false;
784788
}
785789

786-
void SceneTreeEditor::_move_node_item(TreeItem *p_parent, HashMap<Node *, CachedNode>::Iterator &p_I) {
790+
void SceneTreeEditor::_move_node_item(TreeItem *p_parent, HashMap<Node *, CachedNode>::Iterator &p_I, TreeItem *p_correct_prev) {
787791
if (!p_parent) {
788792
return;
789793
}
@@ -806,25 +810,34 @@ void SceneTreeEditor::_move_node_item(TreeItem *p_parent, HashMap<Node *, Cached
806810
}
807811

808812
if (p_I->value.index != current_node_index) {
809-
// If we just re-parented we know our index.
810-
if (current_item_index == -1) {
811-
current_item_index = item->get_index();
813+
bool already_in_correct_location;
814+
if (current_item_index >= 0) {
815+
// If we just re-parented we know our index.
816+
already_in_correct_location = current_item_index == current_node_index;
817+
} else if (p_correct_prev) {
818+
// It's cheaper to check if we're set up correctly by checking via correct_prev if we can
819+
already_in_correct_location = item->get_prev() == p_correct_prev;
820+
} else {
821+
already_in_correct_location = item->get_index() == current_node_index;
812822
}
813823

814824
// Are we already in the right place?
815-
if (current_node_index == current_item_index) {
825+
if (already_in_correct_location) {
816826
p_I->value.index = current_node_index;
817827
return;
818828
}
819829

820830
// Are we the first node?
821831
if (current_node_index == 0) {
822832
// There has to be at least 1 other node, otherwise we would not have gotten here.
823-
TreeItem *neighbor_item = p_parent->get_child(0);
833+
TreeItem *neighbor_item = p_parent->get_first_child();
824834
item->move_before(neighbor_item);
825835
} else {
826-
TreeItem *neighbor_item = p_parent->get_child(CLAMP(current_node_index - 1, 0, p_parent->get_child_count() - 1));
827-
item->move_after(neighbor_item);
836+
TreeItem *prev_item = p_correct_prev;
837+
if (!prev_item) {
838+
prev_item = p_parent->get_child(CLAMP(current_node_index - 1, 0, p_parent->get_child_count() - 1));
839+
}
840+
item->move_after(prev_item);
828841
}
829842

830843
p_I->value.index = current_node_index;

editor/scene/scene_tree_editor.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -152,7 +152,7 @@ class SceneTreeEditor : public Control {
152152
void _tree_process_mode_changed();
153153

154154
void _move_node_children(HashMap<Node *, CachedNode>::Iterator &p_I);
155-
void _move_node_item(TreeItem *p_parent, HashMap<Node *, CachedNode>::Iterator &p_I);
155+
void _move_node_item(TreeItem *p_parent, HashMap<Node *, CachedNode>::Iterator &p_I, TreeItem *p_correct_prev = nullptr);
156156

157157
void _node_child_order_changed(Node *p_node);
158158
void _node_editor_state_changed(Node *p_node);

scene/gui/tree.cpp

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -895,7 +895,7 @@ TreeItem *TreeItem::create_child(int p_index) {
895895
} else {
896896
int idx = 0;
897897
if (!children_cache.is_empty()) {
898-
idx = MIN(children_cache.size() - 1, p_index);
898+
idx = MIN(int(children_cache.size()) - 1, p_index);
899899
item_next = children_cache[idx];
900900
item_prev = item_next->prev;
901901
}
@@ -920,7 +920,7 @@ TreeItem *TreeItem::create_child(int p_index) {
920920
if (ti->next) {
921921
children_cache.insert(p_index, ti);
922922
} else {
923-
children_cache.append(ti);
923+
children_cache.push_back(ti);
924924
}
925925
}
926926
} else {
@@ -957,7 +957,7 @@ void TreeItem::add_child(TreeItem *p_item) {
957957
last_child = p_item;
958958

959959
if (!children_cache.is_empty()) {
960-
children_cache.append(p_item);
960+
children_cache.push_back(p_item);
961961
}
962962

963963
validate_cache();
@@ -1111,15 +1111,15 @@ TreeItem *TreeItem::get_child(int p_index) {
11111111
if (p_index < 0) {
11121112
p_index += children_cache.size();
11131113
}
1114-
ERR_FAIL_INDEX_V(p_index, children_cache.size(), nullptr);
1114+
ERR_FAIL_INDEX_V(p_index, (int)children_cache.size(), nullptr);
11151115

1116-
return children_cache.get(p_index);
1116+
return children_cache[p_index];
11171117
}
11181118

11191119
int TreeItem::get_visible_child_count() {
11201120
_create_children_cache();
11211121
int visible_count = 0;
1122-
for (int i = 0; i < children_cache.size(); i++) {
1122+
for (uint32_t i = 0; i < children_cache.size(); i++) {
11231123
if (children_cache[i]->is_visible()) {
11241124
visible_count += 1;
11251125
}
@@ -1175,7 +1175,7 @@ void TreeItem::validate_cache() const {
11751175
return;
11761176
}
11771177
TreeItem *scan = parent->first_child;
1178-
int index = 0;
1178+
uint32_t index = 0;
11791179
while (scan) {
11801180
DEV_ASSERT(parent->children_cache[index] == scan);
11811181
++index;
@@ -1265,7 +1265,7 @@ void TreeItem::move_after(TreeItem *p_item) {
12651265
// If the cache is empty, it has not been built but there
12661266
// are items in the tree (note p_item != nullptr,) so we cannot update it.
12671267
if (!parent->children_cache.is_empty()) {
1268-
parent->children_cache.append(this);
1268+
parent->children_cache.push_back(this);
12691269
}
12701270
}
12711271

scene/gui/tree.h

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -150,7 +150,7 @@ class TreeItem : public Object {
150150
TreeItem *first_child = nullptr;
151151
TreeItem *last_child = nullptr;
152152

153-
Vector<TreeItem *> children_cache;
153+
LocalVector<TreeItem *> children_cache;
154154
bool is_root = false; // For tree root.
155155
Tree *tree = nullptr; // Tree (for reference).
156156

@@ -169,7 +169,7 @@ class TreeItem : public Object {
169169
if (children_cache.is_empty()) {
170170
TreeItem *c = first_child;
171171
while (c) {
172-
children_cache.append(c);
172+
children_cache.push_back(c);
173173
c = c->next;
174174
}
175175
}
@@ -201,7 +201,7 @@ class TreeItem : public Object {
201201
}
202202
if (parent) {
203203
if (!parent->children_cache.is_empty()) {
204-
parent->children_cache.remove_at(get_index());
204+
parent->children_cache.erase(this);
205205
}
206206
if (parent->first_child == this) {
207207
parent->first_child = next;

0 commit comments

Comments
 (0)