BsEditorTestSuite.cpp 18 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660
  1. #include "BsEditorTestSuite.h"
  2. #include "BsSceneObject.h"
  3. #include "BsCmdRecordSO.h"
  4. #include "BsUndoRedo.h"
  5. #include "BsRTTIType.h"
  6. #include "BsGameObjectRTTI.h"
  7. #include "BsBinarySerializer.h"
  8. #include "BsMemorySerializer.h"
  9. #include "BsBinaryDiff.h"
  10. #include "BsPrefab.h"
  11. #include "BsResources.h"
  12. #include "BsPrefabDiff.h"
  13. namespace BansheeEngine
  14. {
  15. class TestComponentARTTI : public RTTIType<TestComponentA, Component, TestComponentARTTI>
  16. {
  17. private:
  18. HSceneObject& getRef1(TestComponentA* obj) { return obj->ref1; }
  19. void setRef1(TestComponentA* obj, HSceneObject& val) { obj->ref1 = val; }
  20. HComponent& getRef2(TestComponentA* obj) { return obj->ref2; }
  21. void setRef2(TestComponentA* obj, HComponent& val) { obj->ref2 = val; }
  22. public:
  23. TestComponentARTTI()
  24. {
  25. addReflectableField("ref1", 0, &TestComponentARTTI::getRef1, &TestComponentARTTI::setRef1);
  26. addReflectableField("ref2", 1, &TestComponentARTTI::getRef2, &TestComponentARTTI::setRef2);
  27. }
  28. virtual const String& getRTTIName()
  29. {
  30. static String name = "TestComponentA";
  31. return name;
  32. }
  33. virtual UINT32 getRTTIId()
  34. {
  35. return TID_TestComponentA;
  36. }
  37. virtual std::shared_ptr<IReflectable> newRTTIObject()
  38. {
  39. return GameObjectRTTI::createGameObject<TestComponentA>();
  40. }
  41. };
  42. class TestComponentBRTTI : public RTTIType<TestComponentB, Component, TestComponentBRTTI>
  43. {
  44. private:
  45. HSceneObject& getRef1(TestComponentB* obj) { return obj->ref1; }
  46. void setRef1(TestComponentB* obj, HSceneObject& val) { obj->ref1 = val; }
  47. String& getVal1(TestComponentB* obj) { return obj->val1; }
  48. void setVal1(TestComponentB* obj, String& val) { obj->val1 = val; }
  49. public:
  50. TestComponentBRTTI()
  51. {
  52. addReflectableField("ref1", 0, &TestComponentBRTTI::getRef1, &TestComponentBRTTI::setRef1);
  53. addPlainField("val1", 1, &TestComponentBRTTI::getVal1, &TestComponentBRTTI::setVal1);
  54. }
  55. virtual const String& getRTTIName()
  56. {
  57. static String name = "TestComponentB";
  58. return name;
  59. }
  60. virtual UINT32 getRTTIId()
  61. {
  62. return TID_TestComponentB;
  63. }
  64. virtual std::shared_ptr<IReflectable> newRTTIObject()
  65. {
  66. return GameObjectRTTI::createGameObject<TestComponentB>();
  67. }
  68. };
  69. TestComponentA::TestComponentA(const HSceneObject& parent)
  70. :Component(parent)
  71. {}
  72. RTTITypeBase* TestComponentA::getRTTIStatic()
  73. {
  74. return TestComponentARTTI::instance();
  75. }
  76. RTTITypeBase* TestComponentA::getRTTI() const
  77. {
  78. return TestComponentA::getRTTIStatic();
  79. }
  80. TestComponentB::TestComponentB(const HSceneObject& parent)
  81. :Component(parent)
  82. {}
  83. RTTITypeBase* TestComponentB::getRTTIStatic()
  84. {
  85. return TestComponentBRTTI::instance();
  86. }
  87. RTTITypeBase* TestComponentB::getRTTI() const
  88. {
  89. return TestComponentB::getRTTIStatic();
  90. }
  91. struct TestObjectB : IReflectable
  92. {
  93. UINT32 intA = 100;
  94. String strA = "100";
  95. /************************************************************************/
  96. /* RTTI */
  97. /************************************************************************/
  98. public:
  99. friend class TestObjectBRTTI;
  100. static RTTITypeBase* getRTTIStatic();
  101. virtual RTTITypeBase* getRTTI() const;
  102. };
  103. struct TestObjectA : IReflectable
  104. {
  105. TestObjectA()
  106. {
  107. arrStrA = { "10", "11", "12" };
  108. arrStrB = { "13", "14", "15" };
  109. arrStrC = { "16", "17", "18" };
  110. arrObjA = { TestObjectB(), TestObjectB(), TestObjectB() };
  111. arrObjB = { TestObjectB(), TestObjectB(), TestObjectB() };
  112. arrObjPtrA = { bs_shared_ptr<TestObjectB>(), bs_shared_ptr<TestObjectB>(), bs_shared_ptr<TestObjectB>() };
  113. arrObjPtrB = { bs_shared_ptr<TestObjectB>(), bs_shared_ptr<TestObjectB>(), bs_shared_ptr<TestObjectB>() };
  114. }
  115. UINT32 intA = 5;
  116. String strA = "5";
  117. String strB = "7";
  118. TestObjectB objA;
  119. TestObjectB objB;
  120. SPtr<TestObjectB> objPtrA = bs_shared_ptr<TestObjectB>();
  121. SPtr<TestObjectB> objPtrB = bs_shared_ptr<TestObjectB>();
  122. SPtr<TestObjectB> objPtrC = bs_shared_ptr<TestObjectB>();
  123. SPtr<TestObjectB> objPtrD = nullptr;
  124. Vector<String> arrStrA;
  125. Vector<String> arrStrB;
  126. Vector<String> arrStrC;
  127. Vector<TestObjectB> arrObjA;
  128. Vector<TestObjectB> arrObjB;
  129. Vector<SPtr<TestObjectB>> arrObjPtrA;
  130. Vector<SPtr<TestObjectB>> arrObjPtrB;
  131. /************************************************************************/
  132. /* RTTI */
  133. /************************************************************************/
  134. public:
  135. friend class TestObjectARTTI;
  136. static RTTITypeBase* getRTTIStatic();
  137. virtual RTTITypeBase* getRTTI() const;
  138. };
  139. class TestObjectARTTI : public RTTIType < TestObjectA, IReflectable, TestObjectARTTI >
  140. {
  141. private:
  142. BS_PLAIN_MEMBER(intA);
  143. BS_PLAIN_MEMBER(strA);
  144. BS_PLAIN_MEMBER(strB);
  145. BS_REFL_MEMBER(objA);
  146. BS_REFL_MEMBER(objB);
  147. BS_REFLPTR_MEMBER(objPtrA);
  148. BS_REFLPTR_MEMBER(objPtrB);
  149. BS_REFLPTR_MEMBER(objPtrC);
  150. BS_REFLPTR_MEMBER(objPtrD);
  151. BS_PLAIN_MEMBER_VEC(arrStrA);
  152. BS_PLAIN_MEMBER_VEC(arrStrB);
  153. BS_PLAIN_MEMBER_VEC(arrStrC);
  154. BS_REFL_MEMBER_VEC(arrObjA);
  155. BS_REFL_MEMBER_VEC(arrObjB);
  156. BS_REFLPTR_MEMBER_VEC(arrObjPtrA);
  157. BS_REFLPTR_MEMBER_VEC(arrObjPtrB);
  158. public:
  159. TestObjectARTTI()
  160. {
  161. BS_ADD_PLAIN_FIELD(intA, 0);
  162. BS_ADD_PLAIN_FIELD(strA, 1);
  163. BS_ADD_PLAIN_FIELD(strB, 2);
  164. BS_ADD_REFL_FIELD(objA, 3);
  165. BS_ADD_REFL_FIELD(objB, 4);
  166. BS_ADD_REFLPTR_FIELD(objPtrA, 5);
  167. BS_ADD_REFLPTR_FIELD(objPtrB, 6);
  168. BS_ADD_REFLPTR_FIELD(objPtrC, 7);
  169. BS_ADD_REFLPTR_FIELD(objPtrD, 8);
  170. BS_ADD_PLAIN_FIELD_ARR(arrStrA, 9);
  171. BS_ADD_PLAIN_FIELD_ARR(arrStrB, 10);
  172. BS_ADD_PLAIN_FIELD_ARR(arrStrC, 11);
  173. BS_ADD_REFL_FIELD_ARR(arrObjA, 12);
  174. BS_ADD_REFL_FIELD_ARR(arrObjB, 13);
  175. BS_ADD_REFLPTR_FIELD_ARR(arrObjPtrA, 14);
  176. BS_ADD_REFLPTR_FIELD_ARR(arrObjPtrB, 15);
  177. }
  178. virtual const String& getRTTIName()
  179. {
  180. static String name = "TestObjectA";
  181. return name;
  182. }
  183. virtual UINT32 getRTTIId()
  184. {
  185. return TID_TestObjectA;
  186. }
  187. virtual std::shared_ptr<IReflectable> newRTTIObject()
  188. {
  189. return bs_shared_ptr<TestObjectA>();
  190. }
  191. };
  192. class TestObjectBRTTI : public RTTIType < TestObjectB, IReflectable, TestObjectBRTTI >
  193. {
  194. private:
  195. BS_PLAIN_MEMBER(intA);
  196. BS_PLAIN_MEMBER(strA);
  197. public:
  198. TestObjectBRTTI()
  199. {
  200. BS_ADD_PLAIN_FIELD(intA, 0);
  201. BS_ADD_PLAIN_FIELD(strA, 1);
  202. }
  203. virtual const String& getRTTIName()
  204. {
  205. static String name = "TestObjectB";
  206. return name;
  207. }
  208. virtual UINT32 getRTTIId()
  209. {
  210. return TID_TestObjectB;
  211. }
  212. virtual std::shared_ptr<IReflectable> newRTTIObject()
  213. {
  214. return bs_shared_ptr<TestObjectB>();
  215. }
  216. };
  217. RTTITypeBase* TestObjectB::getRTTIStatic()
  218. {
  219. return TestObjectBRTTI::instance();
  220. }
  221. RTTITypeBase* TestObjectB::getRTTI() const
  222. {
  223. return TestObjectB::getRTTIStatic();
  224. }
  225. RTTITypeBase* TestObjectA::getRTTIStatic()
  226. {
  227. return TestObjectARTTI::instance();
  228. }
  229. RTTITypeBase* TestObjectA::getRTTI() const
  230. {
  231. return TestObjectA::getRTTIStatic();
  232. }
  233. class TestComponentC : public Component
  234. {
  235. public:
  236. TestObjectA obj;
  237. /************************************************************************/
  238. /* COMPONENT OVERRIDES */
  239. /************************************************************************/
  240. protected:
  241. friend class SceneObject;
  242. TestComponentC(const HSceneObject& parent)
  243. :Component(parent)
  244. {}
  245. /************************************************************************/
  246. /* RTTI */
  247. /************************************************************************/
  248. public:
  249. friend class TestComponentCRTTI;
  250. static RTTITypeBase* getRTTIStatic();
  251. virtual RTTITypeBase* getRTTI() const;
  252. protected:
  253. TestComponentC() {} // Serialization only
  254. };
  255. class TestComponentD : public Component
  256. {
  257. public:
  258. TestObjectB obj;
  259. /************************************************************************/
  260. /* COMPONENT OVERRIDES */
  261. /************************************************************************/
  262. protected:
  263. friend class SceneObject;
  264. TestComponentD(const HSceneObject& parent)
  265. :Component(parent)
  266. {}
  267. /************************************************************************/
  268. /* RTTI */
  269. /************************************************************************/
  270. public:
  271. friend class TestComponentDRTTI;
  272. static RTTITypeBase* getRTTIStatic();
  273. virtual RTTITypeBase* getRTTI() const;
  274. protected:
  275. TestComponentD() {} // Serialization only
  276. };
  277. class TestComponentCRTTI : public RTTIType < TestComponentC, Component, TestComponentCRTTI >
  278. {
  279. private:
  280. BS_REFL_MEMBER(obj)
  281. public:
  282. TestComponentCRTTI()
  283. {
  284. BS_ADD_REFL_FIELD(obj, 0);
  285. }
  286. virtual const String& getRTTIName()
  287. {
  288. static String name = "TestComponentC";
  289. return name;
  290. }
  291. virtual UINT32 getRTTIId()
  292. {
  293. return TID_TestComponentC;
  294. }
  295. virtual std::shared_ptr<IReflectable> newRTTIObject()
  296. {
  297. return GameObjectRTTI::createGameObject<TestComponentC>();
  298. }
  299. };
  300. class TestComponentDRTTI : public RTTIType < TestComponentD, Component, TestComponentDRTTI >
  301. {
  302. private:
  303. BS_REFL_MEMBER(obj)
  304. public:
  305. TestComponentDRTTI()
  306. {
  307. BS_ADD_REFL_FIELD(obj, 0);
  308. }
  309. virtual const String& getRTTIName()
  310. {
  311. static String name = "TestComponentD";
  312. return name;
  313. }
  314. virtual UINT32 getRTTIId()
  315. {
  316. return TID_TestComponentD;
  317. }
  318. virtual std::shared_ptr<IReflectable> newRTTIObject()
  319. {
  320. return GameObjectRTTI::createGameObject<TestComponentD>();
  321. }
  322. };
  323. RTTITypeBase* TestComponentC::getRTTIStatic()
  324. {
  325. return TestComponentCRTTI::instance();
  326. }
  327. RTTITypeBase* TestComponentC::getRTTI() const
  328. {
  329. return TestComponentC::getRTTIStatic();
  330. }
  331. RTTITypeBase* TestComponentD::getRTTIStatic()
  332. {
  333. return TestComponentDRTTI::instance();
  334. }
  335. RTTITypeBase* TestComponentD::getRTTI() const
  336. {
  337. return TestComponentD::getRTTIStatic();
  338. }
  339. EditorTestSuite::EditorTestSuite()
  340. {
  341. BS_ADD_TEST(EditorTestSuite::SceneObjectRecord_UndoRedo);
  342. BS_ADD_TEST(EditorTestSuite::BinaryDiff);
  343. BS_ADD_TEST(EditorTestSuite::TestPrefabDiff);
  344. }
  345. void EditorTestSuite::SceneObjectRecord_UndoRedo()
  346. {
  347. HSceneObject so0_0 = SceneObject::create("so0_0");
  348. HSceneObject so1_0 = SceneObject::create("so1_0");
  349. HSceneObject so1_1 = SceneObject::create("so1_1");
  350. HSceneObject so2_0 = SceneObject::create("so2_0");
  351. so1_0->setParent(so0_0);
  352. so1_1->setParent(so0_0);
  353. so2_0->setParent(so1_0);
  354. GameObjectHandle<TestComponentA> cmpA1_1 = so1_1->addComponent<TestComponentA>();
  355. GameObjectHandle<TestComponentB> cmpB1_1 = so1_1->addComponent<TestComponentB>();
  356. HSceneObject soExternal = SceneObject::create("soExternal");
  357. GameObjectHandle<TestComponentA> cmpExternal = soExternal->addComponent<TestComponentA>();
  358. cmpA1_1->ref1 = so2_0;
  359. cmpA1_1->ref2 = cmpB1_1;
  360. cmpB1_1->ref1 = soExternal;
  361. cmpB1_1->val1 = "InitialValue";
  362. cmpExternal->ref1 = so1_1;
  363. cmpExternal->ref2 = cmpA1_1;
  364. CmdRecordSO::execute(so0_0);
  365. cmpB1_1->val1 = "ModifiedValue";
  366. UndoRedo::instance().undo();
  367. BS_TEST_ASSERT(!so0_0.isDestroyed());
  368. BS_TEST_ASSERT(!so1_0.isDestroyed());
  369. BS_TEST_ASSERT(!so1_1.isDestroyed());
  370. BS_TEST_ASSERT(!so2_0.isDestroyed());
  371. BS_TEST_ASSERT(!cmpA1_1.isDestroyed());
  372. BS_TEST_ASSERT(!cmpB1_1.isDestroyed());
  373. BS_TEST_ASSERT(!cmpA1_1->ref1.isDestroyed());
  374. BS_TEST_ASSERT(!cmpA1_1->ref2.isDestroyed());
  375. BS_TEST_ASSERT(!cmpB1_1->ref1.isDestroyed());
  376. BS_TEST_ASSERT(!cmpExternal->ref1.isDestroyed());
  377. BS_TEST_ASSERT(!cmpExternal->ref2.isDestroyed());
  378. BS_TEST_ASSERT(cmpB1_1->val1 == "InitialValue");
  379. so0_0->destroy();
  380. }
  381. void EditorTestSuite::BinaryDiff()
  382. {
  383. SPtr<TestObjectA> orgObj = bs_shared_ptr<TestObjectA>();
  384. SPtr<TestObjectA> newObj = bs_shared_ptr<TestObjectA>();
  385. newObj->intA = 995;
  386. newObj->strA = "potato";
  387. newObj->arrStrB = { "orange", "carrot" };
  388. newObj->arrStrC[2] = "banana";
  389. newObj->objB.intA = 9940;
  390. newObj->objPtrB->strA = "kiwi";
  391. newObj->objPtrC = nullptr;
  392. newObj->objPtrD = bs_shared_ptr<TestObjectB>();
  393. newObj->arrObjB[1].strA = "strawberry";
  394. newObj->arrObjPtrB[0]->intA = 99100;
  395. MemorySerializer ms;
  396. UINT32 orgDataLength = 0;
  397. UINT8* orgData = ms.encode(orgObj.get(), orgDataLength, &bs_alloc);
  398. UINT32 newDataLength = 0;
  399. UINT8* newData = ms.encode(newObj.get(), newDataLength, &bs_alloc);
  400. BinarySerializer bs;
  401. SPtr<SerializedObject> orgSerialized = bs._decodeIntermediate(orgData, orgDataLength);
  402. SPtr<SerializedObject> newSerialized = bs._decodeIntermediate(newData, newDataLength);
  403. IDiff& diffHandler = orgObj->getRTTI()->getDiffHandler();
  404. SPtr<SerializedObject> objDiff = diffHandler.generateDiff(orgSerialized, newSerialized);
  405. diffHandler.applyDiff(orgObj, objDiff);
  406. bs_free(orgData);
  407. bs_free(newData);
  408. BS_TEST_ASSERT(orgObj->intA == newObj->intA);
  409. BS_TEST_ASSERT(orgObj->strA == newObj->strA);
  410. BS_TEST_ASSERT(orgObj->strB == newObj->strB);
  411. BS_TEST_ASSERT(orgObj->objA.intA == newObj->objA.intA);
  412. BS_TEST_ASSERT(orgObj->objB.intA == newObj->objB.intA);
  413. BS_TEST_ASSERT(orgObj->objPtrA->strA == newObj->objPtrA->strA);
  414. BS_TEST_ASSERT(orgObj->objPtrB->strA == newObj->objPtrB->strA);
  415. BS_TEST_ASSERT(orgObj->objPtrD->strA == newObj->objPtrD->strA);
  416. BS_TEST_ASSERT(orgObj->objPtrC == newObj->objPtrC);
  417. BS_TEST_ASSERT(orgObj->arrStrA.size() == newObj->arrStrA.size());
  418. for (UINT32 i = 0; i < (UINT32)orgObj->arrStrA.size(); i++)
  419. BS_TEST_ASSERT(orgObj->arrStrA[i] == newObj->arrStrA[i]);
  420. BS_TEST_ASSERT(orgObj->arrStrB.size() == newObj->arrStrB.size());
  421. for (UINT32 i = 0; i < (UINT32)orgObj->arrStrB.size(); i++)
  422. BS_TEST_ASSERT(orgObj->arrStrB[i] == newObj->arrStrB[i]);
  423. BS_TEST_ASSERT(orgObj->arrStrC.size() == newObj->arrStrC.size());
  424. for (UINT32 i = 0; i < (UINT32)orgObj->arrStrC.size(); i++)
  425. BS_TEST_ASSERT(orgObj->arrStrC[i] == newObj->arrStrC[i]);
  426. BS_TEST_ASSERT(orgObj->arrObjA.size() == newObj->arrObjA.size());
  427. for (UINT32 i = 0; i < (UINT32)orgObj->arrObjA.size(); i++)
  428. BS_TEST_ASSERT(orgObj->arrObjA[i].strA == newObj->arrObjA[i].strA);
  429. BS_TEST_ASSERT(orgObj->arrObjB.size() == newObj->arrObjB.size());
  430. for (UINT32 i = 0; i < (UINT32)orgObj->arrObjB.size(); i++)
  431. BS_TEST_ASSERT(orgObj->arrObjB[i].strA == newObj->arrObjB[i].strA);
  432. BS_TEST_ASSERT(orgObj->arrObjPtrA.size() == newObj->arrObjPtrA.size());
  433. for (UINT32 i = 0; i < (UINT32)orgObj->arrObjPtrA.size(); i++)
  434. BS_TEST_ASSERT(orgObj->arrObjPtrA[i]->intA == newObj->arrObjPtrA[i]->intA);
  435. BS_TEST_ASSERT(orgObj->arrObjPtrB.size() == newObj->arrObjPtrB.size());
  436. for (UINT32 i = 0; i < (UINT32)orgObj->arrObjPtrB.size(); i++)
  437. BS_TEST_ASSERT(orgObj->arrObjPtrB[i]->intA == newObj->arrObjPtrB[i]->intA);
  438. }
  439. void EditorTestSuite::TestPrefabDiff()
  440. {
  441. HSceneObject root = SceneObject::create("root");
  442. HSceneObject so0 = SceneObject::create("so0");
  443. HSceneObject so1 = SceneObject::create("so1");
  444. HSceneObject so2 = SceneObject::create("so2");
  445. HSceneObject so0_0 = SceneObject::create("so0_0");
  446. HSceneObject so0_1 = SceneObject::create("so0_1");
  447. HSceneObject so1_0 = SceneObject::create("so1_0");
  448. HSceneObject so1_1 = SceneObject::create("so1_1");
  449. HSceneObject so1_2 = SceneObject::create("so1_2");
  450. HSceneObject so2_0 = SceneObject::create("so2_0");
  451. so0->setParent(root);
  452. so1->setParent(root);
  453. so2->setParent(root);
  454. so0_0->setParent(so0);
  455. so0_1->setParent(so0);
  456. so1_0->setParent(so1);
  457. so1_1->setParent(so1);
  458. so1_2->setParent(so1);
  459. so2_0->setParent(so2);
  460. GameObjectHandle<TestComponentC> cmp0 = so0->addComponent<TestComponentC>();
  461. GameObjectHandle<TestComponentC> cmp0_1_A = so0_1->addComponent<TestComponentC>();
  462. GameObjectHandle<TestComponentD> cmp0_1_B = so0_1->addComponent<TestComponentD>();
  463. GameObjectHandle<TestComponentD> cmp1 = so1->addComponent<TestComponentD>();
  464. GameObjectHandle<TestComponentD> cmp1_2 = so1_2->addComponent<TestComponentD>();
  465. GameObjectHandle<TestComponentD> cmp2 = so2->addComponent<TestComponentD>();
  466. HPrefab prefab = Prefab::create(root);
  467. gResources().save(prefab, "C:\\testprefab.asset", true);
  468. // Perform modifications
  469. GameObjectHandle<TestComponentC> cmp1_3;
  470. GameObjectHandle<TestComponentD> cmp3;
  471. HSceneObject so1_3, so2_1, so3;
  472. {
  473. cmp0->obj.strA = "banana";
  474. so0_0->destroy();
  475. cmp0_1_A->destroy();
  476. so1_3 = SceneObject::create("so1_2");
  477. so1_3->setParent(so1);
  478. cmp1_3 = so1_3->addComponent<TestComponentC>();
  479. cmp1_3->obj.intA = 999;
  480. so1_0->setName("apple");
  481. so1_1->destroy();
  482. cmp1_2->destroy();
  483. cmp1_2 = so1_2->addComponent<TestComponentD>();
  484. cmp1_2->obj.strA = "orange";
  485. so2_1 = SceneObject::create("so2_1");
  486. so2_1->setParent(so2);
  487. so2_0->addComponent<TestComponentD>();
  488. so3 = SceneObject::create("so3");
  489. so3->setParent(root);
  490. cmp3 = so3->addComponent<TestComponentD>();
  491. }
  492. SPtr<PrefabDiff> prefabDiff = PrefabDiff::create(prefab->getRoot(), root);
  493. prefab = gResources().load<Prefab>("C:\\testprefab.asset");
  494. HSceneObject newRoot = prefab->instantiate();
  495. prefabDiff->apply(newRoot);
  496. // Compare and assert
  497. BS_TEST_ASSERT(root->getNumChildren() == newRoot->getNumChildren());
  498. HSceneObject nso0 = newRoot->getChild(0);
  499. GameObjectHandle<TestComponentC> ncmp0 = nso0->getComponent<TestComponentC>();
  500. BS_TEST_ASSERT(cmp0->obj.strA == ncmp0->obj.strA);
  501. BS_TEST_ASSERT(so0->getNumChildren() == nso0->getNumChildren());
  502. HSceneObject nso0_1 = nso0->getChild(0);
  503. GameObjectHandle<TestComponentC> ncmp0_1 = nso0_1->getComponent<TestComponentD>();
  504. BS_TEST_ASSERT(ncmp0_1 != nullptr);
  505. HSceneObject nso1 = newRoot->getChild(1);
  506. BS_TEST_ASSERT(so1->getNumChildren() == nso1->getNumChildren());
  507. HSceneObject nso1_0 = nso1->getChild(0);
  508. BS_TEST_ASSERT(so1_0->getName() == nso1_0->getName());
  509. HSceneObject nso1_2 = nso1->getChild(1);
  510. GameObjectHandle<TestComponentD> ncmp1_2 = nso1_2->getComponent<TestComponentD>();
  511. BS_TEST_ASSERT(cmp1_2->obj.strA == ncmp1_2->obj.strA);
  512. HSceneObject nso1_3 = nso1->getChild(2);
  513. GameObjectHandle<TestComponentC> ncmp1_3 = nso1_3->getComponent<TestComponentC>();
  514. BS_TEST_ASSERT(cmp1_3->obj.intA == ncmp1_3->obj.intA);
  515. HSceneObject nso2 = newRoot->getChild(2);
  516. BS_TEST_ASSERT(so2->getNumChildren() == nso2->getNumChildren());
  517. HSceneObject nso2_0 = nso2->getChild(0);
  518. GameObjectHandle<TestComponentD> ncmp2_0 = nso2_0->getComponent<TestComponentD>();
  519. BS_TEST_ASSERT(ncmp2_0 != nullptr);
  520. HSceneObject nso3 = newRoot->getChild(3);
  521. GameObjectHandle<TestComponentD> ncmp3 = nso3->getComponent<TestComponentD>();
  522. BS_TEST_ASSERT(ncmp3 != nullptr);
  523. root->destroy();
  524. }
  525. }