From 4f7d308ca386df33ca1830ea248a4f26a1d0b1a5 Mon Sep 17 00:00:00 2001 From: Paul Licameli Date: Fri, 16 Feb 2018 14:49:26 -0500 Subject: [PATCH] Some inversion of control flow when popping Undo state --- src/Project.cpp | 7 ++++--- src/UndoManager.cpp | 19 ++++++------------- src/UndoManager.h | 8 +++++--- src/menus/EditMenus.cpp | 10 ++++------ 4 files changed, 19 insertions(+), 25 deletions(-) diff --git a/src/Project.cpp b/src/Project.cpp index 0354ed884..14429d661 100644 --- a/src/Project.cpp +++ b/src/Project.cpp @@ -4673,6 +4673,8 @@ void AudacityProject::ModifyState(bool bWantsAutoSave) // Need to keep it and its tracks "t" available for Undo/Redo/SetStateTo. void AudacityProject::PopState(const UndoState &state) { + mViewInfo.selectedRegion = state.selectedRegion; + // Restore tags mTags = state.tags; @@ -4725,9 +4727,8 @@ void AudacityProject::PopState(const UndoState &state) void AudacityProject::SetStateTo(unsigned int n) { - const UndoState &state = - GetUndoManager()->SetStateTo(n, &mViewInfo.selectedRegion); - PopState(state); + GetUndoManager()->SetStateTo(n, + [this]( const UndoState &state ){ PopState(state); } ); HandleResize(); mTrackPanel->SetFocusedTrack(NULL); diff --git a/src/UndoManager.cpp b/src/UndoManager.cpp index 79ecc7d58..5f2728b40 100644 --- a/src/UndoManager.cpp +++ b/src/UndoManager.cpp @@ -300,8 +300,7 @@ void UndoManager::PushState(const TrackList * l, lastAction = longDescription; } -const UndoState &UndoManager::SetStateTo - (unsigned int n, SelectedRegion *selectedRegion) +void UndoManager::SetStateTo(unsigned int n, const Consumer &consumer) { n -= 1; @@ -309,36 +308,30 @@ const UndoState &UndoManager::SetStateTo current = n; - *selectedRegion = stack[current]->state.selectedRegion; - lastAction = wxT(""); mayConsolidate = false; - return stack[current]->state; + consumer( stack[current]->state ); } -const UndoState &UndoManager::Undo(SelectedRegion *selectedRegion) +void UndoManager::Undo(const Consumer &consumer) { wxASSERT(UndoAvailable()); current--; - *selectedRegion = stack[current]->state.selectedRegion; - lastAction = wxT(""); mayConsolidate = false; - return stack[current]->state; + consumer( stack[current]->state ); } -const UndoState &UndoManager::Redo(SelectedRegion *selectedRegion) +void UndoManager::Redo(const Consumer &consumer) { wxASSERT(RedoAvailable()); current++; - *selectedRegion = stack[current]->state.selectedRegion; - /* if (!RedoAvailable()) { *sel0 = stack[current]->sel0; @@ -355,7 +348,7 @@ const UndoState &UndoManager::Redo(SelectedRegion *selectedRegion) lastAction = wxT(""); mayConsolidate = false; - return stack[current]->state; + consumer( stack[current]->state ); } bool UndoManager::UnsavedChanges() diff --git a/src/UndoManager.h b/src/UndoManager.h index bea72d5fe..0d368f1c8 100644 --- a/src/UndoManager.h +++ b/src/UndoManager.h @@ -118,9 +118,11 @@ class AUDACITY_DLL_API UndoManager { wxLongLong_t GetLongDescription(unsigned int n, wxString *desc, wxString *size); void SetLongDescription(unsigned int n, const wxString &desc); - const UndoState &SetStateTo(unsigned int n, SelectedRegion *selectedRegion); - const UndoState &Undo(SelectedRegion *selectedRegion); - const UndoState &Redo(SelectedRegion *selectedRegion); + // These functions accept a callback that uses the state + using Consumer = std::function< void( const UndoState & ) >; + void SetStateTo(unsigned int n, const Consumer &consumer); + void Undo(const Consumer &consumer); + void Redo(const Consumer &consumer); bool UndoAvailable(); bool RedoAvailable(); diff --git a/src/menus/EditMenus.cpp b/src/menus/EditMenus.cpp index 18926588a..b011b2923 100644 --- a/src/menus/EditMenus.cpp +++ b/src/menus/EditMenus.cpp @@ -219,7 +219,6 @@ void DoUndo(AudacityProject &project) { auto trackPanel = project.GetTrackPanel(); auto &undoManager = *project.GetUndoManager(); - auto &selectedRegion = project.GetViewInfo().selectedRegion; auto mixerBoard = project.GetMixerBoard(); auto historyWindow = project.GetHistoryWindow(); @@ -233,8 +232,8 @@ void DoUndo(AudacityProject &project) return; } - const UndoState &state = undoManager.Undo(&selectedRegion); - project.PopState(state); + undoManager.Undo( + [&]( const UndoState &state ){ project.PopState( state ); } ); trackPanel->EnsureVisible(trackPanel->GetFirstSelectedTrack()); @@ -264,7 +263,6 @@ void OnRedo(const CommandContext &context) auto &project = context.project; auto trackPanel = project.GetTrackPanel(); auto &undoManager = *project.GetUndoManager(); - auto &selectedRegion = project.GetViewInfo().selectedRegion; auto mixerBoard = project.GetMixerBoard(); auto historyWindow = project.GetHistoryWindow(); @@ -277,8 +275,8 @@ void OnRedo(const CommandContext &context) return; } - const UndoState &state = undoManager.Redo(&selectedRegion); - project.PopState(state); + undoManager.Redo( + [&]( const UndoState &state ){ project.PopState( state ); } ); trackPanel->EnsureVisible(trackPanel->GetFirstSelectedTrack());