diff --git a/src/Clipboard.cpp b/src/Clipboard.cpp index 93ff3f89c..5c5d23fd4 100644 --- a/src/Clipboard.cpp +++ b/src/Clipboard.cpp @@ -12,7 +12,7 @@ wxDEFINE_EVENT( EVT_CLIPBOARD_CHANGE, wxCommandEvent); Clipboard::Clipboard() -: mTracks { TrackList::Create() } +: mTracks { TrackList::Create( nullptr ) } { } diff --git a/src/ProjectAudioManager.cpp b/src/ProjectAudioManager.cpp index 6a6517969..d5395be8d 100644 --- a/src/ProjectAudioManager.cpp +++ b/src/ProjectAudioManager.cpp @@ -767,7 +767,7 @@ void ProjectAudioManager::SetupCutPreviewTracks(double WXUNUSED(playStart), doub { auto trackRange = TrackList::Get( *p ).Selected< const PlayableTrack >(); if( !trackRange.empty() ) { - auto cutPreviewTracks = TrackList::Create(); + auto cutPreviewTracks = TrackList::Create( nullptr ); for (const auto track1 : trackRange) { // Duplicate and change tracks // Clear has a very small chance of throwing diff --git a/src/ProjectFileManager.cpp b/src/ProjectFileManager.cpp index 59dd36b79..c0b4dee72 100644 --- a/src/ProjectFileManager.cpp +++ b/src/ProjectFileManager.cpp @@ -204,7 +204,7 @@ auto ProjectFileManager::ReadProjectFile( const FilePath &fileName ) // the version saved on disk will be preserved until the // user selects Save(). - mLastSavedTracks = TrackList::Create(); + mLastSavedTracks = TrackList::Create( nullptr ); auto &tracks = TrackList::Get( project ); for (auto t : tracks.Any()) { @@ -589,7 +589,7 @@ bool ProjectFileManager::DoSave (const bool fromSaveAs, if (mLastSavedTracks) mLastSavedTracks->Clear(); - mLastSavedTracks = TrackList::Create(); + mLastSavedTracks = TrackList::Create( nullptr ); auto &tracks = TrackList::Get( proj ); for ( auto t : tracks.Any() ) { @@ -643,7 +643,7 @@ bool ProjectFileManager::SaveCopyWaveTracks(const FilePath & strProjectPathName, // Copy the tracks because we're going to do some state changes before exporting. unsigned int numWaveTracks = 0; - auto ppSavedTrackList = TrackList::Create(); + auto ppSavedTrackList = TrackList::Create( nullptr ); auto &pSavedTrackList = *ppSavedTrackList; auto trackRange = tracks.Any< WaveTrack >(); diff --git a/src/Track.cpp b/src/Track.cpp index 44a86d058..cab2e4993 100644 --- a/src/Track.cpp +++ b/src/Track.cpp @@ -492,7 +492,7 @@ wxDEFINE_EVENT(EVT_TRACKLIST_DELETION, TrackListEvent); long TrackList::sCounter = -1; static const AudacityProject::AttachedObjects::RegisteredFactory key{ - [](AudacityProject&) { return TrackList::Create(); } + [](AudacityProject &project) { return TrackList::Create( &project ); } }; TrackList &TrackList::Get( AudacityProject &project ) @@ -505,17 +505,19 @@ const TrackList &TrackList::Get( const AudacityProject &project ) return Get( const_cast< AudacityProject & >( project ) ); } -TrackList::TrackList() +TrackList::TrackList( AudacityProject *pOwner ) : wxEvtHandler() +, mOwner{ pOwner } { } // Factory function -std::shared_ptr TrackList::Create() +std::shared_ptr TrackList::Create( AudacityProject *pOwner ) { - return std::make_shared(); + return std::make_shared( pOwner ); } +#if 0 TrackList &TrackList::operator= (TrackList &&that) { if (this != &that) { @@ -524,6 +526,7 @@ TrackList &TrackList::operator= (TrackList &&that) } return *this; } +#endif void TrackList::Swap(TrackList &that) { diff --git a/src/Track.h b/src/Track.h index 697f780ae..414daae37 100644 --- a/src/Track.h +++ b/src/Track.h @@ -285,9 +285,9 @@ public: bool HasOwner() const { return static_cast(GetOwner());} -private: std::shared_ptr GetOwner() const { return mList.lock(); } +private: Track *GetLink() const; bool GetLinked () const { return mLinked; } @@ -1141,9 +1141,9 @@ class TrackList final TrackList(const TrackList &that) = delete; TrackList &operator= (const TrackList&) = delete; - // Allow move - TrackList(TrackList &&that) : TrackList() { Swap(that); } - TrackList& operator= (TrackList&&); + // No need for move, disallow it + TrackList(TrackList &&that) = delete; + TrackList& operator= (TrackList&&) = delete; void clear() = delete; @@ -1153,10 +1153,10 @@ class TrackList final // Create an empty TrackList // Don't call directly -- use Create() instead - TrackList(); + explicit TrackList( AudacityProject *pOwner ); // Create an empty TrackList - static std::shared_ptr Create(); + static std::shared_ptr Create( AudacityProject *pOwner ); // Move is defined in terms of Swap void Swap(TrackList &that); @@ -1164,6 +1164,10 @@ class TrackList final // Destructor virtual ~TrackList(); + // Find the owning project, which may be null + AudacityProject *GetOwner() { return mOwner; } + const AudacityProject *GetOwner() const { return mOwner; } + // Iteration // Hide the inherited begin() and end() @@ -1561,6 +1565,8 @@ public: bool HasPendingTracks() const; private: + AudacityProject *mOwner; + // Need to put pending tracks into a list so that GetLink() works ListOfTracks mPendingUpdates; // This is in correspondence with mPendingUpdates diff --git a/src/UndoManager.cpp b/src/UndoManager.cpp index 7eee38ef6..e526ad330 100644 --- a/src/UndoManager.cpp +++ b/src/UndoManager.cpp @@ -254,7 +254,7 @@ void UndoManager::ModifyState(const TrackList * l, stack[current]->state.tracks.reset(); // Duplicate - auto tracksCopy = TrackList::Create(); + auto tracksCopy = TrackList::Create( nullptr ); for (auto t : *l) { if ( t->GetId() == TrackId{} ) // Don't copy a pending added track @@ -294,7 +294,7 @@ void UndoManager::PushState(const TrackList * l, return; } - auto tracksCopy = TrackList::Create(); + auto tracksCopy = TrackList::Create( nullptr ); for (auto t : *l) { if ( t->GetId() == TrackId{} ) // Don't copy a pending added track diff --git a/src/effects/Effect.cpp b/src/effects/Effect.cpp index 0d88f9d24..41b2b853d 100644 --- a/src/effects/Effect.cpp +++ b/src/effects/Effect.cpp @@ -1983,7 +1983,7 @@ void Effect::CopyInputTracks(bool allSyncLockSelected) mIMap.clear(); mOMap.clear(); - mOutputTracks = TrackList::Create(); + mOutputTracks = TrackList::Create( nullptr ); auto trackRange = mTracks->Any() + [&] (const Track *pTrack) { @@ -2271,7 +2271,9 @@ void Effect::Preview(bool dryOnly) } ); // Build NEW tracklist from rendering tracks - auto uTracks = TrackList::Create(); + // Set the same owning project, so FindProject() can see it within Process() + const auto pProject = saveTracks->GetOwner(); + auto uTracks = TrackList::Create( pProject ); mTracks = uTracks.get(); // Linear Effect preview optimised by pre-mixing to one track. diff --git a/src/effects/Equalization48x.cpp b/src/effects/Equalization48x.cpp index 8b2b6c6bb..f0650e6b8 100644 --- a/src/effects/Equalization48x.cpp +++ b/src/effects/Equalization48x.cpp @@ -339,7 +339,7 @@ bool EffectEqualization48x::TrackCompare() SecondIMap.clear(); SecondOMap.clear(); - auto pSecondOutputTracks = TrackList::Create(); + auto pSecondOutputTracks = TrackList::Create( nullptr ); auto &SecondOutputTracks = *pSecondOutputTracks; for (auto aTrack : diff --git a/src/menus/EditMenus.cpp b/src/menus/EditMenus.cpp index 55d02af73..29a51ef10 100644 --- a/src/menus/EditMenus.cpp +++ b/src/menus/EditMenus.cpp @@ -256,7 +256,7 @@ void OnCut(const CommandContext &context) auto &clipboard = Clipboard::Get(); clipboard.Clear(); - auto pNewClipboard = TrackList::Create(); + auto pNewClipboard = TrackList::Create( nullptr ); auto &newClipboard = *pNewClipboard; tracks.Selected().Visit( @@ -361,7 +361,7 @@ void OnCopy(const CommandContext &context) auto &clipboard = Clipboard::Get(); clipboard.Clear(); - auto pNewClipboard = TrackList::Create(); + auto pNewClipboard = TrackList::Create( nullptr ); auto &newClipboard = *pNewClipboard; for (auto n : tracks.Selected()) { @@ -681,7 +681,7 @@ void OnSplitCut(const CommandContext &context) auto &clipboard = Clipboard::Get(); clipboard.Clear(); - auto pNewClipboard = TrackList::Create(); + auto pNewClipboard = TrackList::Create( nullptr ); auto &newClipboard = *pNewClipboard; Track::Holder dest; diff --git a/src/menus/LabelMenus.cpp b/src/menus/LabelMenus.cpp index b779c7405..696068267 100644 --- a/src/menus/LabelMenus.cpp +++ b/src/menus/LabelMenus.cpp @@ -190,7 +190,7 @@ void EditClipboardByLabel( AudacityProject &project, auto &clipboard = Clipboard::Get(); clipboard.Clear(); - auto pNewClipboard = TrackList::Create(); + auto pNewClipboard = TrackList::Create( nullptr ); auto &newClipboard = *pNewClipboard; //Apply action on wavetracks starting from