BsCmdRecordSO.cpp 3.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132
  1. //********************************** Banshee Engine (www.banshee3d.com) **************************************************//
  2. //**************** Copyright (c) 2016 Marko Pintera ([email protected]). All rights reserved. **********************//
  3. #include "UndoRedo/BsCmdRecordSO.h"
  4. #include "Scene/BsSceneObject.h"
  5. #include "Scene/BsComponent.h"
  6. #include "Serialization/BsMemorySerializer.h"
  7. namespace bs
  8. {
  9. CmdRecordSO::CmdRecordSO(const String& description, const HSceneObject& sceneObject, bool recordHierarchy)
  10. : EditorCommand(description), mSceneObject(sceneObject), mRecordHierarchy(recordHierarchy)
  11. , mSerializedObject(nullptr), mSerializedObjectSize(0)
  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 String& description)
  29. {
  30. // Register command and commit it
  31. CmdRecordSO* command = new (bs_alloc<CmdRecordSO>()) CmdRecordSO(description, sceneObject, recordHierarchy);
  32. SPtr<CmdRecordSO> commandPtr = bs_shared_ptr(command);
  33. UndoRedo::instance().registerCommand(commandPtr);
  34. commandPtr->commit();
  35. }
  36. void CmdRecordSO::commit()
  37. {
  38. clear();
  39. if (mSceneObject == nullptr || mSceneObject.isDestroyed())
  40. return;
  41. recordSO(mSceneObject);
  42. }
  43. void CmdRecordSO::revert()
  44. {
  45. if (mSceneObject == nullptr || mSceneObject.isDestroyed())
  46. return;
  47. HSceneObject parent = mSceneObject->getParent();
  48. UINT32 numChildren = mSceneObject->getNumChildren();
  49. HSceneObject* children = nullptr;
  50. if (!mRecordHierarchy)
  51. {
  52. children = bs_stack_new<HSceneObject>(numChildren);
  53. for (UINT32 i = 0; i < numChildren; i++)
  54. {
  55. HSceneObject child = mSceneObject->getChild(i);
  56. children[i] = child;
  57. child->setParent(HSceneObject());
  58. }
  59. }
  60. mSceneObject->destroy(true);
  61. GameObjectManager::instance().setDeserializationMode(GODM_RestoreExternal | GODM_UseNewIds);
  62. MemorySerializer serializer;
  63. SPtr<SceneObject> restored = std::static_pointer_cast<SceneObject>(serializer.decode(mSerializedObject, mSerializedObjectSize));
  64. EditorUtility::restoreIds(restored->getHandle(), mSceneObjectProxy);
  65. restored->setParent(parent);
  66. if (!mRecordHierarchy)
  67. {
  68. for (UINT32 i = 0; i < numChildren; i++)
  69. children[i]->setParent(restored->getHandle());
  70. bs_stack_delete(children, numChildren);
  71. }
  72. restored->_instantiate();
  73. }
  74. void CmdRecordSO::recordSO(const HSceneObject& sceneObject)
  75. {
  76. UINT32 numChildren = mSceneObject->getNumChildren();
  77. HSceneObject* children = nullptr;
  78. if (!mRecordHierarchy)
  79. {
  80. children = bs_stack_new<HSceneObject>(numChildren);
  81. for (UINT32 i = 0; i < numChildren; i++)
  82. {
  83. HSceneObject child = mSceneObject->getChild(i);
  84. children[i] = child;
  85. child->setParent(HSceneObject());
  86. }
  87. }
  88. bool isInstantiated = !mSceneObject->hasFlag(SOF_DontInstantiate);
  89. mSceneObject->_setFlags(SOF_DontInstantiate);
  90. MemorySerializer serializer;
  91. mSerializedObject = serializer.encode(mSceneObject.get(), mSerializedObjectSize);
  92. if (isInstantiated)
  93. mSceneObject->_unsetFlags(SOF_DontInstantiate);
  94. mSceneObjectProxy = EditorUtility::createProxy(mSceneObject);
  95. if (!mRecordHierarchy)
  96. {
  97. for (UINT32 i = 0; i < numChildren; i++)
  98. children[i]->setParent(sceneObject->getHandle());
  99. bs_stack_delete(children, numChildren);
  100. }
  101. }
  102. }