diff --git a/src/NoteTypes.h b/src/NoteTypes.h index a91e6aa693..3d99c63252 100644 --- a/src/NoteTypes.h +++ b/src/NoteTypes.h @@ -307,6 +307,35 @@ inline int BeatToNoteRowNotRounded( float fBeatNum ) { return (int)( fBeatNum * @return the beat. */ inline float NoteRowToBeat( int iRow ) { return iRow / (float)ROWS_PER_BEAT; } +// These functions can be useful for function templates, +// where both rows and beats can be specified. + +/** + * @brief Convert the note row to note row (returns itself). + * @param row the row to convert. + */ +static inline int ToNoteRow(int row) { return row; } + +/** + * @brief Convert the beat to note row. + * @param beat the beat to convert. + */ +static inline int ToNoteRow(float beat) { return BeatToNoteRow(beat); } + +/** + * @brief Convert the note row to beat. + * @param row the row to convert. + */ +static inline float ToBeat(int row) { return NoteRowToBeat(row); } + +/** + * @brief Convert the beat row to beat (return itself). + * @param beat the beat to convert. + */ +static inline float ToBeat(float beat) { return beat; } + + + #endif /** diff --git a/src/TimingSegments.cpp b/src/TimingSegments.cpp index 2cf8c3da51..1cf3780772 100644 --- a/src/TimingSegments.cpp +++ b/src/TimingSegments.cpp @@ -1,49 +1,40 @@ #include "TimingSegments.h" -TimingSegment::TimingSegment() : - startingRow(-1) {} +#define LTCOMPARE(x) if(this->x < other.x) return true; if(this->x > other.x) return false; -TimingSegment::TimingSegment(int s) : - startingRow(s) {} +BaseTimingSegment::~BaseTimingSegment() {} -TimingSegment::TimingSegment(float s) : - startingRow(BeatToNoteRow(s)) {} -TimingSegment::~TimingSegment() {} - -void TimingSegment::SetRow(const int s) +void BaseTimingSegment::SetRow(const int s) { this->startingRow = s; } -void TimingSegment::SetBeat(const float s) + +void BaseTimingSegment::SetBeat(const float s) { - this->startingRow = BeatToNoteRow(s); + SetRow(BeatToNoteRow(s)); } -int TimingSegment::GetRow() const +int BaseTimingSegment::GetRow() const { return this->startingRow; } -float TimingSegment::GetBeat() const +float BaseTimingSegment::GetBeat() const { - return NoteRowToBeat(this->startingRow); + return NoteRowToBeat(GetRow()); } -FakeSegment::FakeSegment(): - TimingSegment(), lengthBeats(-1) {} +template +bool TimingSegment::operator<( const DerivedSegment &other ) const +{ + LTCOMPARE(GetRow()); + return false; +} -FakeSegment::FakeSegment( int s, int r ): - TimingSegment(max(0, s)), lengthBeats(NoteRowToBeat(max(0, r))) {} -FakeSegment::FakeSegment( int s, float b ): - TimingSegment(max(0, s)), lengthBeats(max(0, b)) {} - -FakeSegment::FakeSegment( float s, int r ): - TimingSegment(max(0, s)), lengthBeats(max(0, NoteRowToBeat(r))) {} - -FakeSegment::FakeSegment( float s, float b ): - TimingSegment(max(0, s)), lengthBeats(max(0, b)) {} +/* ====================================================== + Here comes the actual timing segments implementation!! */ float FakeSegment::GetLength() const { @@ -55,54 +46,14 @@ void FakeSegment::SetLength(const float b) this->lengthBeats = b; } -bool FakeSegment::operator==( const FakeSegment &other ) const -{ - if (this->GetRow() != other.GetRow()) return false; - if (this->GetLength() != other.GetLength()) return false; - return true; -} - -bool FakeSegment::operator!=( const FakeSegment &other ) const -{ - return !this->operator==(other); -} - bool FakeSegment::operator<( const FakeSegment &other ) const { - if (this->GetRow() < other.GetRow()) return true; - if (this->GetRow() > other.GetRow()) return false; - return this->GetLength() < other.GetLength(); + LTCOMPARE(GetRow()); + LTCOMPARE(GetLength()); + return false; } -bool FakeSegment::operator<=( const FakeSegment &other ) const -{ - return ( this->operator<(other) || this->operator==(other) ); -} -bool FakeSegment::operator>( const FakeSegment &other ) const -{ - return !this->operator<=(other); -} - -bool FakeSegment::operator>=( const FakeSegment &other ) const -{ - return !this->operator<(other); -} - -TickcountSegment::TickcountSegment() : - TimingSegment(), ticks(4) {} - -TickcountSegment::TickcountSegment(int s) : - TimingSegment(s), ticks(4) {} - -TickcountSegment::TickcountSegment(float s) : - TimingSegment(s), ticks(4) {} - -TickcountSegment::TickcountSegment( int s, int t ): - TimingSegment(max(0, s)), ticks(max(0, t)) {} - -TickcountSegment::TickcountSegment( float s, int t ): - TimingSegment(max(0, s)), ticks(max(0, t)) {} int TickcountSegment::GetTicks() const { @@ -114,38 +65,11 @@ void TickcountSegment::SetTicks(const int i) this->ticks = i; } -bool TickcountSegment::operator==( const TickcountSegment &other ) const -{ - if (this->GetRow() != other.GetRow()) return false; - if (this->GetTicks() != other.GetTicks()) return false; - return true; -} - -bool TickcountSegment::operator!=( const TickcountSegment &other ) const -{ - return !this->operator==(other); -} - bool TickcountSegment::operator<( const TickcountSegment &other ) const { - if (this->GetRow() < other.GetRow()) return true; - if (this->GetRow() > other.GetRow()) return false; - return this->GetTicks() < other.GetTicks(); -} - -bool TickcountSegment::operator<=( const TickcountSegment &other ) const -{ - return ( this->operator<(other) || this->operator==(other) ); -} - -bool TickcountSegment::operator>( const TickcountSegment &other ) const -{ - return !this->operator<=(other); -} - -bool TickcountSegment::operator>=( const TickcountSegment &other ) const -{ - return !this->operator<(other); + LTCOMPARE(GetRow()); + LTCOMPARE(GetTicks()); + return false; } /** diff --git a/src/TimingSegments.h b/src/TimingSegments.h index 5c34e7ac6b..d01674c0f3 100644 --- a/src/TimingSegments.h +++ b/src/TimingSegments.h @@ -10,52 +10,116 @@ #define COMPARE(x) if(x!=other.x) return false; /** - * @brief The general TimingSegment for all of the changing glory. - * - * Each segment is supposed to derive from this one. */ -struct TimingSegment + * @brief The base timing segment for all of the changing glory. + * + * Do not derive from this class!! Instead, derive from TimingSegment! + */ +struct BaseTimingSegment { - /** @brief Set up a TimingSegment with default values. */ - TimingSegment(); - /** - * @brief Set up a TimingSegment with specified values. - * @param s the starting row. */ - TimingSegment(int s); - /** - * @brief Set up a TimingSegment with specified values. - * @param s the starting beat. */ - TimingSegment(float s); - - virtual ~TimingSegment(); + + /** @brief Set up a BaseTimingSegment with default values. */ + BaseTimingSegment(): + startingRow(-1) {}; /** - * @brief Set the starting row of the TimingSegment. + * @brief Set up a BaseTimingSegment with specified values. + * @param s the starting row / beat. */ + template + BaseTimingSegment(StartType s): + startingRow(ToNoteRow(s)) {}; + + virtual ~BaseTimingSegment(); + + /** + * @brief Set the starting row of the BaseTimingSegment. * * This is virtual to allow other segments to implement validation * as required by them. * @param s the supplied row. */ virtual void SetRow( const int s ); + /** - * @brief Set the starting beat of the TimingSegment. + * @brief Set the starting beat of the BaseTimingSegment. * - * This is virtual to allow other segments to implement validation - * as required by them. * @param s the supplied beat. */ - virtual void SetBeat( const float s ); + void SetBeat( const float s ); + /** - * @brief Get the starting row of the TimingSegment. + * @brief Get the starting row of the BaseTimingSegment. * @return the starting row. */ int GetRow() const; + /** - * @brief Get the starting beat of the TimingSegment. + * @brief Get the starting beat of the BaseTimingSegment. * @return the starting beat. */ float GetBeat() const; - -private: + +protected: /** @brief The row in which this segment activates. */ int startingRow; + }; +/** + * @brief The general TimingSegment for all of the changing glory. + * + * Each segment is supposed to derive from this one. */ +template +struct TimingSegment: public BaseTimingSegment +{ + + TimingSegment(): BaseTimingSegment() {}; + + template + TimingSegment(StartType s): BaseTimingSegment(s) {}; + + /** + * @brief Compares two DrivedSegments to see if one is less than the other. + * @param other the other TimingSegments to compare to. + * @return the truth/falsehood of if the first is less than the second. + * + * This is virtual to allow other segments to implement comparison + * as required by them. + */ + virtual bool operator<( const DerivedSegment &other ) const; + + /** + * @brief Compares two DrivedSegments to see if they are equal to each other. + * @param other the other FakeSegment to compare to. + * @return the equality of the two segments. + * + * This is virtual to allow other segments to implement comparison + * as required by them. + */ + bool operator==( const DerivedSegment &other ) const { return !this->operator<(other) && !other.operator<(*static_cast(this)); }; + /** + * @brief Compares two DrivedSegments to see if they are not equal to each other. + * @param other the other DrivedSegments to compare to. + * @return the inequality of the two segments. + */ + bool operator!=( const DerivedSegment &other ) const { return !this->operator==(other); }; + /** + * @brief Compares two DrivedSegments to see if one is less than or equal to the other. + * @param other the other DrivedSegments to compare to. + * @return the truth/falsehood of if the first is less or equal to than the second. + */ + bool operator<=( const DerivedSegment &other ) const { return !this->operator>(other); }; + /** + * @brief Compares two DrivedSegments to see if one is greater than the other. + * @param other the other DrivedSegments to compare to. + * @return the truth/falsehood of if the first is greater than the second. + */ + bool operator>( const DerivedSegment &other ) const { return other.operator<(*static_cast(this)); }; + /** + * @brief Compares two DrivedSegments to see if one is greater than or equal to the other. + * @param other the other DrivedSegments to compare to. + * @return the truth/falsehood of if the first is greater than or equal to the second. + */ + bool operator>=( const DerivedSegment &other ) const { return !this->operator<(other); }; + +}; + + /** * @brief Identifies when a whole region of arrows is to be ignored. * @@ -67,38 +131,24 @@ private: * drawn normally. * * These were inspired by the Pump It Up series. */ -struct FakeSegment : public TimingSegment +struct FakeSegment : public TimingSegment { /** * @brief Create a simple Fake Segment with default values. * * It is best to override the values as soon as possible. */ - FakeSegment(); + FakeSegment(): + TimingSegment(), lengthBeats(-1) {}; + /** * @brief Create a Fake Segment with the specified values. * @param s the starting row of this segment. * @param r the number of rows this segment lasts. */ - FakeSegment( int s, int r ); - /** - * @brief Creates a Fake Segment with the specified values. - * @param s the starting row of this segment. - * @param b the number of beats this segment lasts. - */ - FakeSegment( int s, float b ); - /** - * @brief Create a Fake Segment with the specified values. - * @param s the starting beat in this segment. - * @param r the number of rows this segment lasts. - */ - FakeSegment( float s, int r ); - /** - * @brief Creates a Fake Segment with the specified values. - * @param s the starting beat of this segment. - * @param b the number of beats this segment lasts. - */ - FakeSegment( float s, float b ); + template + FakeSegment( StartType s, LengthType r ): + TimingSegment(max((StartType)0, s)), lengthBeats(ToBeat(max((LengthType)0, r))) {}; /** * @brief Get the length in beats of the FakeSegment. @@ -116,36 +166,13 @@ struct FakeSegment : public TimingSegment * @return the equality of the two segments. */ bool operator==( const FakeSegment &other ) const; - /** - * @brief Compares two FakeSegments to see if they are not equal to each other. - * @param other the other FakeSegment to compare to. - * @return the inequality of the two segments. - */ - bool operator!=( const FakeSegment &other ) const; /** * @brief Compares two FakeSegments to see if one is less than the other. * @param other the other FakeSegment to compare to. * @return the truth/falsehood of if the first is less than the second. */ bool operator<( const FakeSegment &other ) const; - /** - * @brief Compares two FakeSegments to see if one is less than or equal to the other. - * @param other the other FakeSegment to compare to. - * @return the truth/falsehood of if the first is less or equal to than the second. - */ - bool operator<=( const FakeSegment &other ) const; - /** - * @brief Compares two FakeSegments to see if one is greater than the other. - * @param other the other FakeSegment to compare to. - * @return the truth/falsehood of if the first is greater than the second. - */ - bool operator>( const FakeSegment &other ) const; - /** - * @brief Compares two FakeSegments to see if one is greater than or equal to the other. - * @param other the other FakeSegment to compare to. - * @return the truth/falsehood of if the first is greater than or equal to the second. - */ - bool operator>=( const FakeSegment &other ) const; + private: /** * @brief The number of beats the FakeSegment is alive for. @@ -161,34 +188,30 @@ private: * system used by various based video games. The number is used to * represent how many ticks can be counted in one beat. */ -struct TickcountSegment : public TimingSegment +struct TickcountSegment : public TimingSegment { /** * @brief Creates a simple Tickcount Segment with default values. * * It is best to override the values as soon as possible. */ - TickcountSegment(); + TickcountSegment(): + TimingSegment(), ticks(4) {}; + /** * @brief Creates a TickcountSegment with specified values. - * @param s the starting row. */ - TickcountSegment(int s); + * @param s the starting row / beat. */ + template + TickcountSegment( StartType s ): + TimingSegment(max((StartType)0, s)), ticks(4) {}; + /** * @brief Creates a TickcountSegment with specified values. - * @param s the starting beat. */ - TickcountSegment(float s); - /** - * @brief Creates a Tickcount Segment with the specified values. - * @param s the starting row. - * @param t the amount of ticks counted per beat. - */ - TickcountSegment( int s, int t ); - /** - * @brief Creates a Tickcount Segment with the specified values. - * @param s the starting beat. - * @param t the amount of ticks counted per beat. - */ - TickcountSegment( float s, int t ); + * @param s the starting row / beat. + * @param t the amount of ticks counted per beat. */ + template + TickcountSegment( StartType s, int t ): + TimingSegment(max((StartType)0, s)), ticks(max(0, t)) {}; /** * @brief Get the number of ticks in this TickcountSegment. @@ -206,36 +229,12 @@ struct TickcountSegment : public TimingSegment * @return the equality of the two segments. */ bool operator==( const TickcountSegment &other ) const; - /** - * @brief Compares two TickcountSegments to see if they are not equal to each other. - * @param other the other TickcountSegment to compare to. - * @return the inequality of the two segments. - */ - bool operator!=( const TickcountSegment &other ) const; /** * @brief Compares two TickcountSegments to see if one is less than the other. * @param other the other TickcountSegment to compare to. * @return the truth/falsehood of if the first is less than the second. */ bool operator<( const TickcountSegment &other ) const; - /** - * @brief Compares two TickcountSegments to see if one is less than or equal to the other. - * @param other the other TickcountSegment to compare to. - * @return the truth/falsehood of if the first is less or equal to than the second. - */ - bool operator<=( const TickcountSegment &other ) const; - /** - * @brief Compares two TickcountSegments to see if one is greater than the other. - * @param other the other TickcountSegment to compare to. - * @return the truth/falsehood of if the first is greater than the second. - */ - bool operator>( const TickcountSegment &other ) const; - /** - * @brief Compares two TickcountSegments to see if one is greater than or equal to the other. - * @param other the other TickcountSegment to compare to. - * @return the truth/falsehood of if the first is greater than or equal to the second. - */ - bool operator>=( const TickcountSegment &other ) const; private: /**