summaryrefslogtreecommitdiff
path: root/scene/main
diff options
context:
space:
mode:
authorPedro J. Estébanez <pedrojrulez@gmail.com>2017-11-25 21:13:52 +0100
committerPedro J. Estébanez <pedrojrulez@gmail.com>2017-11-25 21:14:35 +0100
commit922cf9fbb0395417168b2e40c204384274ab1b77 (patch)
tree4dbcd6e6ff62c06f40eb814d2d4c8f62d07d45ff /scene/main
parent9738ebcda047fd9b4ddf71a0da5d682ade1a2666 (diff)
Fix crash on node duplication
That happened when an instanced scene was being duplicated while it also contained nodes added to it in the scene holding the instance. Plus: - Add comments about the logic behind all this. - Move the null guard to where it can protect the most, but consider it a runtime error rather that a situation we expect. Fixes #13282.
Diffstat (limited to 'scene/main')
-rw-r--r--scene/main/node.cpp12
1 files changed, 9 insertions, 3 deletions
diff --git a/scene/main/node.cpp b/scene/main/node.cpp
index 506dc85475..d8baa7834d 100644
--- a/scene/main/node.cpp
+++ b/scene/main/node.cpp
@@ -2114,8 +2114,16 @@ Node *Node::_duplicate(int p_flags, Map<const Node *, Node *> *r_duplimap) const
node_tree.push_front(this);
if (instanced) {
+ // Since nodes in the instanced hierarchy won't be duplicated explicitly, we need to make an inventory
+ // of all the nodes in the tree of the instanced scene in order to transfer the values of the properties
+
for (List<const Node *>::Element *N = node_tree.front(); N; N = N->next()) {
for (int i = 0; i < N->get()->get_child_count(); ++i) {
+
+ // Skip nodes not really belonging to the instanced hierarchy; they'll be processed normally later
+ if (get_child(i)->data.owner != this)
+ continue;
+
node_tree.push_back(N->get()->get_child(i));
}
}
@@ -2124,6 +2132,7 @@ Node *Node::_duplicate(int p_flags, Map<const Node *, Node *> *r_duplimap) const
for (List<const Node *>::Element *N = node_tree.front(); N; N = N->next()) {
Node *current_node = node->get_node(get_path_to(N->get()));
+ ERR_CONTINUE(!current_node);
if (p_flags & DUPLICATE_SCRIPTS) {
bool is_valid = false;
@@ -2136,9 +2145,6 @@ Node *Node::_duplicate(int p_flags, Map<const Node *, Node *> *r_duplimap) const
List<PropertyInfo> plist;
N->get()->get_property_list(&plist);
- if (!current_node)
- continue;
-
for (List<PropertyInfo>::Element *E = plist.front(); E; E = E->next()) {
if (!(E->get().usage & PROPERTY_USAGE_STORAGE))