mirror of
https://github.com/cookiengineer/audacity
synced 2025-06-21 23:00:06 +02:00
Some reimplementation of track iterators and GetLink() ...
... avoiding direct usage of the inherited end() and of the increment and decrement of the std::list iterators
This commit is contained in:
parent
9dd5b521ea
commit
242e9a5668
205
src/Track.cpp
205
src/Track.cpp
@ -209,20 +209,16 @@ Track *Track::GetLink() const
|
|||||||
|
|
||||||
if (!pList->isNull(mNode)) {
|
if (!pList->isNull(mNode)) {
|
||||||
if (mLinked) {
|
if (mLinked) {
|
||||||
auto next = mNode;
|
auto next = pList->getNext( mNode );
|
||||||
++next;
|
if ( !pList->isNull( next ) )
|
||||||
if (!pList->isNull(next)) {
|
|
||||||
return next->get();
|
return next->get();
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (pList->hasPrev(mNode)) {
|
auto prev = pList->getPrev( mNode );
|
||||||
auto prev = mNode;
|
if ( !pList->isNull( prev ) ) {
|
||||||
--prev;
|
|
||||||
auto track = prev->get();
|
auto track = prev->get();
|
||||||
if (track && track->GetLinked()) {
|
if (track && track->GetLinked())
|
||||||
return track;
|
return track;
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -332,7 +328,7 @@ TrackListIterator::TrackListIterator(TrackList * val)
|
|||||||
, cur{}
|
, cur{}
|
||||||
{
|
{
|
||||||
if (l)
|
if (l)
|
||||||
cur = l->ListOfTracks::begin();
|
cur = l->getBegin();
|
||||||
}
|
}
|
||||||
|
|
||||||
Track *TrackListIterator::StartWith(Track * val)
|
Track *TrackListIterator::StartWith(Track * val)
|
||||||
@ -362,13 +358,13 @@ Track *TrackListIterator::First(TrackList * val)
|
|||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
cur = l->ListOfTracks::begin();
|
cur = l->getBegin();
|
||||||
|
|
||||||
if (!l->isNull(cur)) {
|
if (!l->isNull(cur)) {
|
||||||
return cur->get();
|
return cur->get();
|
||||||
}
|
}
|
||||||
|
|
||||||
return NULL;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
Track *TrackListIterator::Last(bool skiplinked)
|
Track *TrackListIterator::Last(bool skiplinked)
|
||||||
@ -377,18 +373,19 @@ Track *TrackListIterator::Last(bool skiplinked)
|
|||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
cur = l->ListOfTracks::end();
|
cur = l->getPrev( l->getEnd() );
|
||||||
if (l->hasPrev(cur))
|
if ( l->isNull( cur ) )
|
||||||
--cur;
|
return nullptr;
|
||||||
else
|
|
||||||
return NULL;
|
|
||||||
|
|
||||||
// With skiplinked set, we won't return the second channel of a linked pair
|
// With skiplinked set, we won't return the second channel of a linked pair
|
||||||
if (skiplinked &&
|
if (skiplinked) {
|
||||||
l->hasPrev(cur) &&
|
auto prev = l->getPrev( cur );
|
||||||
!(*cur)->GetLinked() &&
|
if ( !l->isNull( prev ) &&
|
||||||
(*cur)->GetLink())
|
!(*cur)->GetLinked() &&
|
||||||
--cur;
|
(*cur)->GetLink()
|
||||||
|
)
|
||||||
|
cur = prev;
|
||||||
|
}
|
||||||
|
|
||||||
return cur->get();
|
return cur->get();
|
||||||
}
|
}
|
||||||
@ -403,27 +400,24 @@ Track *TrackListIterator::Next(bool skipLinked)
|
|||||||
return nullptr;
|
return nullptr;
|
||||||
|
|
||||||
if (skipLinked &&
|
if (skipLinked &&
|
||||||
(*cur)->GetLinked()) {
|
(*cur)->GetLinked())
|
||||||
++cur;
|
cur = l->getNext( cur );
|
||||||
}
|
|
||||||
|
|
||||||
#ifdef DEBUG_TLI // if we are debugging this bit
|
#ifdef DEBUG_TLI // if we are debugging this bit
|
||||||
wxASSERT_MSG((!cur || (*l).Contains((*cur).t)), wxT("cur invalid after skipping linked tracks.")); // check that cur is in the list
|
wxASSERT_MSG((!cur || (*l).Contains((*cur).t)), wxT("cur invalid after skipping linked tracks.")); // check that cur is in the list
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
if (!l->isNull(cur)) {
|
if (!l->isNull(cur))
|
||||||
++cur;
|
cur = l->getNext( cur );
|
||||||
}
|
|
||||||
|
|
||||||
#ifdef DEBUG_TLI // if we are debugging this bit
|
#ifdef DEBUG_TLI // if we are debugging this bit
|
||||||
wxASSERT_MSG((!cur || (*l).Contains((*cur).t)), wxT("cur invalid after moving to next track.")); // check that cur is in the list if it is not null
|
wxASSERT_MSG((!cur || (*l).Contains((*cur).t)), wxT("cur invalid after moving to next track.")); // check that cur is in the list if it is not null
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
if (!l->isNull(cur)) {
|
if (!l->isNull(cur))
|
||||||
return cur->get();
|
return cur->get();
|
||||||
}
|
|
||||||
|
|
||||||
return NULL;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
Track *TrackListIterator::Prev(bool skiplinked)
|
Track *TrackListIterator::Prev(bool skiplinked)
|
||||||
@ -431,17 +425,13 @@ Track *TrackListIterator::Prev(bool skiplinked)
|
|||||||
if (!l || l->isNull(cur))
|
if (!l || l->isNull(cur))
|
||||||
return nullptr;
|
return nullptr;
|
||||||
|
|
||||||
if (!l->hasPrev(cur)) {
|
cur = l->getPrev( cur );
|
||||||
l->setNull(cur);
|
if ( l->isNull( cur ) )
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
|
||||||
|
|
||||||
--cur;
|
if ( skiplinked ) {
|
||||||
|
auto prev = l->getPrev( cur );
|
||||||
if (skiplinked && l->hasPrev(cur)) {
|
if( !l->isNull( prev ) && (*prev)->GetLinked() )
|
||||||
auto prev = cur;
|
|
||||||
--prev;
|
|
||||||
if ((*prev)->GetLinked())
|
|
||||||
cur = prev;
|
cur = prev;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -458,20 +448,19 @@ Track *TrackListIterator::operator *() const
|
|||||||
|
|
||||||
Track *TrackListIterator::RemoveCurrent()
|
Track *TrackListIterator::RemoveCurrent()
|
||||||
{
|
{
|
||||||
if (!l || l->isNull(cur))
|
if ( !l || l->isNull( cur ) )
|
||||||
return nullptr;
|
return nullptr;
|
||||||
|
|
||||||
cur = l->Remove(cur->get());
|
cur = l->Remove( cur->get() );
|
||||||
|
|
||||||
#ifdef DEBUG_TLI // if we are debugging this bit
|
#ifdef DEBUG_TLI // if we are debugging this bit
|
||||||
wxASSERT_MSG((!cur || (*l).Contains((*cur).t)), wxT("cur invalid after deletion of track.")); // check that cur is in the list
|
wxASSERT_MSG((!cur || (*l).Contains((*cur).t)), wxT("cur invalid after deletion of track.")); // check that cur is in the list
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
if (!l->isNull(cur)) {
|
if ( !l->isNull( cur ) )
|
||||||
return cur->get();
|
return cur->get();
|
||||||
}
|
|
||||||
|
|
||||||
return NULL;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool TrackListIterator::operator == (const TrackListIterator &other) const
|
bool TrackListIterator::operator == (const TrackListIterator &other) const
|
||||||
@ -494,7 +483,7 @@ Track *TrackListCondIterator::StartWith(Track *val)
|
|||||||
Track *t = TrackListIterator::StartWith(val);
|
Track *t = TrackListIterator::StartWith(val);
|
||||||
|
|
||||||
if (t && !this->Condition(t))
|
if (t && !this->Condition(t))
|
||||||
return NULL;
|
return nullptr;
|
||||||
|
|
||||||
return t;
|
return t;
|
||||||
}
|
}
|
||||||
@ -655,11 +644,11 @@ Track *SyncLockedTracksIterator::Next(bool skiplinked)
|
|||||||
Track *t = TrackListIterator::Next(skiplinked);
|
Track *t = TrackListIterator::Next(skiplinked);
|
||||||
|
|
||||||
if (!t)
|
if (!t)
|
||||||
return NULL;
|
return nullptr;
|
||||||
|
|
||||||
if ( ! IsGoodNextTrack(t) ) {
|
if ( ! IsGoodNextTrack(t) ) {
|
||||||
l->setNull(cur);
|
cur = l->getEnd();
|
||||||
return NULL;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
mInLabelSection = ( t->GetKind() == Track::Label );
|
mInLabelSection = ( t->GetKind() == Track::Label );
|
||||||
@ -677,19 +666,19 @@ Track *SyncLockedTracksIterator::Prev(bool skiplinked)
|
|||||||
|
|
||||||
// Beginning of tracks
|
// Beginning of tracks
|
||||||
if (!t)
|
if (!t)
|
||||||
return NULL;
|
return nullptr;
|
||||||
|
|
||||||
const bool isLabel = ( t->GetKind() == Track::Label );
|
const bool isLabel = ( t->GetKind() == Track::Label );
|
||||||
const bool isSyncLockable = IsSyncLockableNonLabelTrack( t );
|
const bool isSyncLockable = IsSyncLockableNonLabelTrack( t );
|
||||||
|
|
||||||
if ( !( isLabel || isSyncLockable ) ) {
|
if ( !( isLabel || isSyncLockable ) ) {
|
||||||
l->setNull(cur);
|
cur = l->getEnd();
|
||||||
return NULL;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ( !mInLabelSection && isLabel ) {
|
if ( !mInLabelSection && isLabel ) {
|
||||||
l->setNull(cur);
|
cur = l->getEnd();
|
||||||
return NULL;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
mInLabelSection = isLabel;
|
mInLabelSection = isLabel;
|
||||||
@ -699,8 +688,8 @@ Track *SyncLockedTracksIterator::Prev(bool skiplinked)
|
|||||||
|
|
||||||
Track *SyncLockedTracksIterator::Last(bool skiplinked)
|
Track *SyncLockedTracksIterator::Last(bool skiplinked)
|
||||||
{
|
{
|
||||||
if (!l || l->isNull(cur))
|
if ( !l || l->isNull( cur ) )
|
||||||
return NULL;
|
return nullptr;
|
||||||
|
|
||||||
Track *t = cur->get();
|
Track *t = cur->get();
|
||||||
|
|
||||||
@ -780,16 +769,15 @@ TrackList::~TrackList()
|
|||||||
|
|
||||||
void TrackList::RecalcPositions(TrackNodePointer node)
|
void TrackList::RecalcPositions(TrackNodePointer node)
|
||||||
{
|
{
|
||||||
if (isNull(node)) {
|
if ( isNull( node ) )
|
||||||
return;
|
return;
|
||||||
}
|
|
||||||
Track *t;
|
Track *t;
|
||||||
int i = 0;
|
int i = 0;
|
||||||
int y = 0;
|
int y = 0;
|
||||||
|
|
||||||
if (hasPrev(node)) {
|
auto prev = getPrev( node );
|
||||||
auto prev = node;
|
if ( !isNull( prev ) ) {
|
||||||
--prev;
|
|
||||||
t = prev->get();
|
t = prev->get();
|
||||||
i = t->GetIndex() + 1;
|
i = t->GetIndex() + 1;
|
||||||
y = t->GetY() + t->GetHeight();
|
y = t->GetY() + t->GetHeight();
|
||||||
@ -834,7 +822,7 @@ void TrackList::Permute(const std::vector<TrackNodePointer> &permutation)
|
|||||||
Track *pTrack = track.get();
|
Track *pTrack = track.get();
|
||||||
pTrack->SetOwner(mSelf, insert(ListOfTracks::end(), std::move(track)));
|
pTrack->SetOwner(mSelf, insert(ListOfTracks::end(), std::move(track)));
|
||||||
}
|
}
|
||||||
auto n = ListOfTracks::begin();
|
auto n = getBegin();
|
||||||
RecalcPositions(n);
|
RecalcPositions(n);
|
||||||
PermutationEvent();
|
PermutationEvent();
|
||||||
}
|
}
|
||||||
@ -844,8 +832,9 @@ Track *TrackList::Add(std::unique_ptr<TrackKind> &&t)
|
|||||||
{
|
{
|
||||||
Track *pTrack;
|
Track *pTrack;
|
||||||
push_back(ListOfTracks::value_type(pTrack = t.release()));
|
push_back(ListOfTracks::value_type(pTrack = t.release()));
|
||||||
auto n = ListOfTracks::end();
|
|
||||||
--n;
|
auto n = getPrev( getEnd() );
|
||||||
|
|
||||||
pTrack->SetOwner(mSelf, n);
|
pTrack->SetOwner(mSelf, n);
|
||||||
RecalcPositions(n);
|
RecalcPositions(n);
|
||||||
ResizingEvent(n);
|
ResizingEvent(n);
|
||||||
@ -866,7 +855,7 @@ Track *TrackList::AddToHead(std::unique_ptr<TrackKind> &&t)
|
|||||||
{
|
{
|
||||||
Track *pTrack;
|
Track *pTrack;
|
||||||
push_front(ListOfTracks::value_type(pTrack = t.release()));
|
push_front(ListOfTracks::value_type(pTrack = t.release()));
|
||||||
auto n = ListOfTracks::begin();
|
auto n = getBegin();
|
||||||
pTrack->SetOwner(mSelf, n);
|
pTrack->SetOwner(mSelf, n);
|
||||||
RecalcPositions(n);
|
RecalcPositions(n);
|
||||||
ResizingEvent(n);
|
ResizingEvent(n);
|
||||||
@ -880,8 +869,9 @@ template<typename TrackKind>
|
|||||||
Track *TrackList::Add(std::shared_ptr<TrackKind> &&t)
|
Track *TrackList::Add(std::shared_ptr<TrackKind> &&t)
|
||||||
{
|
{
|
||||||
push_back(t);
|
push_back(t);
|
||||||
auto n = ListOfTracks::end();
|
|
||||||
--n;
|
auto n = getPrev( getEnd() );
|
||||||
|
|
||||||
t->SetOwner(mSelf, n);
|
t->SetOwner(mSelf, n);
|
||||||
RecalcPositions(n);
|
RecalcPositions(n);
|
||||||
ResizingEvent(n);
|
ResizingEvent(n);
|
||||||
@ -915,18 +905,18 @@ auto TrackList::Replace(Track * t, ListOfTracks::value_type &&with) ->
|
|||||||
|
|
||||||
TrackNodePointer TrackList::Remove(Track *t)
|
TrackNodePointer TrackList::Remove(Track *t)
|
||||||
{
|
{
|
||||||
auto result = ListOfTracks::end();
|
auto result = getEnd();
|
||||||
if (t) {
|
if (t) {
|
||||||
auto node = t->GetNode();
|
auto node = t->GetNode();
|
||||||
t->SetOwner({}, {});
|
t->SetOwner({}, {});
|
||||||
|
|
||||||
if (!isNull(node)) {
|
if ( !isNull( node ) ) {
|
||||||
ListOfTracks::value_type holder = std::move( *node );
|
ListOfTracks::value_type holder = std::move( *node );
|
||||||
|
|
||||||
result = erase(node);
|
result = getNext( node );
|
||||||
if (!isNull(result)) {
|
erase(node);
|
||||||
|
if ( !isNull( result ) )
|
||||||
RecalcPositions(result);
|
RecalcPositions(result);
|
||||||
}
|
|
||||||
|
|
||||||
DeletionEvent();
|
DeletionEvent();
|
||||||
}
|
}
|
||||||
@ -951,19 +941,17 @@ void TrackList::Select(Track * t, bool selected /* = true */ )
|
|||||||
{
|
{
|
||||||
if (t) {
|
if (t) {
|
||||||
const auto node = t->GetNode();
|
const auto node = t->GetNode();
|
||||||
if (!isNull(node)) {
|
if ( !isNull( node ) ) {
|
||||||
t->SetSelected(selected);
|
t->SetSelected( selected );
|
||||||
auto next = node;
|
if ( t->GetLinked() ) {
|
||||||
++next;
|
auto next = getNext( node );
|
||||||
if (t->GetLinked() && !isNull(next)) {
|
if ( !isNull( next ) )
|
||||||
(*next)->SetSelected(selected);
|
(*next)->SetSelected( selected );
|
||||||
}
|
}
|
||||||
else if (hasPrev(node)) {
|
else {
|
||||||
auto prev = node;
|
auto prev = getPrev( node );
|
||||||
--prev;
|
if ( !isNull( prev ) && (*prev)->GetLinked() )
|
||||||
if ((*prev)->GetLinked()) {
|
(*prev)->SetSelected( selected );
|
||||||
(*prev)->SetSelected(selected);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -974,50 +962,55 @@ Track *TrackList::GetNext(Track * t, bool linked) const
|
|||||||
{
|
{
|
||||||
if (t) {
|
if (t) {
|
||||||
auto node = t->GetNode();
|
auto node = t->GetNode();
|
||||||
if (!isNull(node)) {
|
if ( !isNull( node ) ) {
|
||||||
if (linked && t->GetLinked()) {
|
if ( linked && t->GetLinked() )
|
||||||
++node;
|
node = getNext( node );
|
||||||
}
|
|
||||||
|
|
||||||
if (!isNull(node)) {
|
if ( !isNull( node ) )
|
||||||
++node;
|
node = getNext( node );
|
||||||
}
|
|
||||||
|
|
||||||
if (!isNull(node)) {
|
if ( !isNull( node ) )
|
||||||
return node->get();
|
return node->get();
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return NULL;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
Track *TrackList::GetPrev(Track * t, bool linked) const
|
Track *TrackList::GetPrev(Track * t, bool linked) const
|
||||||
{
|
{
|
||||||
if (t) {
|
if (t) {
|
||||||
|
TrackNodePointer prev;
|
||||||
auto node = t->GetNode();
|
auto node = t->GetNode();
|
||||||
if (!isNull(node)) {
|
if ( !isNull( node ) ) {
|
||||||
// linked is true and input track second in team?
|
// linked is true and input track second in team?
|
||||||
if (linked && hasPrev(node) &&
|
if (linked) {
|
||||||
!t->GetLinked() && t->GetLink())
|
prev = getPrev( node );
|
||||||
|
if( !isNull( prev ) &&
|
||||||
|
!t->GetLinked() && t->GetLink() )
|
||||||
// Make it the first
|
// Make it the first
|
||||||
--node;
|
node = prev;
|
||||||
|
}
|
||||||
|
|
||||||
if (hasPrev(node)) {
|
prev = getPrev( node );
|
||||||
|
if ( !isNull( prev ) ) {
|
||||||
// Back up once
|
// Back up once
|
||||||
--node;
|
node = prev;
|
||||||
|
|
||||||
// Back up twice sometimes when linked is true
|
// Back up twice sometimes when linked is true
|
||||||
if (linked && hasPrev(node) &&
|
if (linked) {
|
||||||
!(*node)->GetLinked() && (*node)->GetLink())
|
prev = getPrev( node );
|
||||||
--node;
|
if( !isNull( prev ) &&
|
||||||
|
!(*node)->GetLinked() && (*node)->GetLink() )
|
||||||
|
node = prev;
|
||||||
|
}
|
||||||
|
|
||||||
return node->get();
|
return node->get();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return NULL;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// For mono track height of track
|
/// For mono track height of track
|
||||||
@ -1152,7 +1145,7 @@ size_t TrackList::size() const
|
|||||||
int cnt = 0;
|
int cnt = 0;
|
||||||
|
|
||||||
if (!empty())
|
if (!empty())
|
||||||
cnt = back()->GetIndex() + 1;
|
cnt = getPrev( getEnd() )->get()->GetIndex() + 1;
|
||||||
|
|
||||||
return cnt;
|
return cnt;
|
||||||
}
|
}
|
||||||
@ -1290,7 +1283,7 @@ int TrackList::GetHeight() const
|
|||||||
int height = 0;
|
int height = 0;
|
||||||
|
|
||||||
if (!empty()) {
|
if (!empty()) {
|
||||||
const auto &track = back();
|
auto track = getPrev( getEnd() )->get();
|
||||||
height = track->GetY() + track->GetHeight();
|
height = track->GetY() + track->GetHeight();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
28
src/Track.h
28
src/Track.h
@ -688,10 +688,30 @@ class TrackList final : public wxEvtHandler, public ListOfTracks
|
|||||||
private:
|
private:
|
||||||
bool isNull(TrackNodePointer p) const
|
bool isNull(TrackNodePointer p) const
|
||||||
{ return p == ListOfTracks::end(); }
|
{ return p == ListOfTracks::end(); }
|
||||||
void setNull(TrackNodePointer &p)
|
TrackNodePointer getEnd() const
|
||||||
{ p = ListOfTracks::end(); }
|
{ return const_cast<TrackList*>(this)->ListOfTracks::end(); }
|
||||||
bool hasPrev(TrackNodePointer p) const
|
TrackNodePointer getBegin() const
|
||||||
{ return p != ListOfTracks::begin(); }
|
{ return const_cast<TrackList*>(this)->ListOfTracks::begin(); }
|
||||||
|
|
||||||
|
// Move an iterator to the next node, if any; else stay at end
|
||||||
|
TrackNodePointer getNext(TrackNodePointer p) const
|
||||||
|
{
|
||||||
|
if ( isNull(p) )
|
||||||
|
return p;
|
||||||
|
auto q = p;
|
||||||
|
return ++q;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Move an iterator to the previous node, if any; else wrap to end
|
||||||
|
TrackNodePointer getPrev(TrackNodePointer p) const
|
||||||
|
{
|
||||||
|
if (p == this->ListOfTracks::begin())
|
||||||
|
return getEnd();
|
||||||
|
else {
|
||||||
|
auto q = p;
|
||||||
|
return --q;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void DoAssign(const TrackList &that);
|
void DoAssign(const TrackList &that);
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user