BsCmdRecordSO.cpp 3.0 KB

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