BsEditorTestSuite.cpp 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408
  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. namespace BansheeEngine
  11. {
  12. class TestComponentARTTI : public RTTIType<TestComponentA, Component, TestComponentARTTI>
  13. {
  14. private:
  15. HSceneObject& getRef1(TestComponentA* obj) { return obj->ref1; }
  16. void setRef1(TestComponentA* obj, HSceneObject& val) { obj->ref1 = val; }
  17. HComponent& getRef2(TestComponentA* obj) { return obj->ref2; }
  18. void setRef2(TestComponentA* obj, HComponent& val) { obj->ref2 = val; }
  19. public:
  20. TestComponentARTTI()
  21. {
  22. addReflectableField("ref1", 0, &TestComponentARTTI::getRef1, &TestComponentARTTI::setRef1);
  23. addReflectableField("ref2", 1, &TestComponentARTTI::getRef2, &TestComponentARTTI::setRef2);
  24. }
  25. virtual const String& getRTTIName()
  26. {
  27. static String name = "TestComponentA";
  28. return name;
  29. }
  30. virtual UINT32 getRTTIId()
  31. {
  32. return TID_TestComponentA;
  33. }
  34. virtual std::shared_ptr<IReflectable> newRTTIObject()
  35. {
  36. return GameObjectRTTI::createGameObject<TestComponentA>();
  37. }
  38. };
  39. class TestComponentBRTTI : public RTTIType<TestComponentB, Component, TestComponentBRTTI>
  40. {
  41. private:
  42. HSceneObject& getRef1(TestComponentB* obj) { return obj->ref1; }
  43. void setRef1(TestComponentB* obj, HSceneObject& val) { obj->ref1 = val; }
  44. String& getVal1(TestComponentB* obj) { return obj->val1; }
  45. void setVal1(TestComponentB* obj, String& val) { obj->val1 = val; }
  46. public:
  47. TestComponentBRTTI()
  48. {
  49. addReflectableField("ref1", 0, &TestComponentBRTTI::getRef1, &TestComponentBRTTI::setRef1);
  50. addPlainField("val1", 1, &TestComponentBRTTI::getVal1, &TestComponentBRTTI::setVal1);
  51. }
  52. virtual const String& getRTTIName()
  53. {
  54. static String name = "TestComponentB";
  55. return name;
  56. }
  57. virtual UINT32 getRTTIId()
  58. {
  59. return TID_TestComponentB;
  60. }
  61. virtual std::shared_ptr<IReflectable> newRTTIObject()
  62. {
  63. return GameObjectRTTI::createGameObject<TestComponentB>();
  64. }
  65. };
  66. TestComponentA::TestComponentA(const HSceneObject& parent)
  67. :Component(parent)
  68. {}
  69. RTTITypeBase* TestComponentA::getRTTIStatic()
  70. {
  71. return TestComponentARTTI::instance();
  72. }
  73. RTTITypeBase* TestComponentA::getRTTI() const
  74. {
  75. return TestComponentA::getRTTIStatic();
  76. }
  77. TestComponentB::TestComponentB(const HSceneObject& parent)
  78. :Component(parent)
  79. {}
  80. RTTITypeBase* TestComponentB::getRTTIStatic()
  81. {
  82. return TestComponentBRTTI::instance();
  83. }
  84. RTTITypeBase* TestComponentB::getRTTI() const
  85. {
  86. return TestComponentB::getRTTIStatic();
  87. }
  88. struct TestObjectB : IReflectable
  89. {
  90. UINT32 intA = 100;
  91. String strA = "100";
  92. /************************************************************************/
  93. /* RTTI */
  94. /************************************************************************/
  95. public:
  96. friend class TestObjectBRTTI;
  97. static RTTITypeBase* getRTTIStatic();
  98. virtual RTTITypeBase* getRTTI() const;
  99. };
  100. struct TestObjectA : IReflectable
  101. {
  102. TestObjectA()
  103. {
  104. arrStrA = { "10", "11", "12" };
  105. arrStrB = { "13", "14", "15" };
  106. arrStrC = { "16", "17", "18" };
  107. arrObjA = { TestObjectB(), TestObjectB(), TestObjectB() };
  108. arrObjB = { TestObjectB(), TestObjectB(), TestObjectB() };
  109. arrObjPtrA = { bs_shared_ptr<TestObjectB>(), bs_shared_ptr<TestObjectB>(), bs_shared_ptr<TestObjectB>() };
  110. arrObjPtrB = { bs_shared_ptr<TestObjectB>(), bs_shared_ptr<TestObjectB>(), bs_shared_ptr<TestObjectB>() };
  111. }
  112. UINT32 intA = 5;
  113. String strA = "5";
  114. String strB = "7";
  115. TestObjectB objA;
  116. TestObjectB objB;
  117. SPtr<TestObjectB> objPtrA = bs_shared_ptr<TestObjectB>();
  118. SPtr<TestObjectB> objPtrB = bs_shared_ptr<TestObjectB>();
  119. SPtr<TestObjectB> objPtrC = bs_shared_ptr<TestObjectB>();
  120. SPtr<TestObjectB> objPtrD = nullptr;
  121. Vector<String> arrStrA;
  122. Vector<String> arrStrB;
  123. Vector<String> arrStrC;
  124. Vector<TestObjectB> arrObjA;
  125. Vector<TestObjectB> arrObjB;
  126. Vector<SPtr<TestObjectB>> arrObjPtrA;
  127. Vector<SPtr<TestObjectB>> arrObjPtrB;
  128. /************************************************************************/
  129. /* RTTI */
  130. /************************************************************************/
  131. public:
  132. friend class TestObjectARTTI;
  133. static RTTITypeBase* getRTTIStatic();
  134. virtual RTTITypeBase* getRTTI() const;
  135. };
  136. class TestObjectARTTI : public RTTIType < TestObjectA, IReflectable, TestObjectARTTI >
  137. {
  138. private:
  139. BS_PLAIN_MEMBER(intA);
  140. BS_PLAIN_MEMBER(strA);
  141. BS_PLAIN_MEMBER(strB);
  142. BS_REFL_MEMBER(objA);
  143. BS_REFL_MEMBER(objB);
  144. BS_REFLPTR_MEMBER(objPtrA);
  145. BS_REFLPTR_MEMBER(objPtrB);
  146. BS_REFLPTR_MEMBER(objPtrC);
  147. BS_REFLPTR_MEMBER(objPtrD);
  148. BS_PLAIN_MEMBER_VEC(arrStrA);
  149. BS_PLAIN_MEMBER_VEC(arrStrB);
  150. BS_PLAIN_MEMBER_VEC(arrStrC);
  151. BS_REFL_MEMBER_VEC(arrObjA);
  152. BS_REFL_MEMBER_VEC(arrObjB);
  153. BS_REFLPTR_MEMBER_VEC(arrObjPtrA);
  154. BS_REFLPTR_MEMBER_VEC(arrObjPtrB);
  155. public:
  156. TestObjectARTTI()
  157. {
  158. BS_ADD_PLAIN_FIELD(intA, 0);
  159. BS_ADD_PLAIN_FIELD(strA, 1);
  160. BS_ADD_PLAIN_FIELD(strB, 2);
  161. BS_ADD_REFL_FIELD(objA, 3);
  162. BS_ADD_REFL_FIELD(objB, 4);
  163. BS_ADD_REFLPTR_FIELD(objPtrA, 5);
  164. BS_ADD_REFLPTR_FIELD(objPtrB, 6);
  165. BS_ADD_REFLPTR_FIELD(objPtrC, 7);
  166. BS_ADD_REFLPTR_FIELD(objPtrD, 8);
  167. BS_ADD_PLAIN_FIELD_ARR(arrStrA, 9);
  168. BS_ADD_PLAIN_FIELD_ARR(arrStrB, 10);
  169. BS_ADD_PLAIN_FIELD_ARR(arrStrC, 11);
  170. BS_ADD_REFL_FIELD_ARR(arrObjA, 12);
  171. BS_ADD_REFL_FIELD_ARR(arrObjB, 13);
  172. BS_ADD_REFLPTR_FIELD_ARR(arrObjPtrA, 14);
  173. BS_ADD_REFLPTR_FIELD_ARR(arrObjPtrB, 15);
  174. }
  175. virtual const String& getRTTIName()
  176. {
  177. static String name = "TestObjectA";
  178. return name;
  179. }
  180. virtual UINT32 getRTTIId()
  181. {
  182. return TID_TestObjectA;
  183. }
  184. virtual std::shared_ptr<IReflectable> newRTTIObject()
  185. {
  186. return bs_shared_ptr<TestObjectA>();
  187. }
  188. };
  189. class TestObjectBRTTI : public RTTIType < TestObjectB, IReflectable, TestObjectBRTTI >
  190. {
  191. private:
  192. BS_PLAIN_MEMBER(intA);
  193. BS_PLAIN_MEMBER(strA);
  194. public:
  195. TestObjectBRTTI()
  196. {
  197. BS_ADD_PLAIN_FIELD(intA, 0);
  198. BS_ADD_PLAIN_FIELD(strA, 1);
  199. }
  200. virtual const String& getRTTIName()
  201. {
  202. static String name = "TestObjectB";
  203. return name;
  204. }
  205. virtual UINT32 getRTTIId()
  206. {
  207. return TID_TestObjectB;
  208. }
  209. virtual std::shared_ptr<IReflectable> newRTTIObject()
  210. {
  211. return bs_shared_ptr<TestObjectB>();
  212. }
  213. };
  214. RTTITypeBase* TestObjectB::getRTTIStatic()
  215. {
  216. return TestObjectBRTTI::instance();
  217. }
  218. RTTITypeBase* TestObjectB::getRTTI() const
  219. {
  220. return TestObjectB::getRTTIStatic();
  221. }
  222. RTTITypeBase* TestObjectA::getRTTIStatic()
  223. {
  224. return TestObjectARTTI::instance();
  225. }
  226. RTTITypeBase* TestObjectA::getRTTI() const
  227. {
  228. return TestObjectA::getRTTIStatic();
  229. }
  230. EditorTestSuite::EditorTestSuite()
  231. {
  232. BS_ADD_TEST(EditorTestSuite::SceneObjectRecord_UndoRedo);
  233. BS_ADD_TEST(EditorTestSuite::BinaryDiff);
  234. }
  235. void EditorTestSuite::SceneObjectRecord_UndoRedo()
  236. {
  237. HSceneObject so0_0 = SceneObject::create("so0_0");
  238. HSceneObject so1_0 = SceneObject::create("so1_0");
  239. HSceneObject so1_1 = SceneObject::create("so1_1");
  240. HSceneObject so2_0 = SceneObject::create("so2_0");
  241. so1_0->setParent(so0_0);
  242. so1_1->setParent(so0_0);
  243. so2_0->setParent(so1_0);
  244. GameObjectHandle<TestComponentA> cmpA1_1 = so1_1->addComponent<TestComponentA>();
  245. GameObjectHandle<TestComponentB> cmpB1_1 = so1_1->addComponent<TestComponentB>();
  246. HSceneObject soExternal = SceneObject::create("soExternal");
  247. GameObjectHandle<TestComponentA> cmpExternal = soExternal->addComponent<TestComponentA>();
  248. cmpA1_1->ref1 = so2_0;
  249. cmpA1_1->ref2 = cmpB1_1;
  250. cmpB1_1->ref1 = soExternal;
  251. cmpB1_1->val1 = "InitialValue";
  252. cmpExternal->ref1 = so1_1;
  253. cmpExternal->ref2 = cmpA1_1;
  254. CmdRecordSO::execute(so0_0);
  255. cmpB1_1->val1 = "ModifiedValue";
  256. UndoRedo::instance().undo();
  257. BS_TEST_ASSERT(!so0_0.isDestroyed());
  258. BS_TEST_ASSERT(!so1_0.isDestroyed());
  259. BS_TEST_ASSERT(!so1_1.isDestroyed());
  260. BS_TEST_ASSERT(!so2_0.isDestroyed());
  261. BS_TEST_ASSERT(!cmpA1_1.isDestroyed());
  262. BS_TEST_ASSERT(!cmpB1_1.isDestroyed());
  263. BS_TEST_ASSERT(!cmpA1_1->ref1.isDestroyed());
  264. BS_TEST_ASSERT(!cmpA1_1->ref2.isDestroyed());
  265. BS_TEST_ASSERT(!cmpB1_1->ref1.isDestroyed());
  266. BS_TEST_ASSERT(!cmpExternal->ref1.isDestroyed());
  267. BS_TEST_ASSERT(!cmpExternal->ref2.isDestroyed());
  268. BS_TEST_ASSERT(cmpB1_1->val1 == "InitialValue");
  269. }
  270. void EditorTestSuite::BinaryDiff()
  271. {
  272. SPtr<TestObjectA> orgObj = bs_shared_ptr<TestObjectA>();
  273. SPtr<TestObjectA> newObj = bs_shared_ptr<TestObjectA>();
  274. newObj->intA = 995;
  275. newObj->strA = "potato";
  276. newObj->arrStrB = { "orange", "carrot" };
  277. newObj->arrStrC[2] = "banana";
  278. newObj->objB.intA = 9940;
  279. newObj->objPtrB->strA = "kiwi";
  280. newObj->objPtrC = nullptr;
  281. newObj->objPtrD = bs_shared_ptr<TestObjectB>();
  282. newObj->arrObjB[1].strA = "strawberry";
  283. newObj->arrObjPtrB[0]->intA = 99100;
  284. MemorySerializer ms;
  285. UINT32 orgDataLength = 0;
  286. UINT8* orgData = ms.encode(orgObj.get(), orgDataLength, &bs_alloc);
  287. UINT32 newDataLength = 0;
  288. UINT8* newData = ms.encode(newObj.get(), newDataLength, &bs_alloc);
  289. BinarySerializer bs;
  290. SPtr<SerializedObject> orgSerialized = bs._decodeIntermediate(orgData, orgDataLength);
  291. SPtr<SerializedObject> newSerialized = bs._decodeIntermediate(newData, newDataLength);
  292. IDiff& diffHandler = orgObj->getRTTI()->getDiffHandler();
  293. SPtr<SerializedObject> objDiff = diffHandler.generateDiff(orgSerialized, newSerialized);
  294. diffHandler.applyDiff(orgObj, objDiff);
  295. bs_free(orgData);
  296. bs_free(newData);
  297. BS_TEST_ASSERT(orgObj->intA == newObj->intA);
  298. BS_TEST_ASSERT(orgObj->strA == newObj->strA);
  299. BS_TEST_ASSERT(orgObj->strB == newObj->strB);
  300. BS_TEST_ASSERT(orgObj->objA.intA == newObj->objA.intA);
  301. BS_TEST_ASSERT(orgObj->objB.intA == newObj->objB.intA);
  302. BS_TEST_ASSERT(orgObj->objPtrA->strA == newObj->objPtrA->strA);
  303. BS_TEST_ASSERT(orgObj->objPtrB->strA == newObj->objPtrB->strA);
  304. BS_TEST_ASSERT(orgObj->objPtrD->strA == newObj->objPtrD->strA);
  305. BS_TEST_ASSERT(orgObj->objPtrC == newObj->objPtrC);
  306. BS_TEST_ASSERT(orgObj->arrStrA.size() == newObj->arrStrA.size());
  307. for (UINT32 i = 0; i < (UINT32)orgObj->arrStrA.size(); i++)
  308. BS_TEST_ASSERT(orgObj->arrStrA[i] == newObj->arrStrA[i]);
  309. BS_TEST_ASSERT(orgObj->arrStrB.size() == newObj->arrStrB.size());
  310. for (UINT32 i = 0; i < (UINT32)orgObj->arrStrB.size(); i++)
  311. BS_TEST_ASSERT(orgObj->arrStrB[i] == newObj->arrStrB[i]);
  312. BS_TEST_ASSERT(orgObj->arrStrC.size() == newObj->arrStrC.size());
  313. for (UINT32 i = 0; i < (UINT32)orgObj->arrStrC.size(); i++)
  314. BS_TEST_ASSERT(orgObj->arrStrC[i] == newObj->arrStrC[i]);
  315. BS_TEST_ASSERT(orgObj->arrObjA.size() == newObj->arrObjA.size());
  316. for (UINT32 i = 0; i < (UINT32)orgObj->arrObjA.size(); i++)
  317. BS_TEST_ASSERT(orgObj->arrObjA[i].strA == newObj->arrObjA[i].strA);
  318. BS_TEST_ASSERT(orgObj->arrObjB.size() == newObj->arrObjB.size());
  319. for (UINT32 i = 0; i < (UINT32)orgObj->arrObjB.size(); i++)
  320. BS_TEST_ASSERT(orgObj->arrObjB[i].strA == newObj->arrObjB[i].strA);
  321. BS_TEST_ASSERT(orgObj->arrObjPtrA.size() == newObj->arrObjPtrA.size());
  322. for (UINT32 i = 0; i < (UINT32)orgObj->arrObjPtrA.size(); i++)
  323. BS_TEST_ASSERT(orgObj->arrObjPtrA[i]->intA == newObj->arrObjPtrA[i]->intA);
  324. BS_TEST_ASSERT(orgObj->arrObjPtrB.size() == newObj->arrObjPtrB.size());
  325. for (UINT32 i = 0; i < (UINT32)orgObj->arrObjPtrB.size(); i++)
  326. BS_TEST_ASSERT(orgObj->arrObjPtrB[i]->intA == newObj->arrObjPtrB[i]->intA);
  327. }
  328. }