SceneEditHistory.cpp 3.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138
  1. #include <Atomic/IO/Log.h>
  2. #include <Atomic/Core/Timer.h>
  3. #include <Atomic/Scene/Scene.h>
  4. #include <Atomic/Scene/Component.h>
  5. #include <Atomic/Scene/SceneEvents.h>
  6. #include "../../EditorMode/AEEditorEvents.h"
  7. #include "SceneEditOps.h"
  8. #include "SceneEditor3DEvents.h"
  9. #include "SceneEditHistory.h"
  10. namespace AtomicEditor
  11. {
  12. SceneEditHistory::SceneEditHistory(Context* context, Scene* scene) :
  13. Object(context),
  14. scene_(scene)
  15. {
  16. SubscribeToEvent(scene_, E_SCENEEDITSERIALIZABLE, HANDLER(SceneEditHistory, HandleSceneEditSerializable));
  17. SubscribeToEvent(scene_, E_SCENEEDITNODEADDEDREMOVED, HANDLER(SceneEditHistory, HandleSceneEditNodeAddedRemoved));
  18. }
  19. SceneEditHistory::~SceneEditHistory()
  20. {
  21. }
  22. void SceneEditHistory::AddUndoOp(SceneEditOp* op)
  23. {
  24. undoHistory_.Push(op);
  25. scene_->SendEvent(E_SCENEEDITSCENEMODIFIED);
  26. for (unsigned i = 0; i < redoHistory_.Size(); i++)
  27. {
  28. delete redoHistory_[i];
  29. }
  30. redoHistory_.Clear();
  31. }
  32. void SceneEditHistory::HandleSceneEditSerializableUndoRedo(StringHash eventType, VariantMap& eventData)
  33. {
  34. SharedPtr<Serializable> serial(static_cast<Serializable*>(eventData[SceneEditSerializableUndoRedo::P_SERIALIZABLE].GetPtr()));
  35. if (editStates_.Contains(serial))
  36. {
  37. scene_->SendEvent(E_SCENEEDITSCENEMODIFIED);
  38. editStates_[serial] = eventData[SceneEditSerializableUndoRedo::P_STATE].GetVectorBuffer();
  39. }
  40. }
  41. void SceneEditHistory::HandleSceneEditNodeAddedRemoved(StringHash eventType, VariantMap& eventData)
  42. {
  43. bool added = eventData[SceneEditNodeAddedRemoved::P_ADDED].GetBool();
  44. Node* node = static_cast<Node*>(eventData[SceneEditNodeAddedRemoved::P_NODE].GetPtr());
  45. NodeAddedRemovedOp* op = new NodeAddedRemovedOp(node, added);
  46. AddUndoOp(op);
  47. }
  48. void SceneEditHistory::HandleSceneEditSerializable(StringHash eventType, VariantMap& eventData)
  49. {
  50. int editop = eventData[SceneEditSerializable::P_OPERATION].GetInt();
  51. SharedPtr<Serializable> serial(static_cast<Serializable*>(eventData[SceneEditSerializable::P_SERIALIZABLE].GetPtr()));
  52. if (editop == 0) // begin
  53. {
  54. if (editStates_.Contains(serial))
  55. return;
  56. SubscribeToEvent(serial, E_SCENEEDITSERIALIZABLEUNDOREDO, HANDLER(SceneEditHistory, HandleSceneEditSerializableUndoRedo));
  57. VectorBuffer& vb = editStates_[serial];
  58. vb.Clear();
  59. serial->Serializable::Save(vb);
  60. vb.Seek(0);
  61. }
  62. else if (editop == 1) // change
  63. {
  64. if (!editStates_.Contains(serial))
  65. return;
  66. VectorBuffer& beginState = editStates_[serial];
  67. VectorBuffer deltaState;
  68. serial->Serializable::Save(deltaState);
  69. deltaState.Seek(0);
  70. if (beginState.GetSize() != deltaState.GetSize() ||
  71. memcmp(beginState.GetData(), deltaState.GetData(), deltaState.GetSize()))
  72. {
  73. SerializableEditOp* op = new SerializableEditOp(serial, beginState, deltaState);
  74. AddUndoOp(op);
  75. editStates_[serial] = deltaState;
  76. }
  77. }
  78. else if (editop == 2) // end
  79. {
  80. if (!editStates_.Contains(serial))
  81. return;
  82. UnsubscribeFromEvent(serial, E_SCENEEDITSERIALIZABLEUNDOREDO);
  83. editStates_.Erase(serial);
  84. }
  85. }
  86. void SceneEditHistory::Undo()
  87. {
  88. if (!undoHistory_.Size())
  89. return;
  90. SceneEditOp* op = undoHistory_.Back();
  91. undoHistory_.Pop();
  92. op->Undo();
  93. redoHistory_.Push(op);
  94. }
  95. void SceneEditHistory::Redo()
  96. {
  97. if (!redoHistory_.Size())
  98. return;
  99. SceneEditOp* op = redoHistory_.Back();
  100. redoHistory_.Pop();
  101. op->Redo();
  102. undoHistory_.Push(op);
  103. }
  104. }