From fb1fd171cbf4adcba30d16130949328a8fd62e1c Mon Sep 17 00:00:00 2001 From: Chris Danford Date: Mon, 15 Jan 2007 11:30:40 +0000 Subject: [PATCH] add bInclusive option to _all_tracks_iterator --- stepmania/src/NoteData.cpp | 78 ++++++++++++++++++++++---------------- stepmania/src/NoteData.h | 38 ++++++++++--------- 2 files changed, 66 insertions(+), 50 deletions(-) diff --git a/stepmania/src/NoteData.cpp b/stepmania/src/NoteData.cpp index efd2eb7b0a..c49fdb7b26 100644 --- a/stepmania/src/NoteData.cpp +++ b/stepmania/src/NoteData.cpp @@ -921,21 +921,23 @@ void NoteData::_all_tracks_iterator::Find( bool bReverse ) m_iTrack = -1; if( bReverse ) { - int iMaxRow = m_iStartRow - 1; + int iMaxRow = INT_MIN; for( int iTrack = m_NoteData.GetNumTracks() - 1; iTrack >= 0; --iTrack ) { - iter &i( m_vIters[iTrack] ); + iter &i( m_vCurrentIters[iTrack] ); + const iter &begin = m_vBeginIters[iTrack]; + const iter &end = m_vEndIters[iTrack]; if( m_Cond ) { - while( i != m_NoteData.end(iTrack) && i->first > iMaxRow && !m_Cond(i->second) ) + while( i != end && i->first > iMaxRow && !m_Cond(i->second) ) { - if( i == m_NoteData.begin(iTrack) ) - i = m_NoteData.end( iTrack ); + if( i == begin ) + i = end; else --i; } } - if( i != m_NoteData.end(iTrack) && i->first > iMaxRow ) + if( i != end && i->first > iMaxRow ) { iMaxRow = i->first; m_iTrack = iTrack; @@ -944,16 +946,18 @@ void NoteData::_all_tracks_iterator::Find( bool bReverse ) } else { - int iMinRow = m_iEndRow + 1; + + int iMinRow = INT_MAX; for( int iTrack = 0; iTrack < m_NoteData.GetNumTracks(); ++iTrack ) { - iter &i = m_vIters[iTrack]; + iter &i = m_vCurrentIters[iTrack]; + const iter &end = m_vEndIters[iTrack]; if( m_Cond ) { - while( i != m_NoteData.end(iTrack) && i->first < iMinRow && !m_Cond(i->second) ) + while( i != end && i->first < iMinRow && !m_Cond(i->second) ) ++i; } - if( i != m_NoteData.end(iTrack) && i->first < iMinRow ) + if( i != end && i->first < iMinRow ) { iMinRow = i->first; m_iTrack = iTrack; @@ -963,27 +967,35 @@ void NoteData::_all_tracks_iterator::Find( bool bReverse ) } template -NoteData::_all_tracks_iterator::_all_tracks_iterator( ND &nd, int iStartRow, int iEndRow, bool bReverse, NoteData::IteratorCond cond ) : - m_NoteData(nd), m_iTrack(0), m_iStartRow(iStartRow), m_iEndRow(iEndRow), m_bReverse(bReverse), m_Cond(cond) +NoteData::_all_tracks_iterator::_all_tracks_iterator( ND &nd, int iStartRow, int iEndRow, bool bReverse, NoteData::IteratorCond cond, bool bInclusive ) : + m_NoteData(nd), m_iTrack(0), m_bReverse(bReverse), m_Cond(cond) { ASSERT( m_NoteData.GetNumTracks() > 0 ); - if( bReverse ) + + for( int iTrack = 0; iTrack < m_NoteData.GetNumTracks(); ++iTrack ) { - for( int iTrack = 0; iTrack < m_NoteData.GetNumTracks(); ++iTrack ) + NoteData::iterator begin, end; + if( bInclusive ) + m_NoteData.GetTapNoteRangeInclusive( iTrack, iStartRow, iEndRow, begin, end ); + else + m_NoteData.GetTapNoteRange( iTrack, iStartRow, iEndRow, begin, end ); + + m_vBeginIters.push_back( begin ); + m_vEndIters.push_back( end ); + + NoteData::iterator cur; + if( m_bReverse ) { - iter i = m_NoteData.upper_bound( iTrack, iEndRow ); - - if( i == m_NoteData.begin(iTrack) ) - m_vIters.push_back( m_NoteData.end(iTrack) ); - else - m_vIters.push_back( --i ); + cur = end; + cur--; } + else + { + cur = begin; + } + m_vCurrentIters.push_back( cur ); } - else - { - for( int iTrack = 0; iTrack < m_NoteData.GetNumTracks(); ++iTrack ) - m_vIters.push_back( m_NoteData.lower_bound(iTrack, iStartRow) ); - } + Find( bReverse ); } @@ -992,14 +1004,14 @@ NoteData::_all_tracks_iterator &NoteData::_all_tracks_iterator &NoteData::_all_tracks_iterator m_vIters; + vector m_vBeginIters; + + /* There isn't a "past the beginning" iterator so this is hard to make a true bidirectional iterator. + * Use the "past the end" iterator in place of the "past the beginning" iterator when in reverse. */ + vector m_vCurrentIters; + + vector m_vEndIters; int m_iTrack; - const int m_iStartRow; - const int m_iEndRow; const bool m_bReverse; IteratorCond m_Cond; void Find( bool bReverse ); public: - _all_tracks_iterator( ND &nd, int iStartRow, int iEndRow, bool bReverse, IteratorCond cond ); + _all_tracks_iterator( ND &nd, int iStartRow, int iEndRow, bool bReverse, IteratorCond cond, bool bInclusive ); _all_tracks_iterator &operator++(); // preincrement _all_tracks_iterator operator++( int dummy ); // postincrement //_all_tracks_iterator &operator--(); // predecrement //_all_tracks_iterator operator--( int dummy ); // postdecrement inline int Track() const { return m_iTrack; } - inline int Row() const { return m_vIters[m_iTrack]->first; } + inline int Row() const { return m_vCurrentIters[m_iTrack]->first; } inline bool IsAtEnd() const { return m_iTrack == -1; } - inline TN &operator*() { DEBUG_ASSERT( !IsAtEnd() ); return m_vIters[m_iTrack]->second; } - inline TN *operator->() { DEBUG_ASSERT( !IsAtEnd() ); return &m_vIters[m_iTrack]->second; } - inline const TN &operator*() const { DEBUG_ASSERT( !IsAtEnd() ); return m_vIters[m_iTrack]->second; } - inline const TN *operator->() const { DEBUG_ASSERT( !IsAtEnd() ); return &m_vIters[m_iTrack]->second; } + inline TN &operator*() { DEBUG_ASSERT( !IsAtEnd() ); return m_vCurrentIters[m_iTrack]->second; } + inline TN *operator->() { DEBUG_ASSERT( !IsAtEnd() ); return &m_vCurrentIters[m_iTrack]->second; } + inline const TN &operator*() const { DEBUG_ASSERT( !IsAtEnd() ); return m_vCurrentIters[m_iTrack]->second; } + inline const TN *operator->() const { DEBUG_ASSERT( !IsAtEnd() ); return &m_vCurrentIters[m_iTrack]->second; } }; typedef _all_tracks_iterator all_tracks_iterator; typedef _all_tracks_iterator all_tracks_const_iterator; @@ -109,21 +113,21 @@ public: /* Return an iterator range including exactly iStartRow to iEndRow. */ void GetTapNoteRange( int iTrack, int iStartRow, int iEndRow, const_iterator &begin, const_iterator &end ) const; void GetTapNoteRange( int iTrack, int iStartRow, int iEndRow, TrackMap::iterator &begin, TrackMap::iterator &end ); - all_tracks_iterator GetTapNoteRangeAllTracks( int iStartRow, int iEndRow, IteratorCond cond = NULL ) + all_tracks_iterator GetTapNoteRangeAllTracks( int iStartRow, int iEndRow, IteratorCond cond = NULL, bool bInclusive = false ) { - return all_tracks_iterator( *this, iStartRow, iEndRow, false, cond ); + return all_tracks_iterator( *this, iStartRow, iEndRow, false, cond, bInclusive ); } - all_tracks_const_iterator GetTapNoteRangeAllTracks( int iStartRow, int iEndRow, IteratorCond cond = NULL) const + all_tracks_const_iterator GetTapNoteRangeAllTracks( int iStartRow, int iEndRow, IteratorCond cond = NULL, bool bInclusive = false ) const { - return all_tracks_const_iterator( *this, iStartRow, iEndRow, false, cond ); + return all_tracks_const_iterator( *this, iStartRow, iEndRow, false, cond, bInclusive ); } - all_tracks_reverse_iterator GetTapNoteRangeAllTracksReverse( int iStartRow, int iEndRow, IteratorCond cond = NULL ) + all_tracks_reverse_iterator GetTapNoteRangeAllTracksReverse( int iStartRow, int iEndRow, IteratorCond cond = NULL, bool bInclusive = false ) { - return all_tracks_iterator(*this, iStartRow, iEndRow, true, cond); + return all_tracks_iterator(*this, iStartRow, iEndRow, true, cond, bInclusive ); } - all_tracks_const_reverse_iterator GetTapNoteRangeAllTracksReverse( int iStartRow, int iEndRow, IteratorCond cond = NULL) const + all_tracks_const_reverse_iterator GetTapNoteRangeAllTracksReverse( int iStartRow, int iEndRow, IteratorCond cond = NULL, bool bInclusive = false ) const { - return all_tracks_const_iterator(*this, iStartRow, iEndRow, true, cond); + return all_tracks_const_iterator(*this, iStartRow, iEndRow, true, cond, bInclusive ); } /* Return an iterator range include iStartRow to iEndRow. Extend the range to include