Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
godotengine
GitHub Repository: godotengine/godot
Path: blob/master/tests/scene/test_packed_scene.h
10277 views
1
/**************************************************************************/
2
/* test_packed_scene.h */
3
/**************************************************************************/
4
/* This file is part of: */
5
/* GODOT ENGINE */
6
/* https://godotengine.org */
7
/**************************************************************************/
8
/* Copyright (c) 2014-present Godot Engine contributors (see AUTHORS.md). */
9
/* Copyright (c) 2007-2014 Juan Linietsky, Ariel Manzur. */
10
/* */
11
/* Permission is hereby granted, free of charge, to any person obtaining */
12
/* a copy of this software and associated documentation files (the */
13
/* "Software"), to deal in the Software without restriction, including */
14
/* without limitation the rights to use, copy, modify, merge, publish, */
15
/* distribute, sublicense, and/or sell copies of the Software, and to */
16
/* permit persons to whom the Software is furnished to do so, subject to */
17
/* the following conditions: */
18
/* */
19
/* The above copyright notice and this permission notice shall be */
20
/* included in all copies or substantial portions of the Software. */
21
/* */
22
/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
23
/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
24
/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. */
25
/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
26
/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
27
/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
28
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
29
/**************************************************************************/
30
31
#pragma once
32
33
#include "scene/resources/packed_scene.h"
34
35
#include "tests/test_macros.h"
36
37
namespace TestPackedScene {
38
39
TEST_CASE("[PackedScene] Pack Scene and Retrieve State") {
40
// Create a scene to pack.
41
Node *scene = memnew(Node);
42
scene->set_name("TestScene");
43
44
// Pack the scene.
45
PackedScene packed_scene;
46
const Error err = packed_scene.pack(scene);
47
CHECK(err == OK);
48
49
// Retrieve the packed state.
50
Ref<SceneState> state = packed_scene.get_state();
51
CHECK(state.is_valid());
52
CHECK(state->get_node_count() == 1);
53
CHECK(state->get_node_name(0) == "TestScene");
54
55
memdelete(scene);
56
}
57
58
TEST_CASE("[PackedScene] Signals Preserved when Packing Scene") {
59
// Create main scene
60
// root
61
// `- sub_node (local)
62
// `- sub_scene (instance of another scene)
63
// `- sub_scene_node (owned by sub_scene)
64
Node *main_scene_root = memnew(Node);
65
Node *sub_node = memnew(Node);
66
Node *sub_scene_root = memnew(Node);
67
Node *sub_scene_node = memnew(Node);
68
69
main_scene_root->add_child(sub_node);
70
sub_node->set_owner(main_scene_root);
71
72
sub_scene_root->add_child(sub_scene_node);
73
sub_scene_node->set_owner(sub_scene_root);
74
75
main_scene_root->add_child(sub_scene_root);
76
sub_scene_root->set_owner(main_scene_root);
77
78
SUBCASE("Signals that should be saved") {
79
int main_flags = Object::CONNECT_PERSIST;
80
// sub node to a node in main scene
81
sub_node->connect("ready", callable_mp(main_scene_root, &Node::is_ready), main_flags);
82
// subscene root to a node in main scene
83
sub_scene_root->connect("ready", callable_mp(main_scene_root, &Node::is_ready), main_flags);
84
//subscene root to subscene root (connected within main scene)
85
sub_scene_root->connect("ready", callable_mp(sub_scene_root, &Node::is_ready), main_flags);
86
87
// Pack the scene.
88
Ref<PackedScene> packed_scene;
89
packed_scene.instantiate();
90
const Error err = packed_scene->pack(main_scene_root);
91
CHECK(err == OK);
92
93
// Make sure the right connections are in packed scene.
94
Ref<SceneState> state = packed_scene->get_state();
95
CHECK_EQ(state->get_connection_count(), 3);
96
}
97
98
/*
99
// FIXME: This subcase requires GH-48064 to be fixed.
100
SUBCASE("Signals that should not be saved") {
101
int subscene_flags = Object::CONNECT_PERSIST | Object::CONNECT_INHERITED;
102
// subscene node to itself
103
sub_scene_node->connect("ready", callable_mp(sub_scene_node, &Node::is_ready), subscene_flags);
104
// subscene node to subscene root
105
sub_scene_node->connect("ready", callable_mp(sub_scene_root, &Node::is_ready), subscene_flags);
106
//subscene root to subscene root (connected within sub scene)
107
sub_scene_root->connect("ready", callable_mp(sub_scene_root, &Node::is_ready), subscene_flags);
108
109
// Pack the scene.
110
Ref<PackedScene> packed_scene;
111
packed_scene.instantiate();
112
const Error err = packed_scene->pack(main_scene_root);
113
CHECK(err == OK);
114
115
// Make sure the right connections are in packed scene.
116
Ref<SceneState> state = packed_scene->get_state();
117
CHECK_EQ(state->get_connection_count(), 0);
118
}
119
*/
120
121
memdelete(main_scene_root);
122
}
123
124
TEST_CASE("[PackedScene] Clear Packed Scene") {
125
// Create a scene to pack.
126
Node *scene = memnew(Node);
127
scene->set_name("TestScene");
128
129
// Pack the scene.
130
PackedScene packed_scene;
131
packed_scene.pack(scene);
132
133
// Clear the packed scene.
134
packed_scene.clear();
135
136
// Check if it has been cleared.
137
Ref<SceneState> state = packed_scene.get_state();
138
CHECK_FALSE(state->get_node_count() == 1);
139
140
memdelete(scene);
141
}
142
143
TEST_CASE("[PackedScene] Can Instantiate Packed Scene") {
144
// Create a scene to pack.
145
Node *scene = memnew(Node);
146
scene->set_name("TestScene");
147
148
// Pack the scene.
149
PackedScene packed_scene;
150
packed_scene.pack(scene);
151
152
// Check if the packed scene can be instantiated.
153
const bool can_instantiate = packed_scene.can_instantiate();
154
CHECK(can_instantiate == true);
155
156
memdelete(scene);
157
}
158
159
TEST_CASE("[PackedScene] Instantiate Packed Scene") {
160
// Create a scene to pack.
161
Node *scene = memnew(Node);
162
scene->set_name("TestScene");
163
164
// Pack the scene.
165
PackedScene packed_scene;
166
packed_scene.pack(scene);
167
168
// Instantiate the packed scene.
169
Node *instance = packed_scene.instantiate();
170
CHECK(instance != nullptr);
171
CHECK(instance->get_name() == "TestScene");
172
173
memdelete(scene);
174
memdelete(instance);
175
}
176
177
TEST_CASE("[PackedScene] Instantiate Packed Scene With Children") {
178
// Create a scene to pack.
179
Node *scene = memnew(Node);
180
scene->set_name("TestScene");
181
182
// Add persisting child nodes to the scene.
183
Node *child1 = memnew(Node);
184
child1->set_name("Child1");
185
scene->add_child(child1);
186
child1->set_owner(scene);
187
188
Node *child2 = memnew(Node);
189
child2->set_name("Child2");
190
scene->add_child(child2);
191
child2->set_owner(scene);
192
193
// Add non persisting child node to the scene.
194
Node *child3 = memnew(Node);
195
child3->set_name("Child3");
196
scene->add_child(child3);
197
198
// Pack the scene.
199
PackedScene packed_scene;
200
packed_scene.pack(scene);
201
202
// Instantiate the packed scene.
203
Node *instance = packed_scene.instantiate();
204
CHECK(instance != nullptr);
205
CHECK(instance->get_name() == "TestScene");
206
207
// Validate the child nodes of the instantiated scene.
208
CHECK(instance->get_child_count() == 2);
209
CHECK(instance->get_child(0)->get_name() == "Child1");
210
CHECK(instance->get_child(1)->get_name() == "Child2");
211
CHECK(instance->get_child(0)->get_owner() == instance);
212
CHECK(instance->get_child(1)->get_owner() == instance);
213
214
memdelete(scene);
215
memdelete(instance);
216
}
217
218
TEST_CASE("[PackedScene] Set Path") {
219
// Create a scene to pack.
220
Node *scene = memnew(Node);
221
scene->set_name("TestScene");
222
223
// Pack the scene.
224
PackedScene packed_scene;
225
packed_scene.pack(scene);
226
227
// Set a new path for the packed scene.
228
const String new_path = "NewTestPath";
229
packed_scene.set_path(new_path);
230
231
// Check if the path has been set correctly.
232
Ref<SceneState> state = packed_scene.get_state();
233
CHECK(state.is_valid());
234
CHECK(state->get_path() == new_path);
235
236
memdelete(scene);
237
}
238
239
TEST_CASE("[PackedScene] Replace State") {
240
// Create a scene to pack.
241
Node *scene = memnew(Node);
242
scene->set_name("TestScene");
243
244
// Pack the scene.
245
PackedScene packed_scene;
246
packed_scene.pack(scene);
247
248
// Create another scene state to replace with.
249
Ref<SceneState> new_state = memnew(SceneState);
250
new_state->set_path("NewPath");
251
252
// Replace the state.
253
packed_scene.replace_state(new_state);
254
255
// Check if the state has been replaced.
256
Ref<SceneState> state = packed_scene.get_state();
257
CHECK(state.is_valid());
258
CHECK(state == new_state);
259
260
memdelete(scene);
261
}
262
263
TEST_CASE("[PackedScene] Recreate State") {
264
// Create a scene to pack.
265
Node *scene = memnew(Node);
266
scene->set_name("TestScene");
267
268
// Pack the scene.
269
PackedScene packed_scene;
270
packed_scene.pack(scene);
271
272
// Recreate the state.
273
packed_scene.recreate_state();
274
275
// Check if the state has been recreated.
276
Ref<SceneState> state = packed_scene.get_state();
277
CHECK(state.is_valid());
278
CHECK(state->get_node_count() == 0); // Since the state was recreated, it should be empty.
279
280
memdelete(scene);
281
}
282
283
} // namespace TestPackedScene
284
285