BsCmdRecordSO.cpp 3.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122
  1. //********************************** Banshee Engine (www.banshee3d.com) **************************************************//
  2. //**************** Copyright (c) 2016 Marko Pintera ([email protected]). All rights reserved. **********************//
  3. #include "BsCmdRecordSO.h"
  4. #include "BsSceneObject.h"
  5. #include "BsComponent.h"
  6. #include "BsMemorySerializer.h"
  7. namespace BansheeEngine
  8. {
  9. CmdRecordSO::CmdRecordSO(const WString& description, const HSceneObject& sceneObject, bool recordHierarchy)
  10. :EditorCommand(description), mSceneObject(sceneObject), mSerializedObject(nullptr), mSerializedObjectSize(0),
  11. mRecordHierarchy(recordHierarchy)
  12. {
  13. }
  14. CmdRecordSO::~CmdRecordSO()
  15. {
  16. mSceneObject = nullptr;
  17. clear();
  18. }
  19. void CmdRecordSO::clear()
  20. {
  21. mSerializedObjectSize = 0;
  22. if (mSerializedObject != nullptr)
  23. {
  24. bs_free(mSerializedObject);
  25. mSerializedObject = nullptr;
  26. }
  27. }
  28. void CmdRecordSO::execute(const HSceneObject& sceneObject, bool recordHierarchy, const WString& description)
  29. {
  30. // Register command and commit it
  31. CmdRecordSO* command = new (bs_alloc<CmdRecordSO>()) CmdRecordSO(description, sceneObject, recordHierarchy);
  32. UndoRedo::instance().registerCommand(command);
  33. command->commit();
  34. }
  35. void CmdRecordSO::commit()
  36. {
  37. clear();
  38. if (mSceneObject == nullptr || mSceneObject.isDestroyed())
  39. return;
  40. recordSO(mSceneObject);
  41. }
  42. void CmdRecordSO::revert()
  43. {
  44. if (mSceneObject == nullptr || mSceneObject.isDestroyed())
  45. return;
  46. HSceneObject parent = mSceneObject->getParent();
  47. UINT32 numChildren = mSceneObject->getNumChildren();
  48. HSceneObject* children = nullptr;
  49. if (!mRecordHierarchy)
  50. {
  51. children = bs_stack_new<HSceneObject>(numChildren);
  52. for (UINT32 i = 0; i < numChildren; i++)
  53. {
  54. HSceneObject child = mSceneObject->getChild(i);
  55. children[i] = child;
  56. child->setParent(HSceneObject());
  57. }
  58. }
  59. mSceneObject->destroy(true);
  60. GameObjectManager::instance().setDeserializationMode(GODM_RestoreExternal | GODM_UseNewIds);
  61. MemorySerializer serializer;
  62. std::shared_ptr<SceneObject> restored = std::static_pointer_cast<SceneObject>(serializer.decode(mSerializedObject, mSerializedObjectSize));
  63. CmdUtility::restoreIds(restored->getHandle(), mSceneObjectProxy);
  64. restored->setParent(parent);
  65. if (!mRecordHierarchy)
  66. {
  67. for (UINT32 i = 0; i < numChildren; i++)
  68. children[i]->setParent(restored->getHandle());
  69. bs_stack_delete(children, numChildren);
  70. }
  71. }
  72. void CmdRecordSO::recordSO(const HSceneObject& sceneObject)
  73. {
  74. UINT32 numChildren = mSceneObject->getNumChildren();
  75. HSceneObject* children = nullptr;
  76. if (!mRecordHierarchy)
  77. {
  78. children = bs_stack_new<HSceneObject>(numChildren);
  79. for (UINT32 i = 0; i < numChildren; i++)
  80. {
  81. HSceneObject child = mSceneObject->getChild(i);
  82. children[i] = child;
  83. child->setParent(HSceneObject());
  84. }
  85. }
  86. MemorySerializer serializer;
  87. mSerializedObject = serializer.encode(mSceneObject.get(), mSerializedObjectSize);
  88. mSceneObjectProxy = CmdUtility::createProxy(mSceneObject);
  89. if (!mRecordHierarchy)
  90. {
  91. for (UINT32 i = 0; i < numChildren; i++)
  92. children[i]->setParent(sceneObject->getHandle());
  93. bs_stack_delete(children, numChildren);
  94. }
  95. }
  96. }