1
0
mirror of https://github.com/cookiengineer/audacity synced 2025-05-01 16:19:43 +02:00

Define TrackId to identify tracks across undo states

This commit is contained in:
Paul Licameli 2018-01-10 19:28:16 -05:00
parent 8b60e7f02d
commit bd2c7e6abc
3 changed files with 70 additions and 1 deletions

View File

@ -3585,6 +3585,10 @@ XMLTagHandler *AudacityProject::HandleXMLChild(const wxChar *tag)
return mTags.get();
}
// Note that TrackList::Add includes assignment of unique in-session TrackId
// to a reloaded track, though no promise that it equals the id it originally
// had
if (!wxStrcmp(tag, wxT("wavetrack"))) {
return mTracks->Add(mTrackFactory->NewWaveTrack());
}

View File

@ -82,6 +82,8 @@ Track::Track(const Track &orig)
// Copy all the track properties except the actual contents
void Track::Init(const Track &orig)
{
mId = orig.mId;
mDefaultName = orig.mDefaultName;
mName = orig.mName;
@ -739,6 +741,9 @@ DEFINE_EVENT_TYPE(EVT_TRACKLIST_PERMUTED);
DEFINE_EVENT_TYPE(EVT_TRACKLIST_RESIZING);
DEFINE_EVENT_TYPE(EVT_TRACKLIST_DELETION);
// same value as in the default constructed TrackId:
long TrackList::mCounter = -1;
TrackList::TrackList()
: wxEvtHandler()
{
@ -853,6 +858,17 @@ void TrackList::Permute(const std::vector<TrackNodePointer> &permutation)
PermutationEvent();
}
Track *TrackList::FindById( TrackId id )
{
// Linear search. Tracks in a project are usually very few.
// Search only the non-pending tracks.
auto it = std::find_if( ListOfTracks::begin(), ListOfTracks::end(),
[=](const ListOfTracks::value_type &ptr){ return ptr->GetId() == id; } );
if (it == ListOfTracks::end())
return {};
return it->get();
}
template<typename TrackKind>
Track *TrackList::Add(std::unique_ptr<TrackKind> &&t)
{
@ -862,6 +878,7 @@ Track *TrackList::Add(std::unique_ptr<TrackKind> &&t)
auto n = getPrev( getEnd() );
pTrack->SetOwner(mSelf, n);
pTrack->SetId( TrackId{ ++mCounter } );
RecalcPositions(n);
ResizingEvent(n);
return back().get();
@ -883,6 +900,7 @@ Track *TrackList::AddToHead(std::unique_ptr<TrackKind> &&t)
push_front(ListOfTracks::value_type(pTrack = t.release()));
auto n = getBegin();
pTrack->SetOwner(mSelf, n);
pTrack->SetId( TrackId{ ++mCounter } );
RecalcPositions(n);
ResizingEvent(n);
return front().get();
@ -899,6 +917,7 @@ Track *TrackList::Add(std::shared_ptr<TrackKind> &&t)
auto n = getPrev( getEnd() );
t->SetOwner(mSelf, n);
t->SetId( TrackId{ ++mCounter } );
RecalcPositions(n);
ResizingEvent(n);
return back().get();
@ -921,6 +940,7 @@ auto TrackList::Replace(Track * t, ListOfTracks::value_type &&with) ->
Track *pTrack = with.get();
*node = std::move(with);
pTrack->SetOwner(mSelf, node);
pTrack->SetId( t->GetId() );
RecalcPositions(node);
DeletionEvent();

View File

@ -64,6 +64,32 @@ using TrackNodePointer = ListOfTracks::iterator;
class ViewInfo;
// This is an in-session identifier of track objects across undo states
// It does not persist between sessions
// Default constructed value is not equal to the id of any track that has ever
// been added to a TrackList, or (directly or transitively) copied from such
// TrackIds are assigned uniquely across projects
class TrackId
{
public:
TrackId() : mValue(-1) {}
explicit TrackId (long value) : mValue(value) {}
bool operator == (const TrackId &other) const
{ return mValue == other.mValue; }
bool operator != (const TrackId &other) const
{ return mValue != other.mValue; }
// Define this in case you want to key a std::map on TrackId
// The operator does not mean anything else
bool operator < (const TrackId &other) const
{ return mValue < other.mValue; }
private:
long mValue;
};
class AUDACITY_DLL_API Track /* not final */
: public CommonTrackPanelCell, public XMLTagHandler
{
@ -72,6 +98,9 @@ class AUDACITY_DLL_API Track /* not final */
friend class SyncLockedTracksIterator;
// To be TrackDisplay
private:
TrackId mId;
protected:
std::weak_ptr<TrackList> mList;
TrackNodePointer mNode{};
@ -86,6 +115,11 @@ class AUDACITY_DLL_API Track /* not final */
bool mLinked;
bool mMinimized;
public:
TrackId GetId() const { return mId; }
private:
void SetId( TrackId id ) { mId = id; }
public:
// Given a bare pointer, find a shared_ptr. But this is not possible for
@ -617,16 +651,22 @@ class TrackList final : public wxEvtHandler, public ListOfTracks
/// For use in sorting: assume each iterator points into this list, no duplications
void Permute(const std::vector<TrackNodePointer> &permutation);
/// Add this Track or all children of this TrackList.
Track *FindById( TrackId id );
/// Add a Track, giving it a fresh id
template<typename TrackKind>
Track *Add(std::unique_ptr<TrackKind> &&t);
/// Add a Track, giving it a fresh id
template<typename TrackKind>
Track *AddToHead(std::unique_ptr<TrackKind> &&t);
/// Add a Track, giving it a fresh id
template<typename TrackKind>
Track *Add(std::shared_ptr<TrackKind> &&t);
/// Replace first track with second track, give back a holder
/// Give the replacement the same id as the replaced
ListOfTracks::value_type Replace(Track * t, ListOfTracks::value_type &&with);
/// Remove this Track or all children of this TrackList.
@ -743,6 +783,11 @@ private:
void SwapNodes(TrackNodePointer s1, TrackNodePointer s2);
std::weak_ptr<TrackList> mSelf;
// Nondecreasing during the session.
// Nonpersistent.
// Used to assign ids to added tracks.
static long mCounter;
};
class AUDACITY_DLL_API TrackFactory