diff options
author | Ahmad Samir <a.samirh78@gmail.com> | 2024-02-14 22:11:43 +0200 |
---|---|---|
committer | Ahmad Samir <a.samirh78@gmail.com> | 2024-02-23 22:07:47 +0200 |
commit | bfc7535a10f7a6e3723f354b41f08a0fe1d18719 (patch) | |
tree | 4ee2c19f03cc9952a98a53898b7ed3f2d87204b3 | |
parent | bb058909626410d22ccd74919d69cd747fbc33ad (diff) |
QSingleShotTimer: use nanoseconds precision
This is a step towards making QChronoTimer have nanoseconds precision.
Not changing QTimer::singleShot() methods to take nanoseconds; QTimer
uses milliseconds for the most part, having the static singleShot()
methods take nanoseconds would be a bit surprising?
[ChangeLog][Core][QObject] Added startTimer() nanoseconds overload and
removed the milliseconds overload. This change is backwards compatible.
Change-Id: I69e79c8feb6354846c6d3be57dc529af7abd1313
Reviewed-by: Edward Welbourne <edward.welbourne@qt.io>
-rw-r--r-- | src/corelib/compat/removed_api.cpp | 15 | ||||
-rw-r--r-- | src/corelib/kernel/qobject.cpp | 13 | ||||
-rw-r--r-- | src/corelib/kernel/qobject.h | 6 | ||||
-rw-r--r-- | src/corelib/kernel/qsingleshottimer_p.h | 28 |
4 files changed, 43 insertions, 19 deletions
diff --git a/src/corelib/compat/removed_api.cpp b/src/corelib/compat/removed_api.cpp index a2d8d6f63e..b214ca4f36 100644 --- a/src/corelib/compat/removed_api.cpp +++ b/src/corelib/compat/removed_api.cpp @@ -4,6 +4,7 @@ #define QT_CORE_BUILD_REMOVED_API #include "qglobal.h" +#include "qnumeric.h" QT_USE_NAMESPACE @@ -954,6 +955,20 @@ bool QUrlQuery::operator==(const QUrlQuery &other) const return comparesEqual(*this, other); } +#include "qobject.h" + +int QObject::startTimer(std::chrono::milliseconds time, Qt::TimerType timerType) +{ + using namespace std::chrono; + using ratio = std::ratio_divide<std::milli, std::nano>; + if (nanoseconds::rep r; qMulOverflow<ratio::num>(time.count(), &r)) { + qWarning("QObject::startTimer(std::chrono::milliseconds time ...): " + "'time' arg will overflow when converted to nanoseconds."); + } + return startTimer(nanoseconds{time}, timerType); +} + + // #include "qotherheader.h" // // implement removed functions from qotherheader.h // order sections alphabetically to reduce chances of merge conflicts diff --git a/src/corelib/kernel/qobject.cpp b/src/corelib/kernel/qobject.cpp index f386891dc7..828a48e21e 100644 --- a/src/corelib/kernel/qobject.cpp +++ b/src/corelib/kernel/qobject.cpp @@ -1850,7 +1850,6 @@ int QObject::startTimer(int interval, Qt::TimerType timerType) /*! \since 5.9 \overload - \fn int QObject::startTimer(std::chrono::milliseconds interval, Qt::TimerType timerType) Starts a timer and returns a timer identifier, or returns zero if it could not start a timer. @@ -1884,14 +1883,19 @@ int QObject::startTimer(int interval, Qt::TimerType timerType) less clumsy than using timer IDs directly. \sa timerEvent(), killTimer(), QTimer::singleShot() + + \note Starting from Qt 6.8 the type of \a interval + is \c std::chrono::nanoseconds, prior to that it was \c + std::chrono::milliseconds. This change is backwards compatible with + older releases of Qt. */ -int QObject::startTimer(std::chrono::milliseconds interval, Qt::TimerType timerType) +int QObject::startTimer(std::chrono::nanoseconds interval, Qt::TimerType timerType) { Q_D(QObject); using namespace std::chrono_literals; - if (Q_UNLIKELY(interval < 0ms)) { + if (Q_UNLIKELY(interval < 0ns)) { qWarning("QObject::startTimer: Timers cannot have negative intervals"); return 0; } @@ -1907,7 +1911,8 @@ int QObject::startTimer(std::chrono::milliseconds interval, Qt::TimerType timerT } auto dispatcher = thisThreadData->eventDispatcher.loadRelaxed(); - int timerId = dispatcher->registerTimer(interval.count(), timerType, this); + const auto msecs = std::chrono::ceil<std::chrono::milliseconds>(interval); + int timerId = dispatcher->registerTimer(msecs.count(), timerType, this); d->ensureExtraData(); d->extraData->runningTimers.append(timerId); return timerId; diff --git a/src/corelib/kernel/qobject.h b/src/corelib/kernel/qobject.h index 76863d66bc..9d4f4bcbff 100644 --- a/src/corelib/kernel/qobject.h +++ b/src/corelib/kernel/qobject.h @@ -19,6 +19,7 @@ #include <QtCore/qobject_impl.h> #include <QtCore/qbindingstorage.h> +#include <QtCore/qtcoreexports.h> #include <chrono> @@ -141,7 +142,12 @@ public: bool moveToThread(QThread *thread QT6_DECL_NEW_OVERLOAD_TAIL); int startTimer(int interval, Qt::TimerType timerType = Qt::CoarseTimer); + +#if QT_CORE_REMOVED_SINCE(6, 8) int startTimer(std::chrono::milliseconds time, Qt::TimerType timerType = Qt::CoarseTimer); +#endif + int startTimer(std::chrono::nanoseconds time, Qt::TimerType timerType = Qt::CoarseTimer); + void killTimer(int id); template<typename T> diff --git a/src/corelib/kernel/qsingleshottimer_p.h b/src/corelib/kernel/qsingleshottimer_p.h index aeaf310659..06656ec79c 100644 --- a/src/corelib/kernel/qsingleshottimer_p.h +++ b/src/corelib/kernel/qsingleshottimer_p.h @@ -31,12 +31,12 @@ class QSingleShotTimer : public QObject public: inline ~QSingleShotTimer(); - inline QSingleShotTimer(std::chrono::milliseconds msec, Qt::TimerType timerType, const QObject *r, - const char *member); - inline QSingleShotTimer(std::chrono::milliseconds msec, Qt::TimerType timerType, const QObject *r, - QtPrivate::QSlotObjectBase *slotObj); + inline QSingleShotTimer(std::chrono::nanoseconds interval, Qt::TimerType timerType, + const QObject *r, const char *member); + inline QSingleShotTimer(std::chrono::nanoseconds interval, Qt::TimerType timerType, + const QObject *r, QtPrivate::QSlotObjectBase *slotObj); - inline void startTimerForReceiver(std::chrono::milliseconds msec, Qt::TimerType timerType, + inline void startTimerForReceiver(std::chrono::nanoseconds interval, Qt::TimerType timerType, const QObject *receiver); Q_SIGNALS: @@ -46,15 +46,15 @@ private: inline void timerEvent(QTimerEvent *) override; }; -QSingleShotTimer::QSingleShotTimer(std::chrono::milliseconds msec, Qt::TimerType timerType, +QSingleShotTimer::QSingleShotTimer(std::chrono::nanoseconds interval, Qt::TimerType timerType, const QObject *r, const char *member) : QObject(QAbstractEventDispatcher::instance()) { connect(this, SIGNAL(timeout()), r, member); - startTimerForReceiver(msec, timerType, r); + startTimerForReceiver(interval, timerType, r); } -QSingleShotTimer::QSingleShotTimer(std::chrono::milliseconds msec, Qt::TimerType timerType, +QSingleShotTimer::QSingleShotTimer(std::chrono::nanoseconds interval, Qt::TimerType timerType, const QObject *r, QtPrivate::QSlotObjectBase *slotObj) : QObject(QAbstractEventDispatcher::instance()) { @@ -63,7 +63,7 @@ QSingleShotTimer::QSingleShotTimer(std::chrono::milliseconds msec, Qt::TimerType QObjectPrivate::connectImpl(this, signal_index, r ? r : this, nullptr, slotObj, Qt::AutoConnection, nullptr, &staticMetaObject); - startTimerForReceiver(msec, timerType, r); + startTimerForReceiver(interval, timerType, r); } QSingleShotTimer::~QSingleShotTimer() @@ -77,7 +77,7 @@ QSingleShotTimer::~QSingleShotTimer() the same thread as where it will be handled, so that it fires reliably even if the thread that set up the timer is busy. */ -void QSingleShotTimer::startTimerForReceiver(std::chrono::milliseconds msec, +void QSingleShotTimer::startTimerForReceiver(std::chrono::nanoseconds interval, Qt::TimerType timerType, const QObject *receiver) { if (receiver && receiver->thread() != thread()) { @@ -88,20 +88,18 @@ void QSingleShotTimer::startTimerForReceiver(std::chrono::milliseconds msec, setParent(nullptr); moveToThread(receiver->thread()); - QDeadlineTimer deadline(msec, timerType); + QDeadlineTimer deadline(interval, timerType); auto invokable = [this, deadline, timerType] { if (deadline.hasExpired()) { Q_EMIT timeout(); } else { auto nsecs = deadline.remainingTimeAsDuration(); - // Use std::chrono::ceil<milliseconds> to match what - // QDeadlineTimer::remainingTime() did - timerId = startTimer(std::chrono::ceil<std::chrono::milliseconds>(nsecs), timerType); + timerId = startTimer(nsecs, timerType); } }; QMetaObject::invokeMethod(this, invokable, Qt::QueuedConnection); } else { - timerId = startTimer(msec, timerType); + timerId = startTimer(interval, timerType); } } |