mirror of
https://github.com/godotengine/godot.git
synced 2025-12-08 06:09:55 +00:00
Speed up deletion in large trees via the Scene Tree Dock
This commit is contained in:
parent
5950fca36c
commit
1ad3b9986e
4 changed files with 34 additions and 21 deletions
|
|
@ -770,20 +770,24 @@ void SceneTreeEditor::_node_script_changed(Node *p_node) {
|
||||||
|
|
||||||
void SceneTreeEditor::_move_node_children(HashMap<Node *, CachedNode>::Iterator &p_I) {
|
void SceneTreeEditor::_move_node_children(HashMap<Node *, CachedNode>::Iterator &p_I) {
|
||||||
TreeItem *item = p_I->value.item;
|
TreeItem *item = p_I->value.item;
|
||||||
|
TreeItem *previous_item = nullptr;
|
||||||
Node *node = p_I->key;
|
Node *node = p_I->key;
|
||||||
int cc = node->get_child_count(false);
|
int cc = node->get_child_count(false);
|
||||||
|
|
||||||
for (int i = 0; i < cc; i++) {
|
for (int i = 0; i < cc; i++) {
|
||||||
HashMap<Node *, CachedNode>::Iterator CI = node_cache.get(node->get_child(i, false));
|
HashMap<Node *, CachedNode>::Iterator CI = node_cache.get(node->get_child(i, false));
|
||||||
if (CI) {
|
if (CI) {
|
||||||
_move_node_item(item, CI);
|
_move_node_item(item, CI, previous_item);
|
||||||
|
previous_item = CI->value.item;
|
||||||
|
} else {
|
||||||
|
previous_item = nullptr;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
p_I->value.has_moved_children = false;
|
p_I->value.has_moved_children = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
void SceneTreeEditor::_move_node_item(TreeItem *p_parent, HashMap<Node *, CachedNode>::Iterator &p_I) {
|
void SceneTreeEditor::_move_node_item(TreeItem *p_parent, HashMap<Node *, CachedNode>::Iterator &p_I, TreeItem *p_correct_prev) {
|
||||||
if (!p_parent) {
|
if (!p_parent) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
@ -806,13 +810,19 @@ void SceneTreeEditor::_move_node_item(TreeItem *p_parent, HashMap<Node *, Cached
|
||||||
}
|
}
|
||||||
|
|
||||||
if (p_I->value.index != current_node_index) {
|
if (p_I->value.index != current_node_index) {
|
||||||
// If we just re-parented we know our index.
|
bool already_in_correct_location;
|
||||||
if (current_item_index == -1) {
|
if (current_item_index >= 0) {
|
||||||
current_item_index = item->get_index();
|
// If we just re-parented we know our index.
|
||||||
|
already_in_correct_location = current_item_index == current_node_index;
|
||||||
|
} else if (p_correct_prev) {
|
||||||
|
// It's cheaper to check if we're set up correctly by checking via correct_prev if we can
|
||||||
|
already_in_correct_location = item->get_prev() == p_correct_prev;
|
||||||
|
} else {
|
||||||
|
already_in_correct_location = item->get_index() == current_node_index;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Are we already in the right place?
|
// Are we already in the right place?
|
||||||
if (current_node_index == current_item_index) {
|
if (already_in_correct_location) {
|
||||||
p_I->value.index = current_node_index;
|
p_I->value.index = current_node_index;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
@ -820,11 +830,14 @@ void SceneTreeEditor::_move_node_item(TreeItem *p_parent, HashMap<Node *, Cached
|
||||||
// Are we the first node?
|
// Are we the first node?
|
||||||
if (current_node_index == 0) {
|
if (current_node_index == 0) {
|
||||||
// There has to be at least 1 other node, otherwise we would not have gotten here.
|
// There has to be at least 1 other node, otherwise we would not have gotten here.
|
||||||
TreeItem *neighbor_item = p_parent->get_child(0);
|
TreeItem *neighbor_item = p_parent->get_first_child();
|
||||||
item->move_before(neighbor_item);
|
item->move_before(neighbor_item);
|
||||||
} else {
|
} else {
|
||||||
TreeItem *neighbor_item = p_parent->get_child(CLAMP(current_node_index - 1, 0, p_parent->get_child_count() - 1));
|
TreeItem *prev_item = p_correct_prev;
|
||||||
item->move_after(neighbor_item);
|
if (!prev_item) {
|
||||||
|
prev_item = p_parent->get_child(CLAMP(current_node_index - 1, 0, p_parent->get_child_count() - 1));
|
||||||
|
}
|
||||||
|
item->move_after(prev_item);
|
||||||
}
|
}
|
||||||
|
|
||||||
p_I->value.index = current_node_index;
|
p_I->value.index = current_node_index;
|
||||||
|
|
|
||||||
|
|
@ -152,7 +152,7 @@ class SceneTreeEditor : public Control {
|
||||||
void _tree_process_mode_changed();
|
void _tree_process_mode_changed();
|
||||||
|
|
||||||
void _move_node_children(HashMap<Node *, CachedNode>::Iterator &p_I);
|
void _move_node_children(HashMap<Node *, CachedNode>::Iterator &p_I);
|
||||||
void _move_node_item(TreeItem *p_parent, HashMap<Node *, CachedNode>::Iterator &p_I);
|
void _move_node_item(TreeItem *p_parent, HashMap<Node *, CachedNode>::Iterator &p_I, TreeItem *p_correct_prev = nullptr);
|
||||||
|
|
||||||
void _node_child_order_changed(Node *p_node);
|
void _node_child_order_changed(Node *p_node);
|
||||||
void _node_editor_state_changed(Node *p_node);
|
void _node_editor_state_changed(Node *p_node);
|
||||||
|
|
|
||||||
|
|
@ -895,7 +895,7 @@ TreeItem *TreeItem::create_child(int p_index) {
|
||||||
} else {
|
} else {
|
||||||
int idx = 0;
|
int idx = 0;
|
||||||
if (!children_cache.is_empty()) {
|
if (!children_cache.is_empty()) {
|
||||||
idx = MIN(children_cache.size() - 1, p_index);
|
idx = MIN(int(children_cache.size()) - 1, p_index);
|
||||||
item_next = children_cache[idx];
|
item_next = children_cache[idx];
|
||||||
item_prev = item_next->prev;
|
item_prev = item_next->prev;
|
||||||
}
|
}
|
||||||
|
|
@ -920,7 +920,7 @@ TreeItem *TreeItem::create_child(int p_index) {
|
||||||
if (ti->next) {
|
if (ti->next) {
|
||||||
children_cache.insert(p_index, ti);
|
children_cache.insert(p_index, ti);
|
||||||
} else {
|
} else {
|
||||||
children_cache.append(ti);
|
children_cache.push_back(ti);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
|
@ -957,7 +957,7 @@ void TreeItem::add_child(TreeItem *p_item) {
|
||||||
last_child = p_item;
|
last_child = p_item;
|
||||||
|
|
||||||
if (!children_cache.is_empty()) {
|
if (!children_cache.is_empty()) {
|
||||||
children_cache.append(p_item);
|
children_cache.push_back(p_item);
|
||||||
}
|
}
|
||||||
|
|
||||||
validate_cache();
|
validate_cache();
|
||||||
|
|
@ -1111,15 +1111,15 @@ TreeItem *TreeItem::get_child(int p_index) {
|
||||||
if (p_index < 0) {
|
if (p_index < 0) {
|
||||||
p_index += children_cache.size();
|
p_index += children_cache.size();
|
||||||
}
|
}
|
||||||
ERR_FAIL_INDEX_V(p_index, children_cache.size(), nullptr);
|
ERR_FAIL_INDEX_V(p_index, (int)children_cache.size(), nullptr);
|
||||||
|
|
||||||
return children_cache.get(p_index);
|
return children_cache[p_index];
|
||||||
}
|
}
|
||||||
|
|
||||||
int TreeItem::get_visible_child_count() {
|
int TreeItem::get_visible_child_count() {
|
||||||
_create_children_cache();
|
_create_children_cache();
|
||||||
int visible_count = 0;
|
int visible_count = 0;
|
||||||
for (int i = 0; i < children_cache.size(); i++) {
|
for (uint32_t i = 0; i < children_cache.size(); i++) {
|
||||||
if (children_cache[i]->is_visible()) {
|
if (children_cache[i]->is_visible()) {
|
||||||
visible_count += 1;
|
visible_count += 1;
|
||||||
}
|
}
|
||||||
|
|
@ -1175,7 +1175,7 @@ void TreeItem::validate_cache() const {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
TreeItem *scan = parent->first_child;
|
TreeItem *scan = parent->first_child;
|
||||||
int index = 0;
|
uint32_t index = 0;
|
||||||
while (scan) {
|
while (scan) {
|
||||||
DEV_ASSERT(parent->children_cache[index] == scan);
|
DEV_ASSERT(parent->children_cache[index] == scan);
|
||||||
++index;
|
++index;
|
||||||
|
|
@ -1265,7 +1265,7 @@ void TreeItem::move_after(TreeItem *p_item) {
|
||||||
// If the cache is empty, it has not been built but there
|
// If the cache is empty, it has not been built but there
|
||||||
// are items in the tree (note p_item != nullptr,) so we cannot update it.
|
// are items in the tree (note p_item != nullptr,) so we cannot update it.
|
||||||
if (!parent->children_cache.is_empty()) {
|
if (!parent->children_cache.is_empty()) {
|
||||||
parent->children_cache.append(this);
|
parent->children_cache.push_back(this);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -150,7 +150,7 @@ private:
|
||||||
TreeItem *first_child = nullptr;
|
TreeItem *first_child = nullptr;
|
||||||
TreeItem *last_child = nullptr;
|
TreeItem *last_child = nullptr;
|
||||||
|
|
||||||
Vector<TreeItem *> children_cache;
|
LocalVector<TreeItem *> children_cache;
|
||||||
bool is_root = false; // For tree root.
|
bool is_root = false; // For tree root.
|
||||||
Tree *tree = nullptr; // Tree (for reference).
|
Tree *tree = nullptr; // Tree (for reference).
|
||||||
|
|
||||||
|
|
@ -169,7 +169,7 @@ private:
|
||||||
if (children_cache.is_empty()) {
|
if (children_cache.is_empty()) {
|
||||||
TreeItem *c = first_child;
|
TreeItem *c = first_child;
|
||||||
while (c) {
|
while (c) {
|
||||||
children_cache.append(c);
|
children_cache.push_back(c);
|
||||||
c = c->next;
|
c = c->next;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -201,7 +201,7 @@ private:
|
||||||
}
|
}
|
||||||
if (parent) {
|
if (parent) {
|
||||||
if (!parent->children_cache.is_empty()) {
|
if (!parent->children_cache.is_empty()) {
|
||||||
parent->children_cache.remove_at(get_index());
|
parent->children_cache.erase(this);
|
||||||
}
|
}
|
||||||
if (parent->first_child == this) {
|
if (parent->first_child == this) {
|
||||||
parent->first_child = next;
|
parent->first_child = next;
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue