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>bb10
parent
bb05890962
commit
bfc7535a10
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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>
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Reference in New Issue