From d16ba63f5cdf1e6c9dc96200bb80b2155437c4ee Mon Sep 17 00:00:00 2001 From: Thiago Macieira Date: Mon, 30 May 2016 16:10:08 -0300 Subject: QTimer: add support for functions [ChangeLog][QtCore][QTimer] Added support for std::chrono duration objects for QTimer methods, like QTimer::singleShot and QTimer::setInterval. Change-Id: I87e17314d8b24ae983b1fffd14536e24d5b12424 Reviewed-by: Marc Mutz --- src/corelib/kernel/qtimer.cpp | 72 +++++++++++++++++++++++++++++++++ src/corelib/kernel/qtimer.h | 93 ++++++++++++++++++++++++++++++++++--------- 2 files changed, 147 insertions(+), 18 deletions(-) (limited to 'src') diff --git a/src/corelib/kernel/qtimer.cpp b/src/corelib/kernel/qtimer.cpp index 80accc0cb8..8ba494ec3d 100644 --- a/src/corelib/kernel/qtimer.cpp +++ b/src/corelib/kernel/qtimer.cpp @@ -532,6 +532,78 @@ void QTimer::singleShot(int msec, Qt::TimerType timerType, const QObject *receiv \sa start() */ +/*! + \fn void QTimer::singleShot(std::chrono::duration value, const QObject *receiver, const char *member) + \since 5.8 + \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 \l{QObject::timerEvent()}{timerEvent} or + create a local QTimer object. + + The \a receiver is the receiving object and the \a member is the slot. The + time interval is given in the duration object \a value. + + \sa start() +*/ + +/*! + \fn void QTimer::singleShot(std::chrono::duration value, Qt::TimerType timerType, const QObject *receiver, const char *member) + \since 5.8 + \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 \l{QObject::timerEvent()}{timerEvent} or + create a local QTimer object. + + The \a receiver is the receiving object and the \a member is the slot. The + time interval is given in the duration object \a value. The \a timerType affects the + accuracy of the timer. + + \sa start() +*/ + +/*! + \fn void QTimer::start(std::chrono::duration value) + \since 5.8 + \overload + + Starts or restarts the timer with a timeout of duration \a value. + + If the timer is already running, it will be + \l{QTimer::stop()}{stopped} and restarted. + + If \l singleShot is true, the timer will be activated only once. +*/ + +/*! + \fn std::chrono::milliseconds QTimer::intervalAsDuration() const + \since 5.8 + + Returns the interval of this timer as a \c std::chrono::milliseconds object. + + \sa interval +*/ + +/*! + \fn std::chrono::milliseconds QTimer::remainingTimeAsDuration() const + \since 5.8 + + Returns the time remaining in this timer object as a \c + std::chrono::milliseconds object. If this timer is due or overdue, the + returned value is \c std::chrono::milliseconds::zero(). If the remaining + time could not be found or the timer is not active, this function returns a + negative duration. + + \sa remainingTime() +*/ + /*! \property QTimer::singleShot \brief whether the timer is a single-shot timer diff --git a/src/corelib/kernel/qtimer.h b/src/corelib/kernel/qtimer.h index d97fe933b9..1567fe760c 100644 --- a/src/corelib/kernel/qtimer.h +++ b/src/corelib/kernel/qtimer.h @@ -47,6 +47,10 @@ #include // conceptual inheritance #include +#if QT_HAS_INCLUDE() +# include +#endif + QT_BEGIN_NAMESPACE @@ -94,13 +98,13 @@ public: static void singleShot(int msec, Qt::TimerType timerType, const QObject *context, Functor functor); #else // singleShot to a QObject slot - template - static inline void singleShot(int msec, const typename QtPrivate::FunctionPointer::Object *receiver, Func1 slot) + template + static inline void singleShot(Duration interval, const typename QtPrivate::FunctionPointer::Object *receiver, Func1 slot) { - singleShot(msec, msec >= 2000 ? Qt::CoarseTimer : Qt::PreciseTimer, receiver, slot); + singleShot(interval, defaultTypeFor(interval), receiver, slot); } - template - static inline void singleShot(int msec, Qt::TimerType timerType, const typename QtPrivate::FunctionPointer::Object *receiver, + template + static inline void singleShot(Duration interval, Qt::TimerType timerType, const typename QtPrivate::FunctionPointer::Object *receiver, Func1 slot) { typedef QtPrivate::FunctionPointer SlotType; @@ -109,42 +113,42 @@ public: Q_STATIC_ASSERT_X(int(SlotType::ArgumentCount) == 0, "The slot must not have any arguments."); - singleShotImpl(msec, timerType, receiver, + singleShotImpl(interval, timerType, receiver, new QtPrivate::QSlotObject(slot)); } // singleShot to a functor or function pointer (without context) - template + template static inline typename QtPrivate::QEnableIf::IsPointerToMemberFunction && !QtPrivate::is_same::value, void>::Type - singleShot(int msec, Func1 slot) + singleShot(Duration interval, Func1 slot) { - singleShot(msec, msec >= 2000 ? Qt::CoarseTimer : Qt::PreciseTimer, Q_NULLPTR, slot); + singleShot(interval, defaultTypeFor(interval), nullptr, slot); } - template + template static inline typename QtPrivate::QEnableIf::IsPointerToMemberFunction && !QtPrivate::is_same::value, void>::Type - singleShot(int msec, Qt::TimerType timerType, Func1 slot) + singleShot(Duration interval, Qt::TimerType timerType, Func1 slot) { - singleShot(msec, timerType, Q_NULLPTR, slot); + singleShot(interval, timerType, nullptr, slot); } // singleShot to a functor or function pointer (with context) - template + template static inline typename QtPrivate::QEnableIf::IsPointerToMemberFunction && !QtPrivate::is_same::value, void>::Type - singleShot(int msec, QObject *context, Func1 slot) + singleShot(Duration interval, QObject *context, Func1 slot) { - singleShot(msec, msec >= 2000 ? Qt::CoarseTimer : Qt::PreciseTimer, context, slot); + singleShot(interval, defaultTypeFor(interval), context, slot); } - template + template static inline typename QtPrivate::QEnableIf::IsPointerToMemberFunction && !QtPrivate::is_same::value, void>::Type - singleShot(int msec, Qt::TimerType timerType, QObject *context, Func1 slot) + singleShot(Duration interval, Qt::TimerType timerType, QObject *context, Func1 slot) { //compilation error if the slot has arguments. typedef QtPrivate::FunctionPointer SlotType; Q_STATIC_ASSERT_X(int(SlotType::ArgumentCount) <= 0, "The slot must not have any arguments."); - singleShotImpl(msec, timerType, context, + singleShotImpl(interval, timerType, context, new QtPrivate::QFunctorSlotObject::Value, void>(slot)); } @@ -159,6 +163,43 @@ public Q_SLOTS: Q_SIGNALS: void timeout(QPrivateSignal); +public: +#if QT_HAS_INCLUDE() || defined(Q_QDOC) + template + void setInterval(std::chrono::duration value) + { + setInterval(std::chrono::duration_cast(value).count()); + } + + std::chrono::milliseconds intervalAsDuration() const + { + return std::chrono::milliseconds(interval()); + } + + std::chrono::milliseconds remainingTimeAsDuration() const + { + return std::chrono::milliseconds(remainingTime()); + } + + template + static void singleShot(std::chrono::duration value, const QObject *receiver, const char *member) + { + singleShot(int(std::chrono::duration_cast(value).count()), receiver, member); + } + + template + static void singleShot(std::chrono::duration value, Qt::TimerType timerType, const QObject *receiver, const char *member) + { + singleShot(int(std::chrono::duration_cast(value).count()), timerType, receiver, member); + } + + template + void start(std::chrono::duration value) + { + start(int(std::chrono::duration_cast(value).count())); + } +#endif + protected: void timerEvent(QTimerEvent *) Q_DECL_OVERRIDE; @@ -168,9 +209,25 @@ private: inline int startTimer(int){ return -1;} inline void killTimer(int){} + static Q_DECL_CONSTEXPR Qt::TimerType defaultTypeFor(int msecs) Q_DECL_NOTHROW + { return msecs >= 2000 ? Qt::CoarseTimer : Qt::PreciseTimer; } static void singleShotImpl(int msec, Qt::TimerType timerType, const QObject *receiver, QtPrivate::QSlotObjectBase *slotObj); +#if QT_HAS_INCLUDE() + template + static Qt::TimerType defaultTypeFor(std::chrono::duration interval) + { return defaultTypeFor(int(std::chrono::duration_cast(interval).count())); } + + template + static void singleShotImpl(std::chrono::duration interval, Qt::TimerType timerType, + const QObject *receiver, QtPrivate::QSlotObjectBase *slotObj) + { + singleShotImpl(int(std::chrono::duration_cast(interval).count()), + timerType, receiver, slotObj); + } +#endif + int id, inter, del; uint single : 1; uint nulltimer : 1; -- cgit v1.2.3