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

Port the new-style 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 old-style static methods were already ported in the first step,
which also contain the ChangeLog common to both patches.

Pick-to: 6.8
Task-number: QTBUG-128426
Change-Id: I1899465c3b852ab546983a0bf35853fdd3f91ef3
Reviewed-by: Thiago Macieira <thiago.macieira@intel.com>
This commit is contained in:
Marc Mutz 2024-08-28 15:44:39 +02:00
parent 4e911bda29
commit 6991e848e3
3 changed files with 26 additions and 9 deletions

View File

@ -1174,6 +1174,14 @@ void QTimer::singleShot(std::chrono::milliseconds interval, Qt::TimerType timerT
singleShot(from_msecs(interval), timerType, receiver, member);
}
void QTimer::singleShotImpl(std::chrono::milliseconds interval, Qt::TimerType timerType,
const QObject *receiver, QtPrivate::QSlotObjectBase *slotObj)
{
QtPrivate::SlotObjUniquePtr slot(slotObj); // don't leak if from_msecs throws
const auto ns = from_msecs(interval);
singleShotImpl(ns, timerType, receiver, slot.release());
}
#include "qurl.h"
bool QUrl::operator<(const QUrl &url) const

View File

@ -319,11 +319,11 @@ QTimer::from_msecs(std::chrono::milliseconds ms)
as the final sender class.
\a slotObj the slot object
*/
void QTimer::singleShotImpl(std::chrono::milliseconds msec, Qt::TimerType timerType,
void QTimer::singleShotImpl(std::chrono::nanoseconds ns, Qt::TimerType timerType,
const QObject *receiver,
QtPrivate::QSlotObjectBase *slotObj)
{
if (msec == 0ms) {
if (ns == 0ns) {
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.
@ -352,7 +352,7 @@ void QTimer::singleShotImpl(std::chrono::milliseconds msec, Qt::TimerType timerT
return;
}
new QSingleShotTimer(from_msecs(msec), timerType, receiver, slotObj);
(void) new QSingleShotTimer(ns, timerType, receiver, slotObj);
}
/*!
@ -420,14 +420,14 @@ void QTimer::singleShot(std::chrono::nanoseconds ns, Qt::TimerType timerType,
}
}
/*! \fn template<typename Duration, typename Functor> void QTimer::singleShot(Duration msec, const QObject *context, Functor &&functor)
\fn template<typename Duration, typename Functor> void QTimer::singleShot(Duration msec, Qt::TimerType timerType, const QObject *context, Functor &&functor)
\fn template<typename Duration, typename Functor> void QTimer::singleShot(Duration msec, Functor &&functor)
\fn template<typename Duration, typename Functor> void QTimer::singleShot(Duration msec, Qt::TimerType timerType, Functor &&functor)
/*! \fn template<typename Duration, typename Functor> void QTimer::singleShot(Duration interval, const QObject *context, Functor &&functor)
\fn template<typename Duration, typename Functor> void QTimer::singleShot(Duration interval, Qt::TimerType timerType, const QObject *context, Functor &&functor)
\fn template<typename Duration, typename Functor> void QTimer::singleShot(Duration interval, Functor &&functor)
\fn template<typename Duration, typename Functor> void QTimer::singleShot(Duration interval, Qt::TimerType timerType, Functor &&functor)
\since 5.4
\reentrant
This static function calls \a functor after \a msec milliseconds.
This static function calls \a functor after \a interval.
It is very convenient to use this function because you do not need
to bother with a \l{QObject::timerEvent()}{timerEvent} or
@ -441,7 +441,12 @@ void QTimer::singleShot(std::chrono::nanoseconds ns, Qt::TimerType timerType,
If \a functor is a member
function of \a context, then the function will be called on the object.
The \a msec parameter can be an \c int or a \c std::chrono::milliseconds value.
The \a interval parameter can be an \c int (interpreted as a millisecond
count) or a \c std::chrono type that implicitly converts to nanoseconds.
\note In Qt versions prior to 6.8, the chrono overloads took chrono::milliseconds,
not chrono::nanoseconds. The compiler will automatically convert for you,
but the conversion may overflow for extremely large milliseconds counts.
\sa start()
*/

View File

@ -173,8 +173,12 @@ private:
static void singleShotImpl(int msec, Qt::TimerType timerType,
const QObject *receiver, QtPrivate::QSlotObjectBase *slotObj);
#if QT_CORE_REMOVED_SINCE(6, 8)
static void singleShotImpl(std::chrono::milliseconds interval, Qt::TimerType timerType,
const QObject *receiver, QtPrivate::QSlotObjectBase *slotObj);
#endif
static void singleShotImpl(std::chrono::nanoseconds interval, Qt::TimerType timerType,
const QObject *receiver, QtPrivate::QSlotObjectBase *slotObj);
};
#if QT_CORE_INLINE_IMPL_SINCE(6, 8)