00001 #ifndef _PING_PONG_NUMBER_H
00002 #define _PING_PONG_NUMBER_H
00003
00004 #include "RangedNumber.h"
00005 #include "CyclicNumber.h"
00006
00007 namespace luma
00008 {
00009 namespace numbers
00010 {
00011
00037 template <class T>
00038 class PingPongNumber: public RangedNumber<T>
00039 {
00040 private:
00041 CyclicNumber<T> mCyclicNumber;
00042
00046 inline T pingPongValue(T value) const
00047 {
00048 return value >= mMax ? 2 * (mMax - mIncrement) - value: value;
00049 }
00050
00054 inline T pingPongValue() const
00055 {
00056 return pingPongValue((T) mCyclicNumber);
00057 }
00058
00059 public:
00064 PingPongNumber(T value, T min, T max, T increment);
00065
00069 PingPongNumber(const PingPongNumber& other);
00070
00071 PingPongNumber<T>& operator=(const PingPongNumber<T>& other);
00072 PingPongNumber<T>& operator=(const T& value);
00073
00074 PingPongNumber<T>& operator++();
00075 PingPongNumber<T> operator++(int);
00076 PingPongNumber<T>& operator--();
00077 PingPongNumber<T> operator--(int);
00078
00079 virtual void dec(float elapsedTime = 1);
00080 virtual void inc(float elapsedTime = 1);
00081
00082 virtual T getValidValue(const T& value) const;
00083
00084
00086 T getCyclicValue() const;
00087
00088 void setIncrement(const T& increment);
00089 };
00090
00091 template <class T>
00092 PingPongNumber<T>::PingPongNumber(T value, T min, T max, T increment):
00093 RangedNumber(reflect(value, min, max - increment), min, max, increment),
00094 mCyclicNumber(value, min, max + max - min - increment - increment, increment)
00095 {
00096 }
00097
00098 template <class T>
00099 PingPongNumber<T>::PingPongNumber(const PingPongNumber &other):
00100 RangedNumber(other),
00101 mCyclicNumber(other.mCyclicNumber)
00102 {
00103 }
00104
00105 template <class T>
00106 PingPongNumber<T>& PingPongNumber<T>::operator=(const PingPongNumber<T>& other)
00107 {
00108 modify(other.mMin, other.mMax, other.mIncrement);
00109 mCyclicNumber = other.mCyclicNumber;
00110 mValue = pingPongValue();
00111
00112 return *this;
00113 }
00114
00115 template <class T>
00116 PingPongNumber<T>& PingPongNumber<T>::operator=(const T& value)
00117 {
00118 mCyclicNumber = value;
00119 mValue = pingPongValue();
00120
00121 return *this;
00122 }
00123
00124 template <class T>
00125 PingPongNumber<T>& PingPongNumber<T>::operator++()
00126 {
00127 inc();
00128
00129 return *this;
00130 }
00131
00132 template <class T>
00133 PingPongNumber<T> PingPongNumber<T>::operator++(int)
00134 {
00135 PingPongNumber<T> tmp = *this;
00136
00137 ++*this;
00138
00139 return tmp;
00140 }
00141
00142 template <class T>
00143 PingPongNumber<T>& PingPongNumber<T>::operator--()
00144 {
00145 dec();
00146
00147 return *this;
00148 }
00149
00150 template <class T>
00151 PingPongNumber<T> PingPongNumber<T>::operator--(int)
00152 {
00153 PingPongNumber<T> tmp = *this;
00154
00155 --*this;
00156
00157 return tmp;
00158 }
00159
00160 template <class T>
00161 T PingPongNumber<T>::getValidValue(const T& value) const
00162 {
00163 return pingPongValue(mCyclicNumber.getValidValue(value));
00164 }
00165
00166 template <class T>
00167 void PingPongNumber<T>::inc(float ellapsedTime)
00168 {
00169 mCyclicNumber.inc(ellapsedTime);
00170 mValue = pingPongValue((T) mCyclicNumber);
00171
00172 }
00173
00174 template <class T>
00175 void PingPongNumber<T>::dec(float ellapsedTime)
00176 {
00177 mCyclicNumber.dec(ellapsedTime);
00178 mValue = pingPongValue((T) mCyclicNumber);
00179
00180 }
00181
00182 template <class T>
00183 void PingPongNumber<T>::setIncrement(const T& increment)
00184 {
00185 mCyclicNumber.modify(mMin, 2 * mMax - mMin - 2 * increment, increment);
00186 RangedNumber::setIncrement(increment);
00187 }
00188
00189 template <class T>
00190 T PingPongNumber<T>::getCyclicValue() const
00191 {
00192 return mCyclicNumber.getValue();
00193 }
00194
00195 };};
00196 #endif //_PING_PONG_NUMBER_H