diff --git a/src/corelib/kernel/qchronotimer.cpp b/src/corelib/kernel/qchronotimer.cpp index 6aeb99cfa8e..b6926666363 100644 --- a/src/corelib/kernel/qchronotimer.cpp +++ b/src/corelib/kernel/qchronotimer.cpp @@ -38,9 +38,8 @@ QT_BEGIN_NAMESPACE You can set a timer to time out only once by calling setSingleShot(true). - QChronoTimer also has singleShot() static methods: - - \snippet timers/timers.cpp qchronotimer-singleshot + \note QChronoTimer has no singleShot() static methods, as the ones on + QTimer already work with chrono types and nanoseconds resolution. In multithreaded applications, you can use QChronoTimer in any thread that has an event loop. To start an event loop from a non-GUI @@ -360,96 +359,6 @@ QBindable QChronoTimer::bindableTimerType() return {&d_func()->type}; } -/*! - \overload - \reentrant - - This static function calls the slot \a member, on object \a receiver, after - time interval \a interval. \a timerType affects the precision of the timer - - \a member has to be a member function of \a receiver; you need to use the - \c SLOT() macro to get this parameter. - - This function is provided as a convenience to save the need to use a - \l{QObject::timerEvent()}{timerEvent} or create a local QChronoTimer - object. - - \sa start(), Qt::TimerType -*/ -void QChronoTimer::singleShot(std::chrono::nanoseconds interval, Qt::TimerType timerType, - const QObject *receiver, const char *member) -{ - if (Q_UNLIKELY(interval < 0ns)) { - qWarning("QChronoTimer::singleShot: Timers cannot have negative timeouts"); - return; - } - if (receiver && member) { - if (interval == 0ns) { - // special code shortpath for 0-timers - const char* bracketPosition = strchr(member, '('); - if (!bracketPosition || !(member[0] >= '0' && member[0] <= '2')) { - qWarning("QChronoTimer::singleShot: Invalid slot specification"); - return; - } - const auto methodName = QByteArrayView(member + 1, // extract method name - bracketPosition - 1 - member).trimmed(); - QMetaObject::invokeMethod(const_cast(receiver), - methodName.toByteArray().constData(), - Qt::QueuedConnection); - return; - } - (void) new QSingleShotTimer(interval, timerType, receiver, member); - } -} - -/*! - \internal - - \list - \li \a interval the time interval - \li \a timerType the type of the timer; this affects the precision of - the timer - \li \a receiver the receiver or context object; if this is \c nullptr, - this method will figure out a context object to use, see code - comments below - \li \a slotObj a callable, for example a lambda - \endlist -*/ -void QChronoTimer::singleShotImpl(std::chrono::nanoseconds interval, Qt::TimerType timerType, - const QObject *receiver, QtPrivate::QSlotObjectBase *slotObj) -{ - if (interval == 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. - // We need a QObject living in the current thread. But the QThread itself lives - // in a different thread - with the exception of the main QThread which lives in - // itself. And QThread::currentThread() is among the few QObjects we know that will - // most certainly be there. Note that one can actually call singleShot before the - // QApplication is created! - if (!receiver && QThread::currentThread() == QCoreApplicationPrivate::mainThread()) { - // reuse main thread as context object - receiver = QThread::currentThread(); - } else if (!receiver) { - // Create a receiver context object on-demand. According to the benchmarks, - // this is still more efficient than going through a timer. - receiver = new QObject; - deleteReceiver = true; - } - - auto h = QtPrivate::invokeMethodHelper({}); - QMetaObject::invokeMethodImpl(const_cast(receiver), slotObj, - Qt::QueuedConnection, h.parameterCount(), h.parameters.data(), h.typeNames.data(), - h.metaTypes.data()); - - if (deleteReceiver) - const_cast(receiver)->deleteLater(); - return; - } - - new QSingleShotTimer(interval, timerType, receiver, slotObj); -} - QT_END_NAMESPACE #include "moc_qchronotimer.cpp" diff --git a/src/corelib/kernel/qchronotimer.h b/src/corelib/kernel/qchronotimer.h index 136edb06a2e..79f66f89c71 100644 --- a/src/corelib/kernel/qchronotimer.h +++ b/src/corelib/kernel/qchronotimer.h @@ -55,49 +55,6 @@ public: bool isSingleShot() const; QBindable bindableSingleShot(); - // singleShot with context -#ifdef Q_QDOC - template - static inline void singleShot(std::chrono::nanoseconds interval, - const QObject *receiver, Functor &&slot); - template - static inline void singleShot(std::chrono::nanoseconds interval interval, - Qt::TimerType timerType, - const QObject *receiver, Functor &&slot); -#else - template - static void singleShot(std::chrono::nanoseconds interval, - const FunctorContext *receiver, Functor &&slot) - { - singleShot(interval, QTimer::defaultTypeFor(interval), receiver, std::forward(slot)); - } - template - static void singleShot(std::chrono::nanoseconds interval, Qt::TimerType timerType, - const FunctorContext *receiver, Functor &&slot) - { - using Prototype = void(*)(); - auto *slotObj = QtPrivate::makeCallableObject(std::forward(slot)); - singleShotImpl(interval, timerType, receiver, slotObj); - } -#endif - - template - static void singleShot(std::chrono::nanoseconds interval, Qt::TimerType timerType, - Functor &&slot) - { singleShot(interval, timerType, nullptr, std::forward(slot)); } - - template - static void singleShot(std::chrono::nanoseconds interval, Functor &&slot) - { - singleShot(interval, QTimer::defaultTypeFor(interval), nullptr, std::forward(slot)); - } - - static void singleShot(std::chrono::nanoseconds interval, Qt::TimerType timerType, - const QObject *receiver, const char *member); - static void singleShot(std::chrono::nanoseconds interval, const QObject *receiver, - const char *member) - { singleShot(interval, QTimer::defaultTypeFor(interval), receiver, member); } - #ifdef Q_QDOC template QMetaObject::Connection callOnTimeout(const QObject *context, Functor &&slot, @@ -132,9 +89,6 @@ private: // These two functions are inherited from QObject int startTimer(std::chrono::nanoseconds) = delete; void killTimer(int) = delete; - - static void singleShotImpl(std::chrono::nanoseconds interval, Qt::TimerType timerType, - const QObject *receiver, QtPrivate::QSlotObjectBase *slotObj); }; QT_END_NAMESPACE diff --git a/tests/auto/corelib/kernel/qchronotimer/tst_qchronotimer.cpp b/tests/auto/corelib/kernel/qchronotimer/tst_qchronotimer.cpp index 62c402ae24d..9b8980c8abd 100644 --- a/tests/auto/corelib/kernel/qchronotimer/tst_qchronotimer.cpp +++ b/tests/auto/corelib/kernel/qchronotimer/tst_qchronotimer.cpp @@ -472,8 +472,8 @@ public: inTimerEvent = true; QEventLoop eventLoop; - QChronoTimer::singleShot(std::max(100ms, interval * 2), - &eventLoop, &QEventLoop::quit); + QTimer::singleShot(std::max(100ms, interval * 2), + &eventLoop, &QEventLoop::quit); eventLoop.exec(); inTimerEvent = false; @@ -501,8 +501,8 @@ void tst_QChronoTimer::timerInfiniteRecursion() (void) object.startTimer(interval); QEventLoop eventLoop; - QChronoTimer::singleShot(std::max(100ms, interval * 2), &eventLoop, - &QEventLoop::quit); + QTimer::singleShot(std::max(100ms, interval * 2), + &eventLoop, &QEventLoop::quit); eventLoop.exec(); QVERIFY(!object.timerEventRecursed); @@ -527,7 +527,7 @@ public: Q_EMIT done(); } if (recurse) { QEventLoop eventLoop; - QChronoTimer::singleShot(100ms, &eventLoop, &QEventLoop::quit); + QTimer::singleShot(100ms, &eventLoop, &QEventLoop::quit); eventLoop.exec(); } } @@ -804,7 +804,7 @@ public slots: void tst_QChronoTimer::recurseOnTimeoutAndStopTimer() { QEventLoop eventLoop; - QChronoTimer::singleShot(1s, &eventLoop, &QEventLoop::quit); + QTimer::singleShot(1s, &eventLoop, &QEventLoop::quit); RecursOnTimeoutAndStopTimerTimer t; t.one = new QChronoTimer(&t); @@ -1173,16 +1173,16 @@ public: switch (callType) { case String: - QChronoTimer::singleShot(0ns, this, SLOT(stringSlot())); + QTimer::singleShot(0ns, this, SLOT(stringSlot())); break; case PMF: - QChronoTimer::singleShot(0ns, this, &OrderHelper::pmfSlot); + QTimer::singleShot(0ns, this, &OrderHelper::pmfSlot); break; case Functor: - QChronoTimer::singleShot(0ns, this, [this]() { functorSlot(); }); + QTimer::singleShot(0ns, this, [this]() { functorSlot(); }); break; case FunctorNoCtx: - QChronoTimer::singleShot(0ns, [this]() { functorNoCtxSlot(); }); + QTimer::singleShot(0ns, [this]() { functorNoCtxSlot(); }); break; } }