summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAhmad Samir <a.samirh78@gmail.com>2024-02-14 22:11:43 +0200
committerAhmad Samir <a.samirh78@gmail.com>2024-02-23 22:07:47 +0200
commitbfc7535a10f7a6e3723f354b41f08a0fe1d18719 (patch)
tree4ee2c19f03cc9952a98a53898b7ed3f2d87204b3
parentbb058909626410d22ccd74919d69cd747fbc33ad (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.cpp15
-rw-r--r--src/corelib/kernel/qobject.cpp13
-rw-r--r--src/corelib/kernel/qobject.h6
-rw-r--r--src/corelib/kernel/qsingleshottimer_p.h28
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);
}
}