From a4a679ee796a476048ddee3f88025035cca3631a Mon Sep 17 00:00:00 2001 From: Ahmad Samir Date: Fri, 16 Feb 2024 16:46:12 +0200 Subject: [PATCH] QTimer: delegate more to the chrono overloads singleShot() (static) methods: QSingleShotTimer's interval isn't limited by the `int` interval in QTimer, so this is OK, no narrowing. start(int)/setInterval(int): Techincally it makes no difference which overloads delegate to which, because QTimer stores the interval in an `int` (QProperty); so any {int interval,chrono::milliseconds.count()} > INT_MAX is narrowing anyway. But it's less confusing and matches what has been done in other classes when porting them to chrono, int overload delegates to chrono overload. Change-Id: I5ae0888f16130ae28a74be4498a180485fa34550 Reviewed-by: Thiago Macieira --- src/corelib/compat/removed_api.cpp | 2 ++ src/corelib/kernel/qtimer.cpp | 47 ++++++++++++++++++++---------- src/corelib/kernel/qtimer.h | 44 ++++++++++++++++------------ 3 files changed, 59 insertions(+), 34 deletions(-) diff --git a/src/corelib/compat/removed_api.cpp b/src/corelib/compat/removed_api.cpp index c97359bfd8..d46b8692f6 100644 --- a/src/corelib/compat/removed_api.cpp +++ b/src/corelib/compat/removed_api.cpp @@ -919,6 +919,8 @@ QUrl QUrl::fromEncoded(const QByteArray &input, ParsingMode mode) return QUrl::fromEncoded(QByteArrayView(input), mode); } +#include "qtimer.h" // inlined API + // #include "qotherheader.h" // // implement removed functions from qotherheader.h diff --git a/src/corelib/kernel/qtimer.cpp b/src/corelib/kernel/qtimer.cpp index f93293f283..0e09bc9565 100644 --- a/src/corelib/kernel/qtimer.cpp +++ b/src/corelib/kernel/qtimer.cpp @@ -218,8 +218,16 @@ void QTimer::start() cause trouble and highly erratic behavior of the UI. */ void QTimer::start(int msec) +{ + start(msec * 1ms); +} + +void QTimer::start(std::chrono::milliseconds interval) { Q_D(QTimer); + // This could be narrowing as the interval is stored in an `int` QProperty, + // and the type can't be changed in Qt6. + const int msec = interval.count(); const bool intervalChanged = msec != d->inter; d->inter.setValue(msec); start(); @@ -268,14 +276,13 @@ void QTimer::timerEvent(QTimerEvent *e) \a timerType is the timer type \a receiver is the receiver object, can be null. In such a case, it will be the same as the final sender class. - \a slot a pointer only used when using Qt::UniqueConnection \a slotObj the slot object - */ -void QTimer::singleShotImpl(int msec, Qt::TimerType timerType, +*/ +void QTimer::singleShotImpl(std::chrono::milliseconds msec, Qt::TimerType timerType, const QObject *receiver, QtPrivate::QSlotObjectBase *slotObj) { - if (msec == 0) { + if (msec == 0ms) { bool deleteReceiver = false; // Optimize: set a receiver context when none is given, such that we can use // QMetaObject::invokeMethod which is more efficient than going through a timer. @@ -304,11 +311,13 @@ void QTimer::singleShotImpl(int msec, Qt::TimerType timerType, return; } - new QSingleShotTimer(msec * 1ms, timerType, receiver, slotObj); + new QSingleShotTimer(msec, timerType, receiver, slotObj); } /*! + \fn void QTimer::singleShot(int msec, const QObject *receiver, const char *member) \reentrant + \deprecated [6.8] Use the chrono overloads. This static function calls a slot after a given time interval. It is very convenient to use this function because you do not need @@ -327,13 +336,11 @@ void QTimer::singleShotImpl(int msec, Qt::TimerType timerType, \sa start() */ -void QTimer::singleShot(int msec, const QObject *receiver, const char *member) -{ - singleShot(msec, defaultTypeFor(msec), receiver, member); -} - -/*! \overload +/*! + \fn void QTimer::singleShot(int msec, Qt::TimerType timerType, const QObject *receiver, const char *member) + \overload \reentrant + \deprecated [6.8] Use the chrono overloads. This static function calls a slot after a given time interval. It is very convenient to use this function because you do not need @@ -346,14 +353,16 @@ void QTimer::singleShot(int msec, const QObject *receiver, const char *member) \sa start() */ -void QTimer::singleShot(int msec, Qt::TimerType timerType, const QObject *receiver, const char *member) + +void QTimer::singleShot(std::chrono::milliseconds msec, Qt::TimerType timerType, + const QObject *receiver, const char *member) { - if (Q_UNLIKELY(msec < 0)) { + if (Q_UNLIKELY(msec < 0ms)) { qWarning("QTimer::singleShot: Timers cannot have negative timeouts"); return; } if (receiver && member) { - if (msec == 0) { + if (msec == 0ms) { // special code shortpath for 0-timers const char* bracketPosition = strchr(member, '('); if (!bracketPosition || !(member[0] >= '0' && member[0] <= '2')) { @@ -366,7 +375,7 @@ void QTimer::singleShot(int msec, Qt::TimerType timerType, const QObject *receiv Qt::QueuedConnection); return; } - (void) new QSingleShotTimer(msec * 1ms, timerType, receiver, member); + (void) new QSingleShotTimer(msec, timerType, receiver, member); } } @@ -547,8 +556,16 @@ QBindable QTimer::bindableSingleShot() \sa singleShot */ void QTimer::setInterval(int msec) +{ + setInterval(std::chrono::milliseconds{msec}); +} + +void QTimer::setInterval(std::chrono::milliseconds interval) { Q_D(QTimer); + // This could be narrowing as the interval is stored in an `int` QProperty, + // and the type can't be changed in Qt6. + const int msec = interval.count(); d->inter.removeBindingUnlessInWrapper(); const bool intervalChanged = msec != d->inter.valueBypassingBindings(); d->inter.setValueBypassingBindings(msec); diff --git a/src/corelib/kernel/qtimer.h b/src/corelib/kernel/qtimer.h index 80802a4cc5..9b59895e60 100644 --- a/src/corelib/kernel/qtimer.h +++ b/src/corelib/kernel/qtimer.h @@ -46,7 +46,10 @@ public: bool isSingleShot() const; QBindable bindableSingleShot(); + QT_CORE_INLINE_SINCE(6, 8) static void singleShot(int msec, const QObject *receiver, const char *member); + + QT_CORE_INLINE_SINCE(6, 8) static void singleShot(int msec, Qt::TimerType timerType, const QObject *receiver, const char *member); // singleShot with context @@ -111,10 +114,7 @@ Q_SIGNALS: void timeout(QPrivateSignal); public: - void setInterval(std::chrono::milliseconds value) - { - setInterval(int(value.count())); - } + void setInterval(std::chrono::milliseconds value); std::chrono::milliseconds intervalAsDuration() const { @@ -128,18 +128,12 @@ public: static void singleShot(std::chrono::milliseconds value, const QObject *receiver, const char *member) { - singleShot(int(value.count()), receiver, member); + singleShot(value, defaultTypeFor(value), receiver, member); } + static void singleShot(std::chrono::milliseconds interval, Qt::TimerType timerType, + const QObject *receiver, const char *member); - static void singleShot(std::chrono::milliseconds value, Qt::TimerType timerType, const QObject *receiver, const char *member) - { - singleShot(int(value.count()), timerType, receiver, member); - } - - void start(std::chrono::milliseconds value) - { - start(int(value.count())); - } + void start(std::chrono::milliseconds value); protected: void timerEvent(QTimerEvent *) override; @@ -163,17 +157,29 @@ private: return interval >= 2s ? Qt::CoarseTimer : Qt::PreciseTimer; } + QT_CORE_INLINE_SINCE(6, 8) static void singleShotImpl(int msec, Qt::TimerType timerType, const QObject *receiver, QtPrivate::QSlotObjectBase *slotObj); static void singleShotImpl(std::chrono::milliseconds interval, Qt::TimerType timerType, - const QObject *receiver, QtPrivate::QSlotObjectBase *slotObj) - { - singleShotImpl(int(interval.count()), - timerType, receiver, slotObj); - } + const QObject *receiver, QtPrivate::QSlotObjectBase *slotObj); }; +#if QT_CORE_INLINE_IMPL_SINCE(6, 8) +void QTimer::singleShot(int msec, const QObject *receiver, const char *member) +{ singleShot(std::chrono::milliseconds{msec}, receiver, member); } + +void QTimer::singleShot(int msec, Qt::TimerType timerType, const QObject *receiver, + const char *member) +{ singleShot(std::chrono::milliseconds{msec}, timerType, receiver, member); } + +void QTimer::singleShotImpl(int msec, Qt::TimerType timerType, + const QObject *receiver, QtPrivate::QSlotObjectBase *slotObj) +{ + singleShotImpl(std::chrono::milliseconds{msec}, timerType, receiver, slotObj); +} +#endif + QT_END_NAMESPACE #endif // QT_NO_QOBJECT