00001
00002 #ifndef SST_TIMER_H
00003 #define SST_TIMER_H
00004
00005 #include <QObject>
00006
00007 class QDateTime;
00008 class QTimerEvent;
00009
00010
00011 namespace SST {
00012
00013 class XdrStream;
00014 class Timer;
00015 class TimerEngine;
00016 class TimerHostState;
00017
00018
00024 class Time
00025 {
00026 friend class Timer;
00027
00028 public:
00029 qint64 usecs;
00030
00031
00032 inline Time() { }
00033 inline Time(qint64 usecs) : usecs(usecs) { }
00034 inline Time(const Time &other) : usecs(other.usecs) { }
00035
00036 inline bool operator==(const Time &other) const
00037 { return usecs == other.usecs; }
00038 inline bool operator!=(const Time &other) const
00039 { return usecs != other.usecs; }
00040 inline bool operator<(const Time &other) const
00041 { return usecs < other.usecs; }
00042 inline bool operator>(const Time &other) const
00043 { return usecs > other.usecs; }
00044 inline bool operator<=(const Time &other) const
00045 { return usecs <= other.usecs; }
00046 inline bool operator>=(const Time &other) const
00047 { return usecs >= other.usecs; }
00048
00049
00052 inline Time since(const Time &other) const
00053 { return Time(qMax(usecs - other.usecs, (qint64)0)); }
00054
00055
00059 QString toString() const;
00060
00065 static Time fromString(const QString &str);
00066
00067
00070 QDateTime toQDateTime() const;
00071
00075 static Time fromQDateTime(const QDateTime &qdt);
00076
00077
00078
00079 static Time decode(const QByteArray &data);
00080 QByteArray encode() const;
00081 };
00082
00083 XdrStream &operator>>(XdrStream &rs, Time &t);
00084 XdrStream &operator<<(XdrStream &ws, const Time &t);
00085
00086
00089 class TimerEngine : public QObject
00090 {
00091 friend class Timer;
00092
00093 Q_OBJECT
00094
00095 protected:
00097 TimerEngine(Timer *t);
00098
00101 Timer *timer() const { return (Timer*)parent(); }
00102
00103
00108 virtual void start(quint64 usecs) = 0;
00109
00113 virtual void stop() = 0;
00114
00115
00120 void timeout();
00121 };
00122
00123
00130 class Timer : public QObject
00131 {
00132 friend class TimerEngine;
00133
00134 Q_OBJECT
00135
00136 TimerEngine *te;
00137 qint64 iv;
00138 qint64 fail;
00139 bool act;
00140
00141 public:
00142
00144 static const qint64 retryMin = 500*1000;
00145
00147 static const qint64 retryMax = 60*1000*1000;
00148
00150 static const qint64 failMax = 20*1000*1000;
00151
00152
00154 static qint64 backoff(qint64 period, qint64 maxperiod = failMax)
00155 { return qMin(period * 3 / 2, maxperiod); }
00156
00157
00160 Timer(TimerHostState *host, QObject *parent = NULL);
00161
00164 inline bool isActive() const { return act; }
00165
00166
00167
00168 inline qint64 interval() const { return iv; }
00169
00170
00174 inline void start(qint64 initperiod = retryMin,
00175 qint64 failperiod = failMax)
00176 { fail = failperiod; act = true; te->start(iv = initperiod); }
00177
00179 inline void stop()
00180 { te->stop(); act = false; }
00181
00183 inline void restart()
00184 { act = true; te->start(iv = backoff(iv)); }
00185
00188 inline bool failed()
00189 { return fail <= 0; }
00190
00191
00192 signals:
00196 void timeout(bool failed);
00197 };
00198
00199
00203 class DefaultTimerEngine : public TimerEngine
00204 {
00205 friend class TimerHostState;
00206
00207 Q_OBJECT
00208 int timerid;
00209
00210 inline DefaultTimerEngine(Timer *t) : TimerEngine(t), timerid(0) { }
00211 ~DefaultTimerEngine();
00212
00213 virtual void start(quint64 usecs);
00214 virtual void stop();
00215
00217 virtual void timerEvent(QTimerEvent *);
00218 };
00219
00220
00227 class TimerHostState : public QObject
00228 {
00229 Q_OBJECT
00230
00231 public:
00235 virtual Time currentTime();
00236
00237
00242 virtual TimerEngine *newTimerEngine(Timer *timer);
00243 };
00244
00245 }
00246
00247
00248 #endif // SST_TIMER_H