| 1 | // Copyright (C) 2016 The Qt Company Ltd. | 
| 2 | // SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only | 
| 3 |  | 
| 4 | #ifndef QTIMER_H | 
| 5 | #define QTIMER_H | 
| 6 |  | 
| 7 | #include <QtCore/qglobal.h> | 
| 8 |  | 
| 9 | #ifndef QT_NO_QOBJECT | 
| 10 |  | 
| 11 | #include <QtCore/qbasictimer.h> // conceptual inheritance | 
| 12 | #include <QtCore/qobject.h> | 
| 13 |  | 
| 14 | #include <chrono> | 
| 15 |  | 
| 16 | QT_BEGIN_NAMESPACE | 
| 17 |  | 
| 18 | class QTimerPrivate; | 
| 19 | class Q_CORE_EXPORT QTimer : public QObject | 
| 20 | { | 
| 21 |     Q_OBJECT | 
| 22 |     Q_PROPERTY(bool singleShot READ isSingleShot WRITE setSingleShot BINDABLE bindableSingleShot) | 
| 23 |     Q_PROPERTY(int interval READ interval WRITE setInterval BINDABLE bindableInterval) | 
| 24 |     Q_PROPERTY(int remainingTime READ remainingTime) | 
| 25 |     Q_PROPERTY(Qt::TimerType timerType READ timerType WRITE setTimerType BINDABLE bindableTimerType) | 
| 26 |     Q_PROPERTY(bool active READ isActive STORED false BINDABLE bindableActive) | 
| 27 | public: | 
| 28 |     explicit QTimer(QObject *parent = nullptr); | 
| 29 |     ~QTimer(); | 
| 30 |  | 
| 31 |     bool isActive() const; | 
| 32 |     QBindable<bool> bindableActive(); | 
| 33 |     int timerId() const; | 
| 34 |     Qt::TimerId id() const; | 
| 35 |  | 
| 36 |     void setInterval(int msec); | 
| 37 |     int interval() const; | 
| 38 |     QBindable<int> bindableInterval(); | 
| 39 |  | 
| 40 |     int remainingTime() const; | 
| 41 |  | 
| 42 |     void setTimerType(Qt::TimerType atype); | 
| 43 |     Qt::TimerType timerType() const; | 
| 44 |     QBindable<Qt::TimerType> bindableTimerType(); | 
| 45 |  | 
| 46 |     void setSingleShot(bool singleShot); | 
| 47 |     bool isSingleShot() const; | 
| 48 |     QBindable<bool> bindableSingleShot(); | 
| 49 |  | 
| 50 |     QT_CORE_INLINE_SINCE(6, 8) | 
| 51 |     static void singleShot(int msec, const QObject *receiver, const char *member); | 
| 52 |  | 
| 53 |     QT_CORE_INLINE_SINCE(6, 8) | 
| 54 |     static void singleShot(int msec, Qt::TimerType timerType, const QObject *receiver, const char *member); | 
| 55 |  | 
| 56 |     // singleShot with context | 
| 57 | #ifdef Q_QDOC | 
| 58 |     template <typename Duration, typename Functor> | 
| 59 |     static inline void singleShot(Duration interval, const QObject *receiver, Functor &&slot); | 
| 60 |     template <typename Duration, typename Functor> | 
| 61 |     static inline void singleShot(Duration interval, Qt::TimerType timerType, | 
| 62 |                                   const QObject *receiver, Functor &&slot); | 
| 63 | #else | 
| 64 |     template <typename Duration, typename Functor> | 
| 65 |     static inline void singleShot(Duration interval, | 
| 66 |                                   const typename QtPrivate::ContextTypeForFunctor<Functor>::ContextType *receiver, | 
| 67 |                                   Functor &&slot) | 
| 68 |     { | 
| 69 |         singleShot(interval, defaultTypeFor(interval), receiver, std::forward<Functor>(slot)); | 
| 70 |     } | 
| 71 |     template <typename Duration, typename Functor> | 
| 72 |     static inline void singleShot(Duration interval, Qt::TimerType timerType, | 
| 73 |                                   const typename QtPrivate::ContextTypeForFunctor<Functor>::ContextType *receiver, | 
| 74 |                                   Functor &&slot) | 
| 75 |     { | 
| 76 |         using Prototype = void(*)(); | 
| 77 |         singleShotImpl(interval, timerType, receiver, | 
| 78 |                        QtPrivate::makeCallableObject<Prototype>(std::forward<Functor>(slot))); | 
| 79 |     } | 
| 80 | #endif | 
| 81 |  | 
| 82 |     // singleShot without context | 
| 83 |     template <typename Duration, typename Functor> | 
| 84 |     static inline void singleShot(Duration interval, Functor &&slot) | 
| 85 |     { | 
| 86 |         singleShot(interval, defaultTypeFor(interval), nullptr, std::forward<Functor>(slot)); | 
| 87 |     } | 
| 88 |     template <typename Duration, typename Functor> | 
| 89 |     static inline void singleShot(Duration interval, Qt::TimerType timerType, Functor &&slot) | 
| 90 |     { | 
| 91 |         singleShot(interval, timerType, nullptr, std::forward<Functor>(slot)); | 
| 92 |     } | 
| 93 |  | 
| 94 | #ifdef Q_QDOC | 
| 95 |     template <typename Functor> | 
| 96 |     QMetaObject::Connection callOnTimeout(Functor &&slot); | 
| 97 |     template <typename Functor> | 
| 98 |     QMetaObject::Connection callOnTimeout(const QObject *context, Functor &&slot, Qt::ConnectionType connectionType = Qt::AutoConnection); | 
| 99 | #else | 
| 100 |     template <typename ... Args> | 
| 101 |     QMetaObject::Connection callOnTimeout(Args && ...args) | 
| 102 |     { | 
| 103 |         return QObject::connect(this, &QTimer::timeout, std::forward<Args>(args)... ); | 
| 104 |     } | 
| 105 |  | 
| 106 | #endif | 
| 107 |  | 
| 108 | public Q_SLOTS: | 
| 109 |     void start(int msec); | 
| 110 |  | 
| 111 |     void start(); | 
| 112 |     void stop(); | 
| 113 |  | 
| 114 | Q_SIGNALS: | 
| 115 |     void timeout(QPrivateSignal); | 
| 116 |  | 
| 117 | public: | 
| 118 |     void setInterval(std::chrono::milliseconds value); | 
| 119 |  | 
| 120 |     std::chrono::milliseconds intervalAsDuration() const | 
| 121 |     { | 
| 122 |         return std::chrono::milliseconds(interval()); | 
| 123 |     } | 
| 124 |  | 
| 125 |     std::chrono::milliseconds remainingTimeAsDuration() const | 
| 126 |     { | 
| 127 |         return std::chrono::milliseconds(remainingTime()); | 
| 128 |     } | 
| 129 |  | 
| 130 | #if QT_CORE_REMOVED_SINCE(6, 8) | 
| 131 |     static void singleShot(std::chrono::milliseconds value, const QObject *receiver, const char *member) | 
| 132 |     { | 
| 133 |         singleShot(value, defaultTypeFor(value), receiver, member); | 
| 134 |     } | 
| 135 |     static void singleShot(std::chrono::milliseconds interval, Qt::TimerType timerType, | 
| 136 |                            const QObject *receiver, const char *member); | 
| 137 | #endif // QT_CORE_REMOVED_SINCE(6, 8) | 
| 138 |     static void singleShot(std::chrono::nanoseconds value, const QObject *receiver, const char *member) | 
| 139 |     { | 
| 140 |         singleShot(interval: value, timerType: defaultTypeFor(interval: value), receiver, member); | 
| 141 |     } | 
| 142 |     static void singleShot(std::chrono::nanoseconds interval, Qt::TimerType timerType, | 
| 143 |                            const QObject *receiver, const char *member); | 
| 144 |  | 
| 145 |     void start(std::chrono::milliseconds value); | 
| 146 |  | 
| 147 | protected: | 
| 148 |     void timerEvent(QTimerEvent *) override; | 
| 149 |  | 
| 150 | private: | 
| 151 |     Q_DISABLE_COPY(QTimer) | 
| 152 |     Q_DECLARE_PRIVATE(QTimer) | 
| 153 |     friend class QChronoTimer; | 
| 154 |  | 
| 155 |     static std::chrono::nanoseconds from_msecs(std::chrono::milliseconds); | 
| 156 |  | 
| 157 |     inline int startTimer(int){ return -1;} | 
| 158 |     inline void killTimer(int){} | 
| 159 |  | 
| 160 |     static constexpr Qt::TimerType defaultTypeFor(int msecs) noexcept | 
| 161 |     { return defaultTypeFor(interval: std::chrono::milliseconds{msecs}); } | 
| 162 |  | 
| 163 |     static constexpr Qt::TimerType defaultTypeFor(std::chrono::nanoseconds interval) noexcept | 
| 164 |     { | 
| 165 |         // coarse timers are worst in their first firing | 
| 166 |         // so we prefer a high precision timer for something that happens only once | 
| 167 |         // unless the timeout is too big, in which case we go for coarse anyway | 
| 168 |         using namespace std::chrono_literals; | 
| 169 |         return interval >= 2s ? Qt::CoarseTimer : Qt::PreciseTimer; | 
| 170 |     } | 
| 171 |  | 
| 172 |     QT_CORE_INLINE_SINCE(6, 8) | 
| 173 |     static void singleShotImpl(int msec, Qt::TimerType timerType, | 
| 174 |                                const QObject *receiver, QtPrivate::QSlotObjectBase *slotObj); | 
| 175 |  | 
| 176 | #if QT_CORE_REMOVED_SINCE(6, 8) | 
| 177 |     static void singleShotImpl(std::chrono::milliseconds interval, Qt::TimerType timerType, | 
| 178 |                                const QObject *receiver, QtPrivate::QSlotObjectBase *slotObj); | 
| 179 | #endif | 
| 180 |     static void singleShotImpl(std::chrono::nanoseconds interval, Qt::TimerType timerType, | 
| 181 |                                const QObject *receiver, QtPrivate::QSlotObjectBase *slotObj); | 
| 182 | }; | 
| 183 |  | 
| 184 | #if QT_CORE_INLINE_IMPL_SINCE(6, 8) | 
| 185 | void QTimer::singleShot(int msec, const QObject *receiver, const char *member) | 
| 186 | { singleShot(value: std::chrono::milliseconds{msec}, receiver, member); } | 
| 187 |  | 
| 188 | void QTimer::singleShot(int msec, Qt::TimerType timerType, const QObject *receiver, | 
| 189 |                         const char *member) | 
| 190 | { singleShot(interval: std::chrono::milliseconds{msec}, timerType, receiver, member); } | 
| 191 |  | 
| 192 | void QTimer::singleShotImpl(int msec, Qt::TimerType timerType, | 
| 193 |                             const QObject *receiver, QtPrivate::QSlotObjectBase *slotObj) | 
| 194 | { | 
| 195 |     singleShotImpl(interval: std::chrono::milliseconds{msec}, timerType, receiver, slotObj); | 
| 196 | } | 
| 197 | #endif | 
| 198 |  | 
| 199 | QT_END_NAMESPACE | 
| 200 |  | 
| 201 | #endif // QT_NO_QOBJECT | 
| 202 |  | 
| 203 | #endif // QTIMER_H | 
| 204 |  |