test_packed_scene.h 9.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284
  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. #pragma once
  31. #include "scene/resources/packed_scene.h"
  32. #include "tests/test_macros.h"
  33. namespace TestPackedScene {
  34. TEST_CASE("[PackedScene] Pack Scene and Retrieve State") {
  35. // Create a scene to pack.
  36. Node *scene = memnew(Node);
  37. scene->set_name("TestScene");
  38. // Pack the scene.
  39. PackedScene packed_scene;
  40. const Error err = packed_scene.pack(scene);
  41. CHECK(err == OK);
  42. // Retrieve the packed state.
  43. Ref<SceneState> state = packed_scene.get_state();
  44. CHECK(state.is_valid());
  45. CHECK(state->get_node_count() == 1);
  46. CHECK(state->get_node_name(0) == "TestScene");
  47. memdelete(scene);
  48. }
  49. TEST_CASE("[PackedScene] Signals Preserved when Packing Scene") {
  50. // Create main scene
  51. // root
  52. // `- sub_node (local)
  53. // `- sub_scene (instance of another scene)
  54. // `- sub_scene_node (owned by sub_scene)
  55. Node *main_scene_root = memnew(Node);
  56. Node *sub_node = memnew(Node);
  57. Node *sub_scene_root = memnew(Node);
  58. Node *sub_scene_node = memnew(Node);
  59. main_scene_root->add_child(sub_node);
  60. sub_node->set_owner(main_scene_root);
  61. sub_scene_root->add_child(sub_scene_node);
  62. sub_scene_node->set_owner(sub_scene_root);
  63. main_scene_root->add_child(sub_scene_root);
  64. sub_scene_root->set_owner(main_scene_root);
  65. SUBCASE("Signals that should be saved") {
  66. int main_flags = Object::CONNECT_PERSIST;
  67. // sub node to a node in main scene
  68. sub_node->connect("ready", callable_mp(main_scene_root, &Node::is_ready), main_flags);
  69. // subscene root to a node in main scene
  70. sub_scene_root->connect("ready", callable_mp(main_scene_root, &Node::is_ready), main_flags);
  71. //subscene root to subscene root (connected within main scene)
  72. sub_scene_root->connect("ready", callable_mp(sub_scene_root, &Node::is_ready), main_flags);
  73. // Pack the scene.
  74. Ref<PackedScene> packed_scene;
  75. packed_scene.instantiate();
  76. const Error err = packed_scene->pack(main_scene_root);
  77. CHECK(err == OK);
  78. // Make sure the right connections are in packed scene.
  79. Ref<SceneState> state = packed_scene->get_state();
  80. CHECK_EQ(state->get_connection_count(), 3);
  81. }
  82. /*
  83. // FIXME: This subcase requires GH-48064 to be fixed.
  84. SUBCASE("Signals that should not be saved") {
  85. int subscene_flags = Object::CONNECT_PERSIST | Object::CONNECT_INHERITED;
  86. // subscene node to itself
  87. sub_scene_node->connect("ready", callable_mp(sub_scene_node, &Node::is_ready), subscene_flags);
  88. // subscene node to subscene root
  89. sub_scene_node->connect("ready", callable_mp(sub_scene_root, &Node::is_ready), subscene_flags);
  90. //subscene root to subscene root (connected within sub scene)
  91. sub_scene_root->connect("ready", callable_mp(sub_scene_root, &Node::is_ready), subscene_flags);
  92. // Pack the scene.
  93. Ref<PackedScene> packed_scene;
  94. packed_scene.instantiate();
  95. const Error err = packed_scene->pack(main_scene_root);
  96. CHECK(err == OK);
  97. // Make sure the right connections are in packed scene.
  98. Ref<SceneState> state = packed_scene->get_state();
  99. CHECK_EQ(state->get_connection_count(), 0);
  100. }
  101. */
  102. memdelete(main_scene_root);
  103. }
  104. TEST_CASE("[PackedScene] Clear Packed Scene") {
  105. // Create a scene to pack.
  106. Node *scene = memnew(Node);
  107. scene->set_name("TestScene");
  108. // Pack the scene.
  109. PackedScene packed_scene;
  110. packed_scene.pack(scene);
  111. // Clear the packed scene.
  112. packed_scene.clear();
  113. // Check if it has been cleared.
  114. Ref<SceneState> state = packed_scene.get_state();
  115. CHECK_FALSE(state->get_node_count() == 1);
  116. memdelete(scene);
  117. }
  118. TEST_CASE("[PackedScene] Can Instantiate Packed Scene") {
  119. // Create a scene to pack.
  120. Node *scene = memnew(Node);
  121. scene->set_name("TestScene");
  122. // Pack the scene.
  123. PackedScene packed_scene;
  124. packed_scene.pack(scene);
  125. // Check if the packed scene can be instantiated.
  126. const bool can_instantiate = packed_scene.can_instantiate();
  127. CHECK(can_instantiate == true);
  128. memdelete(scene);
  129. }
  130. TEST_CASE("[PackedScene] Instantiate Packed Scene") {
  131. // Create a scene to pack.
  132. Node *scene = memnew(Node);
  133. scene->set_name("TestScene");
  134. // Pack the scene.
  135. PackedScene packed_scene;
  136. packed_scene.pack(scene);
  137. // Instantiate the packed scene.
  138. Node *instance = packed_scene.instantiate();
  139. CHECK(instance != nullptr);
  140. CHECK(instance->get_name() == "TestScene");
  141. memdelete(scene);
  142. memdelete(instance);
  143. }
  144. TEST_CASE("[PackedScene] Instantiate Packed Scene With Children") {
  145. // Create a scene to pack.
  146. Node *scene = memnew(Node);
  147. scene->set_name("TestScene");
  148. // Add persisting child nodes to the scene.
  149. Node *child1 = memnew(Node);
  150. child1->set_name("Child1");
  151. scene->add_child(child1);
  152. child1->set_owner(scene);
  153. Node *child2 = memnew(Node);
  154. child2->set_name("Child2");
  155. scene->add_child(child2);
  156. child2->set_owner(scene);
  157. // Add non persisting child node to the scene.
  158. Node *child3 = memnew(Node);
  159. child3->set_name("Child3");
  160. scene->add_child(child3);
  161. // Pack the scene.
  162. PackedScene packed_scene;
  163. packed_scene.pack(scene);
  164. // Instantiate the packed scene.
  165. Node *instance = packed_scene.instantiate();
  166. CHECK(instance != nullptr);
  167. CHECK(instance->get_name() == "TestScene");
  168. // Validate the child nodes of the instantiated scene.
  169. CHECK(instance->get_child_count() == 2);
  170. CHECK(instance->get_child(0)->get_name() == "Child1");
  171. CHECK(instance->get_child(1)->get_name() == "Child2");
  172. CHECK(instance->get_child(0)->get_owner() == instance);
  173. CHECK(instance->get_child(1)->get_owner() == instance);
  174. memdelete(scene);
  175. memdelete(instance);
  176. }
  177. TEST_CASE("[PackedScene] Set Path") {
  178. // Create a scene to pack.
  179. Node *scene = memnew(Node);
  180. scene->set_name("TestScene");
  181. // Pack the scene.
  182. PackedScene packed_scene;
  183. packed_scene.pack(scene);
  184. // Set a new path for the packed scene.
  185. const String new_path = "NewTestPath";
  186. packed_scene.set_path(new_path);
  187. // Check if the path has been set correctly.
  188. Ref<SceneState> state = packed_scene.get_state();
  189. CHECK(state.is_valid());
  190. CHECK(state->get_path() == new_path);
  191. memdelete(scene);
  192. }
  193. TEST_CASE("[PackedScene] Replace State") {
  194. // Create a scene to pack.
  195. Node *scene = memnew(Node);
  196. scene->set_name("TestScene");
  197. // Pack the scene.
  198. PackedScene packed_scene;
  199. packed_scene.pack(scene);
  200. // Create another scene state to replace with.
  201. Ref<SceneState> new_state = memnew(SceneState);
  202. new_state->set_path("NewPath");
  203. // Replace the state.
  204. packed_scene.replace_state(new_state);
  205. // Check if the state has been replaced.
  206. Ref<SceneState> state = packed_scene.get_state();
  207. CHECK(state.is_valid());
  208. CHECK(state == new_state);
  209. memdelete(scene);
  210. }
  211. TEST_CASE("[PackedScene] Recreate State") {
  212. // Create a scene to pack.
  213. Node *scene = memnew(Node);
  214. scene->set_name("TestScene");
  215. // Pack the scene.
  216. PackedScene packed_scene;
  217. packed_scene.pack(scene);
  218. // Recreate the state.
  219. packed_scene.recreate_state();
  220. // Check if the state has been recreated.
  221. Ref<SceneState> state = packed_scene.get_state();
  222. CHECK(state.is_valid());
  223. CHECK(state->get_node_count() == 0); // Since the state was recreated, it should be empty.
  224. memdelete(scene);
  225. }
  226. } // namespace TestPackedScene