SceneEditHistory.cpp 6.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240
  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. locked_(false)
  16. {
  17. SubscribeToEvent(E_HISTORYNODEADDED, HANDLER(SceneEditHistory, HandleHistoryNodeAdded));
  18. SubscribeToEvent(E_HISTORYNODEREMOVED, HANDLER(SceneEditHistory, HandleHistoryNodeRemoved));
  19. SubscribeToEvent(E_HISTORYNODECHANGED, HANDLER(SceneEditHistory, HandleHistoryNodeChanged));
  20. SubscribeToEvent(E_HISTORYCOMPONENTCHANGED, HANDLER(SceneEditHistory, HandleHistoryComponentChanged));
  21. SubscribeToEvent(E_EDITORACTIVENODECHANGE, HANDLER(SceneEditHistory, HandleEditorActiveNodeChange));
  22. }
  23. SceneEditHistory::~SceneEditHistory()
  24. {
  25. }
  26. void SceneEditHistory::AddUndoOp(SceneHistoryOp* op)
  27. {
  28. undoHistory_.Push(op);
  29. // adding a new undo op invalids redos
  30. for (unsigned i = 0; i < redoHistory_.Size(); i++)
  31. {
  32. delete redoHistory_[i];
  33. }
  34. redoHistory_.Clear();
  35. if (activeNode_.NotNull())
  36. {
  37. if (op->type_ == SCENEHISTORYOP_NODECHANGED)
  38. {
  39. activeNodeCurrentState_.Clear();
  40. activeNode_->Animatable::Save(activeNodeCurrentState_);
  41. activeNodeCurrentState_.Seek(0);
  42. }
  43. if (op->type_ == SCENEHISTORYOP_COMPONENTCHANGED)
  44. {
  45. ComponentChangedOp* ccop = (ComponentChangedOp*) op;
  46. currentComponentStates_[ccop->component_].Clear();
  47. ccop->component_->Animatable::Save(currentComponentStates_[ccop->component_]);
  48. currentComponentStates_[ccop->component_].Seek(0);
  49. }
  50. }
  51. }
  52. void SceneEditHistory::HandleHistoryNodeAdded(StringHash eventType, VariantMap& eventData)
  53. {
  54. if (locked_)
  55. return;
  56. Scene* scene = static_cast<Scene*>(eventData[HistoryNodeAdded::P_SCENE].GetPtr());
  57. if (scene != scene_)
  58. return;
  59. Node* node = static_cast<Node*>(eventData[HistoryNodeAdded::P_NODE].GetPtr());
  60. NodeAddedOp* op = new NodeAddedOp(node);
  61. AddUndoOp(op);
  62. }
  63. void SceneEditHistory::HandleHistoryNodeChanged(StringHash eventType, VariantMap& eventData)
  64. {
  65. if (locked_)
  66. return;
  67. Scene* scene = static_cast<Scene*>(eventData[HistoryNodeChanged::P_SCENE].GetPtr());
  68. if (scene != scene_)
  69. return;
  70. Node* node = static_cast<Node*>(eventData[HistoryNodeChanged::P_NODE].GetPtr());
  71. NodeChangedOp* op = new NodeChangedOp(node, activeNodeCurrentState_);
  72. if (activeNodeCurrentState_.GetSize() != op->newState_.GetSize() ||
  73. memcmp(activeNodeCurrentState_.GetData(), op->newState_.GetData(), op->newState_.GetSize()))
  74. {
  75. activeNodeCurrentState_ = op->newState_;
  76. AddUndoOp(op);
  77. }
  78. else
  79. {
  80. delete op;
  81. }
  82. }
  83. void SceneEditHistory::HandleHistoryNodeRemoved(StringHash eventType, VariantMap& eventData)
  84. {
  85. if (locked_)
  86. return;
  87. }
  88. void SceneEditHistory::HandleEditorActiveNodeChange(StringHash eventType, VariantMap& eventData)
  89. {
  90. Node* node = static_cast<Node*>(eventData[EditorActiveNodeChange::P_NODE].GetPtr());
  91. if (activeNode_ == node)
  92. return;
  93. activeNode_ = node;
  94. activeNodeCurrentState_.Clear();
  95. currentComponentStates_.Clear();
  96. if (activeNode_.Null())
  97. return;
  98. node->Animatable::Save(activeNodeCurrentState_);
  99. activeNodeCurrentState_.Seek(0);
  100. const Vector<SharedPtr<Component> >& comps = activeNode_->GetComponents();
  101. for (unsigned i = 0; i < comps.Size(); i++)
  102. {
  103. comps[i]->Animatable::Save(currentComponentStates_[comps[i]]);
  104. currentComponentStates_[comps[i]].Seek(0);
  105. }
  106. }
  107. void SceneEditHistory::HandleHistoryComponentChanged(StringHash eventType, VariantMap& eventData)
  108. {
  109. if (locked_)
  110. return;
  111. Component* component = static_cast<Component*>(eventData[HistoryComponentChanged::P_COMPONENT].GetPtr());
  112. if (!component || component->GetNode() != activeNode_)
  113. return;
  114. assert(currentComponentStates_.Contains(component));
  115. ComponentChangedOp* op = new ComponentChangedOp(component, currentComponentStates_[component]);
  116. if (currentComponentStates_[component].GetSize() != op->newState_.GetSize() ||
  117. memcmp(currentComponentStates_[component].GetData(), op->newState_.GetData(), op->newState_.GetSize()))
  118. {
  119. activeNodeCurrentState_ = op->newState_;
  120. AddUndoOp(op);
  121. }
  122. else
  123. {
  124. delete op;
  125. }
  126. }
  127. void SceneEditHistory::BeginUndoRedo()
  128. {
  129. //VariantMap evData;
  130. //evData[SceneUndoRedoBegin::P_SCENE] = scene_;
  131. //SendEvent(E_SCENEUNDOREDOBEGIN, evData);
  132. }
  133. void SceneEditHistory::EndUndoRedo()
  134. {
  135. //VariantMap evData;
  136. //evData[SceneUndoRedoEnd::P_SCENE] = scene_;
  137. //SendEvent(E_SCENEUNDOREDOEND, evData);
  138. }
  139. void SceneEditHistory::Undo()
  140. {
  141. if (!undoHistory_.Size())
  142. return;
  143. SceneHistoryOp* op = undoHistory_.Back();
  144. undoHistory_.Pop();
  145. op->Undo();
  146. VariantMap eventData;
  147. if (op->type_ == SCENEHISTORYOP_NODECHANGED)
  148. {
  149. NodeChangedOp* ncop = (NodeChangedOp*) op;
  150. eventData[HistoryNodeChangedUndoRedo::P_NODE] = ncop->node_;
  151. ncop->node_->SendEvent(E_HISTORYNODECHANGEDUNDOREDO, eventData);
  152. }
  153. else if (op->type_ == SCENEHISTORYOP_COMPONENTCHANGED)
  154. {
  155. ComponentChangedOp* ccop = (ComponentChangedOp*) op;
  156. eventData[HistoryComponentChangedUndoRedo::P_COMPONENT] = ccop->component_;
  157. ccop->component_->SendEvent(E_HISTORYCOMPONENTCHANGEDUNDOREDO, eventData);
  158. }
  159. redoHistory_.Push(op);
  160. }
  161. void SceneEditHistory::Redo()
  162. {
  163. if (!redoHistory_.Size())
  164. return;
  165. SceneHistoryOp* op = redoHistory_.Back();
  166. redoHistory_.Pop();
  167. op->Redo();
  168. undoHistory_.Push(op);
  169. VariantMap eventData;
  170. if (op->type_ == SCENEHISTORYOP_NODECHANGED)
  171. {
  172. NodeChangedOp* ncop = (NodeChangedOp*) op;
  173. eventData[HistoryNodeChangedUndoRedo::P_NODE] = ncop->node_;
  174. ncop->node_->SendEvent(E_HISTORYNODECHANGEDUNDOREDO, eventData);
  175. }
  176. else if (op->type_ == SCENEHISTORYOP_COMPONENTCHANGED)
  177. {
  178. ComponentChangedOp* ccop = (ComponentChangedOp*) op;
  179. eventData[HistoryComponentChangedUndoRedo::P_COMPONENT] = ccop->component_;
  180. ccop->component_->SendEvent(E_HISTORYCOMPONENTCHANGEDUNDOREDO, eventData);
  181. }
  182. }
  183. }