00001 #ifndef TIME_H_
00002 #define TIME_H_
00003
00004 #include <string>
00005 using std::string;
00006
00007 #ifndef SWIG
00008 #include <iostream>
00009 using std::ostream;
00010 using std::cerr;
00011 using std::endl;
00012 #endif
00013
00014 #include <limits>
00015 #include <cmath>
00016
00017 #include <boost/format.hpp>
00018
00019 #include "PCSIMException.h"
00020
00021
00022 #ifndef SWIG
00023
00024 namespace PCSIM
00025 {
00026 class TimeException : public Exception
00027 {
00028 public:
00029 TimeException( string method, string msg ) : Exception( method, msg ) {};
00030 virtual string name() const { return string("PCSIM::TimeException"); };
00031 };
00032
00033 class TimeRangeException : public TimeException
00034 {
00035 public:
00036 TimeRangeException( string method, string msg ) : TimeException( method, msg ) {};
00037 virtual string name() const { return string("PCSIM::TimeRangeException"); };
00038 };
00039
00040 }
00041
00042 #endif
00043
00044 typedef long long tic_t;
00045 typedef unsigned long step_t;
00046
00047 class Time
00048 {
00049 public:
00050
00051 Time() : _tics(0) {} ;
00052 Time(const Time& t) : _tics(t._tics) {};
00053
00054 static Time ticks(tic_t t);
00055 static Time steps(const step_t s, const Time &dt);
00056 static Time ms(double t);
00057 static Time sec(double t);
00058
00060 tic_t in_tics() const;
00062 step_t in_steps(const Time &dt) const;
00064 double in_ms() const;
00066 double in_sec() const;
00067
00068 #ifndef SWIG
00069
00070 string toString() const;
00071
00072 bool operator==(const Time& t) const;
00073 bool operator!=(const Time& t) const;
00074 bool operator<=(const Time& t) const;
00075 bool operator<(const Time& t) const;
00076 bool operator>=(const Time& t) const;
00077 bool operator>(const Time& t) const;
00078
00079 Time operator+=(const Time& t);
00080 Time operator-=(const Time& t);
00081 Time operator+(const Time& t);
00082 Time operator-(const Time& t);
00083
00084 #endif
00085
00086 private:
00087
00088 static const double _sec_per_tic;
00089 static const double _tics_per_sec;
00090 static const double _ms_per_tic;
00091 static const double _tics_per_ms;
00092
00093 static step_t tics2steps(const tic_t tics, const Time &dt);
00094 static tic_t steps2tics(const step_t s, const Time &dt);
00095
00096 static double tics2ms(const tic_t tics);
00097 static tic_t ms2tics(const double ms);
00098
00099 static double tics2sec(const tic_t tics);
00100 static tic_t sec2tics(const double sec);
00101
00103 tic_t _tics;
00104 };
00105
00106 inline Time Time::ticks(tic_t t)
00107 {
00108 Time T;
00109 T._tics = t;
00110 return T;
00111 }
00112
00113 inline Time Time::steps(step_t s, const Time &dt)
00114 {
00115 Time t;
00116 t._tics = steps2tics(s,dt);
00117 return t;
00118 }
00119
00120 inline Time Time::ms(double s)
00121 {
00122 Time t;
00123 t._tics = ms2tics(s);
00124 return t;
00125 }
00126 inline Time Time::sec(double s)
00127 {
00128 Time t;
00129 t._tics = sec2tics(s);
00130 return t;
00131 }
00132
00133 inline tic_t Time::in_tics() const
00134 {
00135 return _tics;
00136 }
00137
00138 inline step_t Time::in_steps(const Time &dt) const
00139 {
00140 return tics2steps(_tics,dt);
00141 }
00142
00143 inline double Time::in_ms() const
00144 {
00145 return tics2ms(_tics);
00146 }
00147
00148 inline double Time::in_sec() const
00149 {
00150 return tics2sec(_tics);
00151 }
00152
00153 inline string Time::toString() const
00154 {
00155 return str( boost::format( "%1% ms" ) % in_ms() );
00156 }
00157
00158 inline bool Time::operator==(const Time& other) const
00159 {
00160 return this->_tics == other._tics;
00161 }
00162
00163 inline bool Time::operator!=(const Time& other) const
00164 {
00165 return this->_tics != other._tics;
00166 }
00167
00168 inline bool Time::operator<=(const Time& t) const
00169 {
00170 return this->_tics <= t._tics;
00171 }
00172
00173 inline bool Time::operator<(const Time& t) const
00174 {
00175 return this->_tics < t._tics;
00176 }
00177
00178 inline bool Time::operator>=(const Time& t) const
00179 {
00180 return this->_tics >= t._tics;
00181 }
00182
00183 inline bool Time::operator>(const Time& t) const
00184 {
00185 return this->_tics > t._tics;
00186 }
00187
00188 inline Time Time::operator+=(const Time& t1)
00189 {
00190 tic_t nt = _tics + t1._tics;
00191 if( (_tics>0) && (t1._tics>0) && (nt<_tics)) {
00192 cerr << toString() << " + " << t1.toString() << endl;
00193 throw( PCSIM::TimeRangeException( "Time::operator+=" , "Overflow" ) );
00194 } else if( (_tics<0) && (t1._tics<0) && (nt>_tics))
00195 throw( PCSIM::TimeRangeException( "Time::operator+=" , "Underflow" ) );
00196 _tics = nt;
00197 return *this;
00198 }
00199
00200 inline Time Time::operator-=(const Time& t1)
00201 {
00202 Time r = t1;
00203 r._tics *= -1;
00204 *this += r;
00205 return r;
00206 }
00207
00208 inline Time Time::operator+(const Time& t)
00209 {
00210 Time res(*this);
00211 res += t;
00212 return res;
00213 }
00214
00215 inline Time Time::operator-(const Time& t)
00216 {
00217 Time res(*this);
00218 res -= t;
00219 return res;
00220 }
00221
00222 #ifndef SWIG
00223
00224 inline ostream& operator<<(ostream &s, const Time &t)
00225 {
00226 return s << t.toString();
00227 }
00228
00229 #endif
00230
00231 inline step_t Time::tics2steps(const tic_t tics, const Time &dt)
00232 {
00233 step_t steps=(step_t)round(tics/dt._tics);
00234
00235 if( (tics % dt._tics) != 0 ) {
00236
00237 }
00238 return steps;
00239 }
00240
00241 inline tic_t Time::steps2tics(const step_t s, const Time &dt)
00242 {
00243 return dt._tics * static_cast<tic_t>(s);
00244 }
00245
00246 inline double Time::tics2ms(const tic_t tics)
00247 {
00248 return _ms_per_tic*static_cast<double>(tics);
00249 }
00250
00251 inline tic_t Time::ms2tics(double ms)
00252 {
00253 return static_cast<tic_t>(std::floor(ms*_tics_per_ms+0.5));
00254 }
00255
00256 inline double Time::tics2sec(const tic_t tics)
00257 {
00258 return _sec_per_tic*static_cast<double>(tics);
00259 }
00260
00261 inline tic_t Time::sec2tics(double sec)
00262 {
00263 return static_cast<tic_t>(std::floor(sec*_tics_per_sec+0.5));
00264 }
00265
00266 #endif