BsCmdDeleteSO.cpp 3.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101
  1. //********************************** Banshee Engine (www.banshee3d.com) **************************************************//
  2. //**************** Copyright (c) 2016 Marko Pintera ([email protected]). All rights reserved. **********************//
  3. #include "UndoRedo/BsCmdDeleteSO.h"
  4. #include "Scene/BsSceneObject.h"
  5. #include "Scene/BsComponent.h"
  6. #include "Serialization/BsMemorySerializer.h"
  7. #include "Utility/BsUtility.h"
  8. namespace bs
  9. {
  10. CmdDeleteSO::CmdDeleteSO(const String& description, const HSceneObject& sceneObject)
  11. : EditorCommand(description), mSceneObject(sceneObject), mSerializedObject(nullptr), mSerializedObjectSize(0)
  12. , mSerializedObjectParentId(0)
  13. {
  14. }
  15. CmdDeleteSO::~CmdDeleteSO()
  16. {
  17. mSceneObject = nullptr;
  18. clear();
  19. }
  20. void CmdDeleteSO::clear()
  21. {
  22. mSerializedObjectSize = 0;
  23. mSerializedObjectParentId = 0;
  24. if (mSerializedObject != nullptr)
  25. {
  26. bs_free(mSerializedObject);
  27. mSerializedObject = nullptr;
  28. }
  29. }
  30. void CmdDeleteSO::execute(const HSceneObject& sceneObject, const String& description)
  31. {
  32. // Register command and commit it
  33. CmdDeleteSO* command = new (bs_alloc<CmdDeleteSO>()) CmdDeleteSO(description, sceneObject);
  34. SPtr<CmdDeleteSO> commandPtr = bs_shared_ptr(command);
  35. UndoRedo::instance().registerCommand(commandPtr);
  36. commandPtr->commit();
  37. }
  38. void CmdDeleteSO::commit()
  39. {
  40. clear();
  41. if (mSceneObject == nullptr || mSceneObject.isDestroyed())
  42. return;
  43. recordSO(mSceneObject);
  44. mSceneObject->destroy();
  45. }
  46. void CmdDeleteSO::revert()
  47. {
  48. if (mSceneObject == nullptr)
  49. return;
  50. HSceneObject parent;
  51. if (mSerializedObjectParentId != 0)
  52. parent = static_object_cast<SceneObject>(GameObjectManager::instance().getObject(mSerializedObjectParentId));
  53. CoreSerializationContext serzContext;
  54. serzContext.goState = bs_shared_ptr_new<GameObjectDeserializationState>(GODM_RestoreExternal | GODM_UseNewIds);
  55. // Object might still only be queued for destruction, but we need to fully destroy it since we're about to replace
  56. // the potentially only reference to the old object
  57. if (!mSceneObject.isDestroyed())
  58. mSceneObject->destroy(true);
  59. MemorySerializer serializer;
  60. SPtr<SceneObject> restored = std::static_pointer_cast<SceneObject>(
  61. serializer.decode(mSerializedObject, mSerializedObjectSize, &serzContext));
  62. EditorUtility::restoreIds(restored->getHandle(), mSceneObjectProxy);
  63. restored->setParent(parent);
  64. restored->_instantiate();
  65. }
  66. void CmdDeleteSO::recordSO(const HSceneObject& sceneObject)
  67. {
  68. bool isInstantiated = !mSceneObject->hasFlag(SOF_DontInstantiate);
  69. mSceneObject->_setFlags(SOF_DontInstantiate);
  70. MemorySerializer serializer;
  71. mSerializedObject = serializer.encode(mSceneObject.get(), mSerializedObjectSize);
  72. if (isInstantiated)
  73. mSceneObject->_unsetFlags(SOF_DontInstantiate);
  74. HSceneObject parent = mSceneObject->getParent();
  75. if (parent != nullptr)
  76. mSerializedObjectParentId = parent->getInstanceId();
  77. mSceneObjectProxy = EditorUtility::createProxy(mSceneObject);
  78. }
  79. }