BsCmdDeleteSO.cpp 2.8 KB

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