2
0
Эх сурвалжийг харах

Fix wrong children range when duplicating node

kobewi 2 сар өмнө
parent
commit
258062e312

+ 5 - 5
scene/main/node.cpp

@@ -3000,18 +3000,18 @@ Node *Node::_duplicate(int p_flags, HashMap<const Node *, Node *> *r_duplimap) c
 	}
 
 	for (int i = 0; i < get_child_count(false); i++) {
-		if (instantiated && get_child(i)->data.owner == this) {
+		if (instantiated && get_child(i, false)->data.owner == this) {
 			continue; //part of instance
 		}
 
-		Node *dup = get_child(i)->_duplicate(p_flags, r_duplimap);
+		Node *dup = get_child(i, false)->_duplicate(p_flags, r_duplimap);
 		if (!dup) {
 			memdelete(node);
 			return nullptr;
 		}
 
 		node->add_child(dup);
-		if (i < node->get_child_count() - 1) {
+		if (i < node->get_child_count(false) - 1) {
 			node->move_child(dup, i);
 		}
 	}
@@ -3030,9 +3030,9 @@ Node *Node::_duplicate(int p_flags, HashMap<const Node *, Node *> *r_duplimap) c
 		}
 
 		parent->add_child(dup);
-		int pos = E->get_index();
+		int pos = E->get_index(false);
 
-		if (pos < parent->get_child_count() - 1) {
+		if (pos < parent->get_child_count(false) - 1) {
 			parent->move_child(dup, pos);
 		}
 	}

+ 28 - 3
tests/scene/test_node.h

@@ -96,6 +96,13 @@ public:
 
 	void set_exported_nodes(const Array &p_nodes) { exported_nodes = p_nodes; }
 	Array get_exported_nodes() const { return exported_nodes; }
+
+	TestNode() {
+		Node *internal = memnew(Node);
+		add_child(internal, false, INTERNAL_MODE_FRONT);
+		internal = memnew(Node);
+		add_child(internal, false, INTERNAL_MODE_BACK);
+	}
 };
 
 TEST_CASE("[SceneTree][Node] Testing node operations with a very simple scene tree") {
@@ -498,6 +505,24 @@ TEST_CASE("[SceneTree][Node] Testing node operations with a more complex simple
 	memdelete(node2);
 }
 
+TEST_CASE("[SceneTree][Node] Duplicating node with internal children") {
+	GDREGISTER_CLASS(TestNode);
+
+	TestNode *node = memnew(TestNode);
+	Node *child = memnew(Node);
+	child->set_name("Child");
+	node->add_child(child);
+
+	int child_count = node->get_child_count();
+
+	Node *dup = node->duplicate();
+	CHECK(dup->get_child_count() == child_count);
+	CHECK(dup->has_node(String("Child")));
+
+	memdelete(node);
+	memdelete(dup);
+}
+
 TEST_CASE("[SceneTree][Node]Exported node checks") {
 	TestNode *node = memnew(TestNode);
 	SceneTree::get_singleton()->get_root()->add_child(node);
@@ -523,7 +548,7 @@ TEST_CASE("[SceneTree][Node]Exported node checks") {
 
 		TestNode *dup = Object::cast_to<TestNode>(node->duplicate());
 		Node *new_exported = Object::cast_to<Node>(dup->get("exported_node"));
-		CHECK(new_exported == dup->get_child(0));
+		CHECK(new_exported == dup->get_child(0, false));
 
 		memdelete(dup);
 	}
@@ -578,10 +603,10 @@ TEST_CASE("[SceneTree][Node]Exported node checks") {
 		root->add_child(sub_child);
 		sub_child->set_owner(root);
 
-		sub_child->set("exported_node", sub_child->get_child(1));
+		sub_child->set("exported_node", sub_child->get_child(1, false));
 
 		children = Array();
-		children.append(sub_child->get_child(1));
+		children.append(sub_child->get_child(1, false));
 		sub_child->set("exported_nodes", children);
 
 		Ref<PackedScene> ps2;