QTimer: make singleShot() have nanoseconds resolution [1/2]: old-style

Port the string-based singleShot() static methods from milliseconds to
nanoseconds resolution.

This matches what QChronoTimer provides, but we want to minimize
porting for users come Qt 7, so we don't want users to first have to
port to QChronoTimer::singleShot() and then back to
QTimer::singleShot(); we want them to continue to use QTimer.

The only reason QChronoTimer is a separate class from QTimer is that
the latter has an int interval property and we can't just port it to
milli- or nanoseconds chrono types if we want users to actually access
the extra range or precision afforded by the chrono types. But that's
not an issue for the singleShot() static methods, as they never return
an object that could be asked for its timeout.

The new-style static methods will be ported in a second step.

[ChangeLog][QtCore][QTimer] The singleShot() static methods now
operate with nanoseconds resolution, like QChronoTimer. The rest of
QTimer remains milliseconds; use QChronoTimer if you need a QTimer
with nanoseconds resolution of more than INT_MAX milliseconds
range. Beware overflow that may occur when passing large milliseconds
objects that may overflow nanoseconds::rep when converted.

Task-number: QTBUG-128426
Change-Id: I11e1ad8529c67b4018f6325ac408686799475823
Reviewed-by: Thiago Macieira <thiago.macieira@intel.com>
(cherry picked from commit 4e911bda295b53bc74cf1af26008b3e60181668d)
Reviewed-by: Qt Cherry-pick Bot <cherrypick_bot@qt-project.org>
This commit is contained in:
Marc Mutz 2024-08-28 15:44:39 +02:00 committed by Qt Cherry-pick Bot
parent d4d2636e5e
commit e6ab7847a7
3 changed files with 30 additions and 8 deletions

View File

@ -1168,6 +1168,12 @@ auto QStringConverter::encodingForName(const char *name) noexcept -> std::option
#include "qtimer.h" // inlined API
void QTimer::singleShot(std::chrono::milliseconds interval, Qt::TimerType timerType,
const QObject *receiver, const char *member)
{
singleShot(from_msecs(interval), timerType, receiver, member);
}
#include "qurl.h"
bool QUrl::operator<(const QUrl &url) const

View File

@ -395,15 +395,15 @@ void QTimer::singleShotImpl(std::chrono::milliseconds msec, Qt::TimerType timerT
\sa start()
*/
void QTimer::singleShot(std::chrono::milliseconds msec, Qt::TimerType timerType,
void QTimer::singleShot(std::chrono::nanoseconds ns, Qt::TimerType timerType,
const QObject *receiver, const char *member)
{
if (Q_UNLIKELY(msec < 0ms)) {
if (ns < 0ns) {
qWarning("QTimer::singleShot: Timers cannot have negative timeouts");
return;
}
if (receiver && member) {
if (msec == 0ms) {
if (ns == 0ns) {
// special code shortpath for 0-timers
const char* bracketPosition = strchr(member, '(');
if (!bracketPosition || !(member[0] >= '0' && member[0] <= '2')) {
@ -416,7 +416,7 @@ void QTimer::singleShot(std::chrono::milliseconds msec, Qt::TimerType timerType,
Qt::QueuedConnection);
return;
}
(void) new QSingleShotTimer(from_msecs(msec), timerType, receiver, member);
(void) new QSingleShotTimer(ns, timerType, receiver, member);
}
}
@ -447,7 +447,7 @@ void QTimer::singleShot(std::chrono::milliseconds msec, Qt::TimerType timerType,
*/
/*!
\fn void QTimer::singleShot(std::chrono::milliseconds msec, const QObject *receiver, const char *member)
\fn void QTimer::singleShot(std::chrono::nanoseconds nsec, const QObject *receiver, const char *member)
\since 5.8
\overload
\reentrant
@ -459,13 +459,19 @@ void QTimer::singleShot(std::chrono::milliseconds msec, Qt::TimerType timerType,
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 msec.
time interval is given in the duration object \a nsec.
//! [qtimer-ns-overflow]
\note In Qt versions prior to 6.8, this function took chrono::milliseconds,
not chrono::nanoseconds. The compiler will automatically convert for you,
but the conversion may overflow for extremely large milliseconds counts.
//! [qtimer-ns-overflow]
\sa start()
*/
/*!
\fn void QTimer::singleShot(std::chrono::milliseconds msec, Qt::TimerType timerType, const QObject *receiver, const char *member)
\fn void QTimer::singleShot(std::chrono::nanoseconds nsec, Qt::TimerType timerType, const QObject *receiver, const char *member)
\since 5.8
\overload
\reentrant
@ -477,9 +483,11 @@ void QTimer::singleShot(std::chrono::milliseconds msec, Qt::TimerType timerType,
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 msec. The \a timerType affects the
time interval is given in the duration object \a nsec. The \a timerType affects the
accuracy of the timer.
\include qtimer.cpp qtimer-ns-overflow
\sa start()
*/

View File

@ -127,12 +127,20 @@ public:
return std::chrono::milliseconds(remainingTime());
}
#if QT_CORE_REMOVED_SINCE(6, 8)
static void singleShot(std::chrono::milliseconds value, const QObject *receiver, const char *member)
{
singleShot(value, defaultTypeFor(value), receiver, member);
}
static void singleShot(std::chrono::milliseconds interval, Qt::TimerType timerType,
const QObject *receiver, const char *member);
#endif // QT_CORE_REMOVED_SINCE(6, 8)
static void singleShot(std::chrono::nanoseconds value, const QObject *receiver, const char *member)
{
singleShot(value, defaultTypeFor(value), receiver, member);
}
static void singleShot(std::chrono::nanoseconds interval, Qt::TimerType timerType,
const QObject *receiver, const char *member);
void start(std::chrono::milliseconds value);