From a2e22dc17b8f3ff56f5d5dc3aa6ff90284335cd0 Mon Sep 17 00:00:00 2001 From: Paul Licameli Date: Sun, 6 Sep 2020 16:27:19 -0400 Subject: [PATCH] TransactionScope for performance also when abandoning redo states --- src/HistoryWindow.cpp | 2 +- src/ProjectManager.cpp | 2 +- src/UndoManager.cpp | 27 ++++++++++++--------------- src/UndoManager.h | 5 ++++- src/menus/FileMenus.cpp | 2 +- 5 files changed, 19 insertions(+), 19 deletions(-) diff --git a/src/HistoryWindow.cpp b/src/HistoryWindow.cpp index e8aeb8891..034c0704c 100644 --- a/src/HistoryWindow.cpp +++ b/src/HistoryWindow.cpp @@ -269,7 +269,7 @@ void HistoryDialog::OnDiscard(wxCommandEvent & WXUNUSED(event)) int i = mLevels->GetValue(); mSelected -= i; - mManager->RemoveStates(i); + mManager->RemoveStates(0, i); ProjectHistory::Get( *mProject ).SetStateTo(mSelected); while(--i >= 0) diff --git a/src/ProjectManager.cpp b/src/ProjectManager.cpp index 8c1b3338b..b9707e0dd 100644 --- a/src/ProjectManager.cpp +++ b/src/ProjectManager.cpp @@ -899,7 +899,7 @@ AudacityProject *ProjectManager::OpenProject( window.Zoom( window.GetZoomOfToFit() ); // "Project was recovered" replaces "Create new project" in Undo History. auto &undoManager = UndoManager::Get( *pProject ); - undoManager.RemoveStates(1); + undoManager.RemoveStates(0, 1); } return pProject; diff --git a/src/UndoManager.cpp b/src/UndoManager.cpp index 35f516532..48a7dc02f 100644 --- a/src/UndoManager.cpp +++ b/src/UndoManager.cpp @@ -180,18 +180,20 @@ void UndoManager::RemoveStateAt(int n) } -void UndoManager::RemoveStates(int num) +void UndoManager::RemoveStates(size_t begin, size_t end) { Optional pTrans; auto pConnection = ConnectionPtr::Get(mProject).mpConnection.get(); if (pConnection) pTrans.emplace(*pConnection, "DiscardingUndoStates"); - for (int i = 0; i < num; i++) { - RemoveStateAt(0); + for (size_t ii = begin; ii < end; ++ii) { + RemoveStateAt(begin); - current -= 1; - saved -= 1; + if (current > begin) + --current; + if (saved > begin) + --saved; } if (pTrans) @@ -200,7 +202,7 @@ void UndoManager::RemoveStates(int num) void UndoManager::ClearStates() { - RemoveStates(stack.size()); + RemoveStates(0, stack.size()); current = -1; saved = -1; } @@ -264,8 +266,6 @@ void UndoManager::PushState(const TrackList * l, const TranslatableString &shortDescription, UndoPush flags) { - unsigned int i; - if ( (flags & UndoPush::CONSOLIDATE) != UndoPush::NONE && // compare full translations not msgids! lastAction.Translation() == longDescription.Translation() && @@ -289,10 +289,11 @@ void UndoManager::PushState(const TrackList * l, mayConsolidate = true; - i = current + 1; - while (i < stack.size()) { - RemoveStateAt(i); + // Abandon redo states + if (saved >= current) { + saved = -1; } + RemoveStates( current + 1, stack.size() ); // Assume tags was duplicated before any changes. // Just save a NEW shared_ptr to it. @@ -304,10 +305,6 @@ void UndoManager::PushState(const TrackList * l, current++; - if (saved >= current) { - saved = -1; - } - lastAction = longDescription; // wxWidgets will own the event object diff --git a/src/UndoManager.h b/src/UndoManager.h index 801a413e4..d580baaac 100644 --- a/src/UndoManager.h +++ b/src/UndoManager.h @@ -132,7 +132,10 @@ class AUDACITY_DLL_API UndoManager final void ModifyState(const TrackList * l, const SelectedRegion &selectedRegion, const std::shared_ptr &tags); void ClearStates(); - void RemoveStates(int num); // removes the 'num' oldest states + void RemoveStates( + size_t begin, //!< inclusive start of range + size_t end //!< exclusive end of range + ); unsigned int GetNumStates(); unsigned int GetCurrentState(); diff --git a/src/menus/FileMenus.cpp b/src/menus/FileMenus.cpp index 1541931b0..32c79e6a1 100644 --- a/src/menus/FileMenus.cpp +++ b/src/menus/FileMenus.cpp @@ -235,7 +235,7 @@ void OnCompact(const CommandContext &context) // Now we can remove all previous states. auto numStates = undoManager.GetNumStates(); - undoManager.RemoveStates(numStates - 1); + undoManager.RemoveStates(0, numStates - 1); // And clear the clipboard clipboard.Clear();