diff options
author | Rémi Verschelde <rverschelde@gmail.com> | 2024-01-11 17:34:19 +0100 |
---|---|---|
committer | Rémi Verschelde <rverschelde@gmail.com> | 2024-01-11 17:34:19 +0100 |
commit | f3fc35eb1756496e81bf0eb3a086494aa2271cf0 (patch) | |
tree | 05d89fae0e16dcab1fa06ac554747bd7b7bbe29c /scene/main/node.cpp | |
parent | 352434668923978f54f2236f20116fc96ebc9173 (diff) | |
parent | b4aa6ad36eb1d523eb5eef41f8572ea654ac0745 (diff) | |
download | redot-engine-f3fc35eb1756496e81bf0eb3a086494aa2271cf0.tar.gz |
Merge pull request #81506 from twobitadder/reparent_keep_owner
Fix `reparent()` losing owner
Diffstat (limited to 'scene/main/node.cpp')
-rw-r--r-- | scene/main/node.cpp | 34 |
1 files changed, 33 insertions, 1 deletions
diff --git a/scene/main/node.cpp b/scene/main/node.cpp index 1dd3b8bd1b..a6b7ca8188 100644 --- a/scene/main/node.cpp +++ b/scene/main/node.cpp @@ -1736,8 +1736,40 @@ void Node::reparent(Node *p_parent, bool p_keep_global_transform) { return; } + bool preserve_owner = data.owner && (data.owner == p_parent || data.owner->is_ancestor_of(p_parent)); + Node *owner_temp = data.owner; + LocalVector<Node *> common_parents; + + // If the new parent is related to the owner, find all children of the reparented node who have the same owner so that we can reassign them. + if (preserve_owner) { + LocalVector<Node *> to_visit; + + to_visit.push_back(this); + common_parents.push_back(this); + + while (to_visit.size() > 0) { + Node *check = to_visit[to_visit.size() - 1]; + to_visit.resize(to_visit.size() - 1); + + for (int i = 0; i < check->get_child_count(); i++) { + Node *child = check->get_child(i, false); + to_visit.push_back(child); + if (child->data.owner == owner_temp) { + common_parents.push_back(child); + } + } + } + } + data.parent->remove_child(this); p_parent->add_child(this); + + // Reassign the old owner to those found nodes. + if (preserve_owner) { + for (Node *E : common_parents) { + E->set_owner(owner_temp); + } + } } Node *Node::get_parent() const { @@ -1925,7 +1957,7 @@ void Node::set_owner(Node *p_owner) { return; } - Node *check = this->get_parent(); + Node *check = get_parent(); bool owner_valid = false; while (check) { |