Add Qt::TimerType and the QTimer::timerType property
authorBradley T. Hughes <bradley.hughes@nokia.com>
Wed, 21 Dec 2011 10:32:43 +0000 (11:32 +0100)
committerQt by Nokia <qt-info@nokia.com>
Mon, 2 Jan 2012 09:44:00 +0000 (10:44 +0100)
The timer type will control the accuracy of the timer. By default, all
timers are CoarseTimers, which allows for +/- 5% interval adjustment.
PreciseTimers will not have any interval adjustments, VeryCoarseTimers
will have intervals adjusted to full second resolution.

Use QTimer::setTimerType() or the QTimer::singleShot() overload to
specify the type.

QObject::startTimer() now takes a Qt::TimerType argument which defaults
to Qt::CoarseTimer. QBasicTimer::startTimer() gets an overload that
takes a Qt::TimerType argument. The argument is unused for now, since
the QAbstractEventDispatcher interface needs to change (done in a
separate commit).

Author: Thiago Macieira <thiago.macieira@nokia.com>
Change-Id: I3100da5aa1fe17ec30b8644897d0fe6ec4a07f52
Reviewed-by: Thiago Macieira <thiago.macieira@intel.com>
src/corelib/global/qnamespace.h
src/corelib/global/qnamespace.qdoc
src/corelib/kernel/qbasictimer.cpp
src/corelib/kernel/qbasictimer.h
src/corelib/kernel/qobject.cpp
src/corelib/kernel/qobject.h
src/corelib/kernel/qtimer.cpp
src/corelib/kernel/qtimer.h

index 4c0b9cc..1927323 100644 (file)
@@ -97,6 +97,7 @@ Qt {
     Q_ENUMS(GestureType)
 #endif
     Q_ENUMS(CursorMoveStyle)
+    Q_ENUMS(TimerType)
 #endif // defined(Q_MOC_RUN)
 
 #if defined(Q_MOC_RUN)
@@ -1527,6 +1528,12 @@ public:
         LogicalMoveStyle,
         VisualMoveStyle
     };
+
+    enum TimerType {
+        PreciseTimer,
+        CoarseTimer,
+        VeryCoarseTimer
+    };
 }
 #ifdef Q_MOC_RUN
  ;
index 4abe981..20ae1ba 100644 (file)
     \sa QApplication::setNavigationMode()
     \sa QApplication::navigationMode()
 */
+
+/*!
+    \enum Qt::TimerType
+
+    The timer type indicates how accurate a timer can be.
+
+    \value PreciseTimer Precise timers try to keep millisecond accuracy
+    \value CoarseTimer Coarse timers try to keep accuracy within 5% of the desired interval
+    \value VeryCoarseTimer Very coarse timers only keep full second accuracy
+*/
index 8efeea6..d91c5a9 100644 (file)
@@ -40,7 +40,6 @@
 ****************************************************************************/
 
 #include "qbasictimer.h"
-#include "qcoreapplication.h"
 #include "qabstracteventdispatcher.h"
 
 QT_BEGIN_NAMESPACE
@@ -121,6 +120,24 @@ void QBasicTimer::start(int msec, QObject *obj)
 }
 
 /*!
+    \overload
+
+    Starts (or restarts) the timer with a \a msec milliseconds timeout and the
+    given \a timerType. See Qt::TimerType for information on the different
+    timer types.
+
+    The given \a object will receive timer events.
+
+    \sa stop() isActive() QObject::timerEvent() Qt::TimerType
+ */
+void QBasicTimer::start(int msec, Qt::TimerType timerType, QObject *obj)
+{
+    stop();
+    if (obj)
+        id = obj->startTimer(msec, timerType);
+}
+
+/*!
     Stops the timer.
 
     \sa start() isActive()
index f13848c..ae5401e 100644 (file)
@@ -43,6 +43,7 @@
 #define QBASICTIMER_H
 
 #include <QtCore/qglobal.h>
+#include <QtCore/qnamespace.h>
 
 QT_BEGIN_HEADER
 
@@ -63,6 +64,7 @@ public:
     inline int timerId() const { return id; }
 
     void start(int msec, QObject *obj);
+    void start(int msec, Qt::TimerType timerType, QObject *obj);
     void stop();
 };
 Q_DECLARE_TYPEINFO(QBasicTimer, Q_MOVABLE_TYPE);
index 4e8d2fc..8db8ace 100644 (file)
@@ -1358,10 +1358,12 @@ void QObjectPrivate::_q_reregisterTimers(void *pointer)
 
     \snippet doc/src/snippets/code/src_corelib_kernel_qobject.cpp 8
 
-    Note that QTimer's accuracy depends on the underlying operating
-    system and hardware. Most platforms support an accuracy of 20
-    milliseconds; some provide more. If Qt is unable to deliver the
-    requested number of timer events, it will silently discard some.
+    Note that QTimer's accuracy depends on the underlying operating system and
+    hardware. The \a timerType argument allows you to customize the accuracy of
+    the timer. See Qt::TimerType for information on the different timer types.
+    Most platforms support an accuracy of 20 milliseconds; some provide more.
+    If Qt is unable to deliver the requested number of timer events, it will
+    silently discard some.
 
     The QTimer class provides a high-level programming interface with
     single-shot timers and timer signals instead of events. There is
@@ -1371,7 +1373,7 @@ void QObjectPrivate::_q_reregisterTimers(void *pointer)
     \sa timerEvent(), killTimer(), QTimer::singleShot()
 */
 
-int QObject::startTimer(int interval)
+int QObject::startTimer(int interval, Qt::TimerType timerType)
 {
     Q_D(QObject);
 
index 3ca2e22..a5ac8fe 100644 (file)
@@ -150,7 +150,7 @@ public:
     QThread *thread() const;
     void moveToThread(QThread *thread);
 
-    int startTimer(int interval);
+    int startTimer(int interval, Qt::TimerType timerType = Qt::CoarseTimer);
     void killTimer(int id);
 
     template<typename T>
index 9be661e..e89abad 100644 (file)
@@ -134,7 +134,6 @@ QT_BEGIN_NAMESPACE
         {Analog Clock Example}, {Wiggly Example}
 */
 
-
 static const int INV_TIMER = -1;                // invalid timer id
 
 /*!
@@ -142,7 +141,7 @@ static const int INV_TIMER = -1;                // invalid timer id
 */
 
 QTimer::QTimer(QObject *parent)
-    : QObject(parent), id(INV_TIMER), inter(0), del(0), single(0), nulltimer(0)
+    : QObject(parent), id(INV_TIMER), inter(0), del(0), single(0), nulltimer(0), type(Qt::CoarseTimer)
 {
 }
 
@@ -203,7 +202,7 @@ void QTimer::start()
     if (id != INV_TIMER)                        // stop running timer
         stop();
     nulltimer = (!inter && single);
-    id = QObject::startTimer(inter);
+    id = QObject::startTimer(inter, Qt::TimerType(type));
 }
 
 /*!
@@ -257,18 +256,18 @@ class QSingleShotTimer : public QObject
     int timerId;
 public:
     ~QSingleShotTimer();
-    QSingleShotTimer(int msec, QObject *r, const char * m);
+    QSingleShotTimer(int msec, Qt::TimerType timerType, QObject *r, const char * m);
 Q_SIGNALS:
     void timeout();
 protected:
     void timerEvent(QTimerEvent *);
 };
 
-QSingleShotTimer::QSingleShotTimer(int msec, QObject *receiver, const char *member)
+QSingleShotTimer::QSingleShotTimer(int msec, Qt::TimerType timerType, QObject *receiver, const char *member)
     : QObject(QAbstractEventDispatcher::instance())
 {
     connect(this, SIGNAL(timeout()), receiver, member);
-    timerId = startTimer(msec);
+    timerId = startTimer(msec, timerType);
 }
 
 QSingleShotTimer::~QSingleShotTimer()
@@ -318,6 +317,25 @@ QT_END_INCLUDE_NAMESPACE
 
 void QTimer::singleShot(int msec, QObject *receiver, const char *member)
 {
+    singleShot(msec, Qt::CoarseTimer, receiver, member);
+}
+
+/*! \overload
+    \reentrant
+    This static function calls a slot after a given time interval.
+
+    It is very convenient to use this function because you do not need
+    to bother with a \link QObject::timerEvent() timerEvent\endlink or
+    create a local QTimer object.
+
+    The \a receiver is the receiving object and the \a member is the slot. The
+    time interval is \a msec milliseconds. The \a timerType affects the
+    accuracy of the timer.
+
+    \sa start()
+*/
+void QTimer::singleShot(int msec, Qt::TimerType timerType, QObject *receiver, const char *member)
+{
     if (receiver && member) {
         if (msec == 0) {
             // special code shortpath for 0-timers
@@ -330,7 +348,7 @@ void QTimer::singleShot(int msec, QObject *receiver, const char *member)
             QMetaObject::invokeMethod(receiver, methodName.constData(), Qt::QueuedConnection);
             return;
         }
-        (void) new QSingleShotTimer(msec, receiver, member);
+        (void) new QSingleShotTimer(msec, timerType, receiver, member);
     }
 }
 
@@ -361,8 +379,17 @@ void QTimer::setInterval(int msec)
     inter = msec;
     if (id != INV_TIMER) {                        // create new timer
         QObject::killTimer(id);                        // restart timer
-        id = QObject::startTimer(msec);
+        id = QObject::startTimer(msec, Qt::TimerType(type));
     }
 }
 
+/*!
+    \property QTimer::timerType
+    \brief controls the accuracy of the timer
+
+    The default value for this property is \c Qt::CoarseTimer.
+
+    \sa Qt::TimerType
+*/
+
 QT_END_NAMESPACE
index 707bc83..5b7dbd1 100644 (file)
@@ -58,6 +58,7 @@ class Q_CORE_EXPORT QTimer : public QObject
     Q_OBJECT
     Q_PROPERTY(bool singleShot READ isSingleShot WRITE setSingleShot)
     Q_PROPERTY(int interval READ interval WRITE setInterval)
+    Q_PROPERTY(Qt::TimerType timerType READ timerType WRITE setTimerType)
     Q_PROPERTY(bool active READ isActive)
 public:
     explicit QTimer(QObject *parent = 0);
@@ -69,10 +70,14 @@ public:
     void setInterval(int msec);
     int interval() const { return inter; }
 
+    void setTimerType(Qt::TimerType type) { this->type = type; }
+    Qt::TimerType timerType() const { return Qt::TimerType(type); }
+
     inline void setSingleShot(bool singleShot);
     inline bool isSingleShot() const { return single; }
 
     static void singleShot(int msec, QObject *receiver, const char *member);
+    static void singleShot(int msec, Qt::TimerType timerType, QObject *receiver, const char *member);
 
 public Q_SLOTS:
     void start(int msec);
@@ -95,6 +100,8 @@ private:
     int id, inter, del;
     uint single : 1;
     uint nulltimer : 1;
+    uint type : 2;
+    // reserved : 28
 };
 
 inline void QTimer::setSingleShot(bool asingleShot) { single = asingleShot; }