ScriptCanvasUndoManager.cpp 3.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135
  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 <Editor/Undo/ScriptCanvasUndoManager.h>
  9. #include <AzCore/Serialization/ObjectStream.h>
  10. namespace ScriptCanvasEditor
  11. {
  12. static const int c_undoLimit = 100;
  13. // ScopedUndoBatch
  14. ScopedUndoBatch::ScopedUndoBatch(AZStd::string_view label)
  15. {
  16. UndoRequestBus::Broadcast(&UndoRequests::BeginUndoBatch, label);
  17. }
  18. ScopedUndoBatch::~ScopedUndoBatch()
  19. {
  20. UndoRequestBus::Broadcast(&UndoRequests::EndUndoBatch);
  21. }
  22. // SceneUndoState
  23. SceneUndoState::SceneUndoState(AzToolsFramework::UndoSystem::IUndoNotify* undoNotify)
  24. {
  25. m_undoStack = AZStd::make_unique<AzToolsFramework::UndoSystem::UndoStack>(c_undoLimit, undoNotify);
  26. m_undoCache = AZStd::make_unique<UndoCache>();
  27. }
  28. void SceneUndoState::BeginUndoBatch(AZStd::string_view label)
  29. {
  30. if (!m_currentUndoBatch)
  31. {
  32. m_currentUndoBatch = aznew AzToolsFramework::UndoSystem::BatchCommand(label, 0);
  33. }
  34. else
  35. {
  36. auto parentUndoBatch = m_currentUndoBatch;
  37. m_currentUndoBatch = aznew AzToolsFramework::UndoSystem::BatchCommand(label, 0);
  38. m_currentUndoBatch->SetParent(parentUndoBatch);
  39. }
  40. }
  41. void SceneUndoState::EndUndoBatch()
  42. {
  43. if (!m_currentUndoBatch)
  44. {
  45. return;
  46. }
  47. if (m_currentUndoBatch->GetParent())
  48. {
  49. // pop one up
  50. m_currentUndoBatch = m_currentUndoBatch->GetParent();
  51. }
  52. else
  53. {
  54. // we're at root
  55. if (m_currentUndoBatch->HasRealChildren() && m_undoStack)
  56. {
  57. m_undoStack->Post(m_currentUndoBatch);
  58. }
  59. else
  60. {
  61. delete m_currentUndoBatch;
  62. }
  63. m_currentUndoBatch = nullptr;
  64. }
  65. }
  66. SceneUndoState::~SceneUndoState()
  67. {
  68. delete m_currentUndoBatch;
  69. }
  70. // UndoCache
  71. void UndoCache::Clear()
  72. {
  73. m_dataMap.clear();
  74. }
  75. void UndoCache::PurgeCache(ScriptCanvas::ScriptCanvasId scriptCanvasId)
  76. {
  77. m_dataMap.erase(scriptCanvasId);
  78. }
  79. void UndoCache::PopulateCache(ScriptCanvas::ScriptCanvasId scriptCanvasId)
  80. {
  81. UpdateCache(scriptCanvasId);
  82. }
  83. void UndoCache::UpdateCache(ScriptCanvas::ScriptCanvasId scriptCanvasId)
  84. {
  85. // Lookup the graph item and perform a snapshot of all it's serialization elements
  86. UndoData undoData;
  87. UndoRequestBus::EventResult(undoData, scriptCanvasId, &UndoRequests::CreateUndoData);
  88. AZ::SerializeContext* serializeContext{};
  89. AZ::ComponentApplicationBus::BroadcastResult(serializeContext, &AZ::ComponentApplicationRequests::GetSerializeContext);
  90. AZStd::vector<AZ::u8>& newData = m_dataMap[scriptCanvasId];
  91. newData.clear();
  92. AZ::IO::ByteContainerStream<AZStd::vector<AZ::u8>> byteStream(&newData);
  93. AZ::ObjectStream* objStream = AZ::ObjectStream::Create(&byteStream, *serializeContext, AZ::DataStream::ST_BINARY);
  94. if (!objStream->WriteClass(&undoData))
  95. {
  96. AZ_Assert(false, "Unable to serialize Script Canvas scene and graph data for undo/redo");
  97. return;
  98. }
  99. objStream->Finalize();
  100. }
  101. const AZStd::vector<AZ::u8>& UndoCache::Retrieve(ScriptCanvas::ScriptCanvasId scriptCanvasId)
  102. {
  103. auto it = m_dataMap.find(scriptCanvasId);
  104. if (it == m_dataMap.end())
  105. {
  106. return m_emptyData;
  107. }
  108. return it->second;
  109. }
  110. }