BsCmdDeleteSO.cpp 2.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596
  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)
  12. { }
  13. CmdDeleteSO::~CmdDeleteSO()
  14. {
  15. mSceneObject = nullptr;
  16. clear();
  17. }
  18. void CmdDeleteSO::clear()
  19. {
  20. mSerializedObjectSize = 0;
  21. mSerializedObjectParentId = 0;
  22. if (mSerializedObject != nullptr)
  23. {
  24. bs_free(mSerializedObject);
  25. mSerializedObject = nullptr;
  26. }
  27. }
  28. void CmdDeleteSO::execute(const HSceneObject& sceneObject, const String& description)
  29. {
  30. // Register command and commit it
  31. CmdDeleteSO* command = new (bs_alloc<CmdDeleteSO>()) CmdDeleteSO(description, sceneObject);
  32. SPtr<CmdDeleteSO> commandPtr = bs_shared_ptr(command);
  33. UndoRedo::instance().registerCommand(commandPtr);
  34. commandPtr->commit();
  35. }
  36. void CmdDeleteSO::commit()
  37. {
  38. clear();
  39. if (mSceneObject == nullptr || mSceneObject.isDestroyed())
  40. return;
  41. recordSO(mSceneObject);
  42. mSceneObject->destroy();
  43. }
  44. void CmdDeleteSO::revert()
  45. {
  46. HSceneObject parent;
  47. if (mSerializedObjectParentId != 0)
  48. parent = static_object_cast<SceneObject>(GameObjectManager::instance().getObject(mSerializedObjectParentId));
  49. CoreSerializationContext serzContext;
  50. serzContext.goState = bs_shared_ptr_new<GameObjectDeserializationState>(GODM_RestoreExternal | GODM_UseNewIds);
  51. // Object might still only be queued for destruction, but we need to fully destroy it since we're about to replace
  52. // the potentially only reference to the old object
  53. if (!mSceneObject.isDestroyed())
  54. mSceneObject->destroy(true);
  55. MemorySerializer serializer;
  56. SPtr<SceneObject> restored = std::static_pointer_cast<SceneObject>(
  57. serializer.decode(mSerializedObject, mSerializedObjectSize, &serzContext));
  58. EditorUtility::restoreIds(restored->getHandle(), mSceneObjectProxy);
  59. restored->setParent(parent);
  60. restored->_instantiate();
  61. mSceneObject = restored->getHandle();
  62. }
  63. void CmdDeleteSO::recordSO(const HSceneObject& sceneObject)
  64. {
  65. bool isInstantiated = !sceneObject->hasFlag(SOF_DontInstantiate);
  66. sceneObject->_setFlags(SOF_DontInstantiate);
  67. MemorySerializer serializer;
  68. mSerializedObject = serializer.encode(sceneObject.get(), mSerializedObjectSize);
  69. if (isInstantiated)
  70. sceneObject->_unsetFlags(SOF_DontInstantiate);
  71. HSceneObject parent = sceneObject->getParent();
  72. if (parent != nullptr)
  73. mSerializedObjectParentId = parent->getInstanceId();
  74. mSceneObjectProxy = EditorUtility::createProxy(sceneObject);
  75. }
  76. }