From 6684c7b9b0b2e9eb5fa7513b1d1aa5381b4da8e6 Mon Sep 17 00:00:00 2001 From: Paul Licameli Date: Wed, 28 Jun 2017 00:31:18 -0400 Subject: [PATCH] More careful use of weak pointers to tracks in UIHandles --- src/SelectionState.cpp | 2 +- src/Track.h | 11 +++++++++++ src/TrackPanelResizeHandle.cpp | 8 ++++---- .../labeltrack/ui/LabelDefaultClickHandle.cpp | 2 +- src/tracks/labeltrack/ui/LabelTextHandle.cpp | 4 ++-- .../notetrack/ui/NoteTrackControls.cpp | 2 +- .../notetrack/ui/NoteTrackVRulerControls.cpp | 9 +++++---- .../wavetrack/ui/WaveTrackVRulerControls.cpp | 9 +++++---- src/tracks/ui/ButtonHandle.cpp | 7 ++++--- src/tracks/ui/SelectHandle.cpp | 17 +++++++++-------- src/tracks/ui/SelectHandle.h | 3 ++- src/tracks/ui/SliderHandle.cpp | 7 +++++++ src/tracks/ui/SliderHandle.h | 3 +-- 13 files changed, 53 insertions(+), 31 deletions(-) diff --git a/src/SelectionState.cpp b/src/SelectionState.cpp index 8aa2c12b7..4c786d805 100644 --- a/src/SelectionState.cpp +++ b/src/SelectionState.cpp @@ -130,7 +130,7 @@ void SelectionState::ChangeSelectionOnShiftClick Track* pFirst = nullptr; Track* pLast = nullptr; // We will either extend from the first or from the last. - auto pExtendFrom = mLastPickedTrack.lock(); + auto pExtendFrom = tracks.Lock(mLastPickedTrack); if( !pExtendFrom ) { TrackListIterator iter( &tracks ); diff --git a/src/Track.h b/src/Track.h index fa23c71bc..17639cc6c 100644 --- a/src/Track.h +++ b/src/Track.h @@ -606,6 +606,17 @@ class TrackList final : public wxEvtHandler, public ListOfTracks /// Mainly a test function. Uses a linear search, so could be slow. bool Contains(const Track * t) const; + // Return non-null only if the weak pointer is not, and the track is + // owned by this list; constant time. + template + std::shared_ptr Lock(const std::weak_ptr &wTrack) + { + auto pTrack = wTrack.lock(); + if (pTrack && this == pTrack->mList) + return pTrack; + return {}; + } + bool IsEmpty() const; int GetCount() const; diff --git a/src/TrackPanelResizeHandle.cpp b/src/TrackPanelResizeHandle.cpp index 1f9af69ae..c7e8d985b 100644 --- a/src/TrackPanelResizeHandle.cpp +++ b/src/TrackPanelResizeHandle.cpp @@ -153,7 +153,7 @@ UIHandle::Result TrackPanelResizeHandle::Click UIHandle::Result TrackPanelResizeHandle::Drag (const TrackPanelMouseEvent &evt, AudacityProject *pProject) { - auto pTrack = mpTrack.lock(); + auto pTrack = pProject->GetTracks()->Lock(mpTrack); if ( !pTrack ) return RefreshCode::Cancelled; @@ -338,7 +338,7 @@ UIHandle::Result TrackPanelResizeHandle::Release UIHandle::Result TrackPanelResizeHandle::Cancel(AudacityProject *pProject) { - auto pTrack = mpTrack.lock(); + auto pTrack = pProject->GetTracks()->Lock(mpTrack); if ( !pTrack ) return RefreshCode::Cancelled; @@ -357,7 +357,7 @@ UIHandle::Result TrackPanelResizeHandle::Cancel(AudacityProject *pProject) pTrack->SetHeight(mInitialUpperActualHeight); pTrack->SetMinimized(mInitialMinimized); #ifdef EXPERIMENTAL_OUTPUT_DISPLAY - if( !MONO_WAVE_PAN(mpTrack) ) + if( !MONO_WAVE_PAN(pTrack) ) #endif { next->SetHeight(mInitialActualHeight); @@ -371,7 +371,7 @@ UIHandle::Result TrackPanelResizeHandle::Cancel(AudacityProject *pProject) pTrack->SetHeight(mInitialActualHeight); pTrack->SetMinimized(mInitialMinimized); #ifdef EXPERIMENTAL_OUTPUT_DISPLAY - if( !MONO_WAVE_PAN(mpTrack) ) + if( !MONO_WAVE_PAN(pTrack) ) #endif { prev->SetHeight(mInitialUpperActualHeight); diff --git a/src/tracks/labeltrack/ui/LabelDefaultClickHandle.cpp b/src/tracks/labeltrack/ui/LabelDefaultClickHandle.cpp index a1aa45c00..9922612c3 100644 --- a/src/tracks/labeltrack/ui/LabelDefaultClickHandle.cpp +++ b/src/tracks/labeltrack/ui/LabelDefaultClickHandle.cpp @@ -53,7 +53,7 @@ void LabelDefaultClickHandle::RestoreState( AudacityProject *pProject ) { if ( mLabelState ) { for ( const auto &pair : mLabelState->mPairs ) - if (auto pLt = pair.first.lock()) + if (auto pLt = pProject->GetTracks()->Lock(pair.first)) pLt->RestoreFlags( pair.second ); mLabelState.reset(); } diff --git a/src/tracks/labeltrack/ui/LabelTextHandle.cpp b/src/tracks/labeltrack/ui/LabelTextHandle.cpp index 14376aa4e..02da82afa 100644 --- a/src/tracks/labeltrack/ui/LabelTextHandle.cpp +++ b/src/tracks/labeltrack/ui/LabelTextHandle.cpp @@ -122,7 +122,7 @@ UIHandle::Result LabelTextHandle::Drag auto result = LabelDefaultClickHandle::Drag( evt, pProject ); const wxMouseEvent &event = evt.event; - auto pLT = mpLT.lock(); + auto pLT = pProject->GetTracks()->Lock(mpLT); if(pLT) pLT->HandleTextDragRelease(event); @@ -170,7 +170,7 @@ UIHandle::Result LabelTextHandle::Release } const wxMouseEvent &event = evt.event; - auto pLT = mpLT.lock(); + auto pLT = pProject->GetTracks()->Lock(mpLT); if (pLT) pLT->HandleTextDragRelease(event); diff --git a/src/tracks/playabletrack/notetrack/ui/NoteTrackControls.cpp b/src/tracks/playabletrack/notetrack/ui/NoteTrackControls.cpp index b6a79d044..e6d6f81cb 100644 --- a/src/tracks/playabletrack/notetrack/ui/NoteTrackControls.cpp +++ b/src/tracks/playabletrack/notetrack/ui/NoteTrackControls.cpp @@ -121,7 +121,7 @@ UIHandle::Result NoteTrackClickHandle::Release { using namespace RefreshCode; - auto pTrack = mpTrack.lock(); + auto pTrack = pProject->GetTracks()->Lock(mpTrack); if (!pTrack) return Cancelled; diff --git a/src/tracks/playabletrack/notetrack/ui/NoteTrackVRulerControls.cpp b/src/tracks/playabletrack/notetrack/ui/NoteTrackVRulerControls.cpp index 26659517e..55f1b76f6 100644 --- a/src/tracks/playabletrack/notetrack/ui/NoteTrackVRulerControls.cpp +++ b/src/tracks/playabletrack/notetrack/ui/NoteTrackVRulerControls.cpp @@ -127,14 +127,15 @@ UIHandle::Result NoteTrackVZoomHandle::Drag (const TrackPanelMouseEvent &evt, AudacityProject *pProject) { using namespace RefreshCode; - if (!mpTrack.lock()) + auto pTrack = pProject->GetTracks()->Lock(mpTrack); + if (!pTrack) return Cancelled; const wxMouseEvent &event = evt.event; mZoomEnd = event.m_y; if (IsDragZooming(mZoomStart, mZoomEnd)) { // changed Note track to work like audio track - // mpTrack->VScroll(mZoomStart, mZoomEnd); + // pTrack->VScroll(mZoomStart, mZoomEnd); return RefreshAll; } return RefreshNone; @@ -151,7 +152,7 @@ UIHandle::Result NoteTrackVZoomHandle::Release wxWindow *pParent) { using namespace RefreshCode; - auto pTrack = mpTrack.lock(); + auto pTrack = pProject->GetTracks()->Lock(mpTrack); if (!pTrack) return RefreshNone; @@ -184,7 +185,7 @@ UIHandle::Result NoteTrackVZoomHandle::Cancel(AudacityProject *pProject) void NoteTrackVZoomHandle::DrawExtras (DrawingPass pass, wxDC * dc, const wxRegion &, const wxRect &panelRect) { - if (!mpTrack.lock()) + if (!mpTrack.lock()) //? TrackList::Lock() return; if ( pass == UIHandle::Cells && diff --git a/src/tracks/playabletrack/wavetrack/ui/WaveTrackVRulerControls.cpp b/src/tracks/playabletrack/wavetrack/ui/WaveTrackVRulerControls.cpp index 5ea79e776..ebf43a791 100644 --- a/src/tracks/playabletrack/wavetrack/ui/WaveTrackVRulerControls.cpp +++ b/src/tracks/playabletrack/wavetrack/ui/WaveTrackVRulerControls.cpp @@ -571,10 +571,11 @@ UIHandle::Result WaveTrackVZoomHandle::Click } UIHandle::Result WaveTrackVZoomHandle::Drag -(const TrackPanelMouseEvent &evt, AudacityProject *) +(const TrackPanelMouseEvent &evt, AudacityProject *pProject) { using namespace RefreshCode; - if (!mpTrack.lock()) + auto pTrack = pProject->GetTracks()->Lock(mpTrack); + if (!pTrack) return Cancelled; const wxMouseEvent &event = evt.event; @@ -595,7 +596,7 @@ UIHandle::Result WaveTrackVZoomHandle::Release wxWindow *pParent) { using namespace RefreshCode; - auto pTrack = mpTrack.lock(); + auto pTrack = pProject->GetTracks()->Lock(mpTrack); if (!pTrack) return RefreshNone; @@ -640,7 +641,7 @@ UIHandle::Result WaveTrackVZoomHandle::Cancel(AudacityProject*) void WaveTrackVZoomHandle::DrawExtras (DrawingPass pass, wxDC * dc, const wxRegion &, const wxRect &panelRect) { - if (!mpTrack.lock()) + if (!mpTrack.lock()) // TrackList::Lock()? return; if ( pass == UIHandle::Cells && diff --git a/src/tracks/ui/ButtonHandle.cpp b/src/tracks/ui/ButtonHandle.cpp index f5402055f..5663f3014 100644 --- a/src/tracks/ui/ButtonHandle.cpp +++ b/src/tracks/ui/ButtonHandle.cpp @@ -59,11 +59,12 @@ UIHandle::Result ButtonHandle::Click } UIHandle::Result ButtonHandle::Drag -(const TrackPanelMouseEvent &evt, AudacityProject *) +(const TrackPanelMouseEvent &evt, AudacityProject *pProject) { const wxMouseEvent &event = evt.event; using namespace RefreshCode; - if (!mpTrack.lock()) + auto pTrack = pProject->GetTracks()->Lock(mpTrack); + if (!pTrack) return Cancelled; const int newState = @@ -88,7 +89,7 @@ UIHandle::Result ButtonHandle::Release wxWindow *pParent) { using namespace RefreshCode; - auto pTrack = mpTrack.lock(); + auto pTrack = pProject->GetTracks()->Lock(mpTrack); if (!pTrack) return Cancelled; diff --git a/src/tracks/ui/SelectHandle.cpp b/src/tracks/ui/SelectHandle.cpp index 909e5e943..3b5b0acd4 100644 --- a/src/tracks/ui/SelectHandle.cpp +++ b/src/tracks/ui/SelectHandle.cpp @@ -617,7 +617,7 @@ UIHandle::Result SelectHandle::Click #endif mSelStartValid = true; mSelStart = value; - AdjustSelection(viewInfo, event.m_x, mRect.x, pTrack); + AdjustSelection(pProject, viewInfo, event.m_x, mRect.x, pTrack); break; } #ifdef EXPERIMENTAL_SPECTRAL_EDITING @@ -796,7 +796,7 @@ UIHandle::Result SelectHandle::Drag } // Also fuhggeddaboudit if not in a track. - auto pTrack = mpTrack.lock(); + auto pTrack = pProject->GetTracks()->Lock(mpTrack); if (!pTrack) return RefreshNone; @@ -836,13 +836,13 @@ UIHandle::Result SelectHandle::Drag (pProject, viewInfo, y, mRect.y, mRect.height, pTrack.get()); else #endif - if (mFreqSelTrack.lock() == pTrack) + if (pProject->GetTracks()->Lock(mFreqSelTrack) == pTrack) AdjustFreqSelection( static_cast(pTrack.get()), viewInfo, y, mRect.y, mRect.height); #endif - AdjustSelection(viewInfo, x, mRect.x, clickedTrack.get()); + AdjustSelection(pProject, viewInfo, x, mRect.x, clickedTrack.get()); } return RefreshNone @@ -997,7 +997,7 @@ void SelectHandle::OnTimer(wxCommandEvent &event) } } - auto pTrack = mpTrack.lock(); + auto pTrack = mpTrack.lock(); // TrackList::Lock() ? if (mAutoScrolling && pTrack) { // AS: To keep the selection working properly as we scroll, // we fake a mouse event (remember, this method is called @@ -1026,7 +1026,7 @@ void SelectHandle::StartSelection mSnapLeft = -1; mSnapRight = -1; bool snappedPoint, snappedTime; - auto pTrack = mpTrack.lock(); + auto pTrack = pProject->GetTracks()->Lock(mpTrack); if (mSnapManager->Snap(pTrack.get(), mSelStart, false, &s, &snappedPoint, &snappedTime)) { if (snappedPoint) @@ -1045,7 +1045,8 @@ void SelectHandle::StartSelection /// Extend or contract the existing selection void SelectHandle::AdjustSelection -(ViewInfo &viewInfo, int mouseXCoordinate, int trackLeftEdge, +(AudacityProject *pProject, + ViewInfo &viewInfo, int mouseXCoordinate, int trackLeftEdge, Track *track) { if (!mSelStartValid) @@ -1059,7 +1060,7 @@ void SelectHandle::AdjustSelection auto pTrack = Track::Pointer( track ); if (!pTrack) - pTrack = mpTrack.lock(); + pTrack = pProject->GetTracks()->Lock(mpTrack); if (mSelStart < selend) { sel0 = mSelStart; diff --git a/src/tracks/ui/SelectHandle.h b/src/tracks/ui/SelectHandle.h index 15ff1f998..73c18427c 100644 --- a/src/tracks/ui/SelectHandle.h +++ b/src/tracks/ui/SelectHandle.h @@ -74,7 +74,8 @@ private: void StartSelection (AudacityProject *pProject, int mouseXCoordinate, int trackLeftEdge); void AdjustSelection - (ViewInfo &viewInfo, int mouseXCoordinate, int trackLeftEdge, + (AudacityProject *pProject, + ViewInfo &viewInfo, int mouseXCoordinate, int trackLeftEdge, Track *pTrack); void StartFreqSelection diff --git a/src/tracks/ui/SliderHandle.cpp b/src/tracks/ui/SliderHandle.cpp index 83ba9071b..41b8ec955 100644 --- a/src/tracks/ui/SliderHandle.cpp +++ b/src/tracks/ui/SliderHandle.cpp @@ -12,6 +12,7 @@ Paul Licameli #include "SliderHandle.h" #include "../../widgets/ASlider.h" #include "../../HitTestResult.h" +#include "../../Project.h" #include "../../RefreshCode.h" #include "../../TrackPanelMouseEvent.h" @@ -98,3 +99,9 @@ UIHandle::Result SliderHandle::Cancel(AudacityProject *pProject) mpTrack.reset(); return RefreshCode::RefreshCell | result; } + +LWSlider *SliderHandle::GetSlider( AudacityProject *pProject ) +{ + auto pTrack = pProject->GetTracks()->Lock(mpTrack); + return mSliderFn( pProject, mRect, pTrack.get() ); +} diff --git a/src/tracks/ui/SliderHandle.h b/src/tracks/ui/SliderHandle.h index 7e1255365..d5408d5c3 100644 --- a/src/tracks/ui/SliderHandle.h +++ b/src/tracks/ui/SliderHandle.h @@ -61,8 +61,7 @@ protected: wxRect mRect{}; using SliderFn = LWSlider *(*)( AudacityProject*, const wxRect&, Track* ); SliderFn mSliderFn; - LWSlider *GetSlider( AudacityProject *pProject ) - { return mSliderFn( pProject, mRect, mpTrack.lock().get() ); } + LWSlider *GetSlider( AudacityProject *pProject ); float mStartingValue {}; };