ScriptCanvasUndoHelper.cpp 5.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203
  1. /*
  2. * Copyright (c) Contributors to the Open 3D Engine Project.
  3. * For complete copyright and license terms please see the LICENSE at the root of this distribution.
  4. *
  5. * SPDX-License-Identifier: Apache-2.0 OR MIT
  6. *
  7. */
  8. #include "ScriptCanvasUndoHelper.h"
  9. #include <Undo/ScriptCanvasGraphCommand.h>
  10. #include <ScriptCanvas/Components/EditorGraph.h>
  11. namespace ScriptCanvasEditor
  12. {
  13. UndoHelper::UndoHelper()
  14. : m_undoState(this)
  15. {
  16. }
  17. UndoHelper::UndoHelper(EditorGraph* graph)
  18. : m_undoState(this)
  19. {
  20. SetSource(graph);
  21. }
  22. UndoHelper::~UndoHelper()
  23. {
  24. UndoRequestBus::Handler::BusDisconnect();
  25. }
  26. void UndoHelper::SetSource(EditorGraph* graph)
  27. {
  28. m_graph = graph;
  29. UndoRequestBus::Handler::BusConnect(graph->GetScriptCanvasId());
  30. }
  31. ScriptCanvasEditor::UndoCache* UndoHelper::GetSceneUndoCache()
  32. {
  33. return m_undoState.m_undoCache.get();
  34. }
  35. ScriptCanvasEditor::UndoData UndoHelper::CreateUndoData()
  36. {
  37. AZ::EntityId graphCanvasGraphId = m_graph->GetGraphCanvasGraphId();
  38. ScriptCanvas::ScriptCanvasId scriptCanvasId = m_graph->GetScriptCanvasId();
  39. GraphCanvas::GraphModelRequestBus::Event(graphCanvasGraphId, &GraphCanvas::GraphModelRequests::OnSaveDataDirtied, graphCanvasGraphId);
  40. UndoData undoData;
  41. ScriptCanvas::GraphData* graphData{};
  42. ScriptCanvas::GraphRequestBus::EventResult(graphData, scriptCanvasId, &ScriptCanvas::GraphRequests::GetGraphData);
  43. const ScriptCanvas::VariableData* varData{};
  44. ScriptCanvas::GraphVariableManagerRequestBus::EventResult(varData, scriptCanvasId, &ScriptCanvas::GraphVariableManagerRequests::GetVariableDataConst);
  45. if (graphData && varData)
  46. {
  47. undoData.m_graphData = *graphData;
  48. undoData.m_variableData = *varData;
  49. EditorGraphRequestBus::EventResult(undoData.m_visualSaveData, scriptCanvasId, &EditorGraphRequests::GetGraphCanvasSaveData);
  50. }
  51. return undoData;
  52. }
  53. void UndoHelper::BeginUndoBatch(AZStd::string_view label)
  54. {
  55. m_undoState.BeginUndoBatch(label);
  56. }
  57. void UndoHelper::EndUndoBatch()
  58. {
  59. m_undoState.EndUndoBatch();
  60. }
  61. void UndoHelper::AddUndo(AzToolsFramework::UndoSystem::URSequencePoint* sequencePoint)
  62. {
  63. if (SceneUndoState* sceneUndoState = &m_undoState)
  64. {
  65. if (!sceneUndoState->m_currentUndoBatch)
  66. {
  67. sceneUndoState->m_undoStack->Post(sequencePoint);
  68. }
  69. else
  70. {
  71. sequencePoint->SetParent(sceneUndoState->m_currentUndoBatch);
  72. }
  73. }
  74. }
  75. void UndoHelper::AddGraphItemChangeUndo(AZStd::string_view undoLabel)
  76. {
  77. GraphItemChangeCommand* command = aznew GraphItemChangeCommand(undoLabel);
  78. command->Capture(m_graph, true);
  79. command->Capture(m_graph, false);
  80. AddUndo(command);
  81. }
  82. void UndoHelper::AddGraphItemAdditionUndo(AZStd::string_view undoLabel)
  83. {
  84. GraphItemAddCommand* command = aznew GraphItemAddCommand(undoLabel);
  85. command->Capture(m_graph, false);
  86. AddUndo(command);
  87. }
  88. void UndoHelper::AddGraphItemRemovalUndo(AZStd::string_view undoLabel)
  89. {
  90. GraphItemRemovalCommand* command = aznew GraphItemRemovalCommand(undoLabel);
  91. command->Capture(m_graph, true);
  92. AddUndo(command);
  93. }
  94. void UndoHelper::Undo()
  95. {
  96. AZ_PROFILE_FUNCTION(ScriptCanvas);
  97. SceneUndoState* sceneUndoState = &m_undoState;
  98. if (sceneUndoState)
  99. {
  100. AZ_Warning("Script Canvas", !sceneUndoState->m_currentUndoBatch, "Script Canvas Editor has an open undo batch when performing a redo operation");
  101. if (sceneUndoState->m_undoStack->CanUndo())
  102. {
  103. m_status = Status::InUndo;
  104. sceneUndoState->m_undoStack->Undo();
  105. m_status = Status::Idle;
  106. UpdateCache();
  107. }
  108. }
  109. }
  110. void UndoHelper::Redo()
  111. {
  112. AZ_PROFILE_FUNCTION(ScriptCanvas);
  113. SceneUndoState* sceneUndoState = &m_undoState;
  114. if (sceneUndoState)
  115. {
  116. AZ_Warning("Script Canvas", !sceneUndoState->m_currentUndoBatch, "Script Canvas Editor has an open undo batch when performing a redo operation");
  117. if (sceneUndoState->m_undoStack->CanRedo())
  118. {
  119. m_status = Status::InUndo;
  120. sceneUndoState->m_undoStack->Redo();
  121. m_status = Status::Idle;
  122. UpdateCache();
  123. }
  124. }
  125. }
  126. void UndoHelper::Reset()
  127. {
  128. if (SceneUndoState* sceneUndoState = &m_undoState)
  129. {
  130. AZ_Warning("Script Canvas", !sceneUndoState->m_currentUndoBatch, "Script Canvas Editor has an open undo batch when resetting the undo stack");
  131. sceneUndoState->m_undoStack->Reset();
  132. }
  133. }
  134. bool UndoHelper::IsIdle()
  135. {
  136. return m_status == Status::Idle;
  137. }
  138. bool UndoHelper::IsActive()
  139. {
  140. return m_status != Status::Idle;
  141. }
  142. bool UndoHelper::CanUndo() const
  143. {
  144. return m_undoState.m_undoStack->CanUndo();
  145. }
  146. bool UndoHelper::CanRedo() const
  147. {
  148. return m_undoState.m_undoStack->CanRedo();
  149. }
  150. void UndoHelper::OnUndoStackChanged()
  151. {
  152. UndoNotificationBus::Broadcast(&UndoNotifications::OnCanUndoChanged, m_undoState.m_undoStack->CanUndo());
  153. UndoNotificationBus::Broadcast(&UndoNotifications::OnCanRedoChanged, m_undoState.m_undoStack->CanRedo());
  154. }
  155. void UndoHelper::UpdateCache()
  156. {
  157. ScriptCanvas::ScriptCanvasId scriptCanvasId = m_graph->GetScriptCanvasId();
  158. UndoCache* undoCache = nullptr;
  159. UndoRequestBus::EventResult(undoCache, scriptCanvasId, &UndoRequests::GetSceneUndoCache);
  160. if (undoCache)
  161. {
  162. undoCache->UpdateCache(scriptCanvasId);
  163. }
  164. }
  165. }