Use QSlotObject helper to drastically simplify QTimer

Change-Id: Iaeef5dcb5282eef834df62c7db09d05851bd7c2b
Reviewed-by: Thiago Macieira <thiago.macieira@intel.com>
This commit is contained in:
Volker Hilsheimer 2023-04-29 22:30:36 +02:00
parent 2cd2789a40
commit ee308018f3
2 changed files with 40 additions and 170 deletions

View File

@ -441,125 +441,26 @@ void QTimer::singleShot(int msec, Qt::TimerType timerType, const QObject *receiv
} }
} }
/*! \fn template<typename PointerToMemberFunction> void QTimer::singleShot(int msec, const QObject *receiver, PointerToMemberFunction method) /*! \fn template<typename Functor> void QTimer::singleShot(int msec, const QObject *context, Functor &&functor)
\fn template<typename Functor> void QTimer::singleShot(int msec, Qt::TimerType timerType, const QObject *context, Functor &&functor)
\fn template<typename Functor> void QTimer::singleShot(int msec, Functor &&functor)
\fn template<typename Functor> void QTimer::singleShot(int msec, Qt::TimerType timerType, Functor &&functor)
\since 5.4 \since 5.4
\overload
\reentrant \reentrant
This static function calls a member function of a QObject after a given time interval. This static function calls \a functor after \a msec milliseconds.
It is very convenient to use this function because you do not need It is very convenient to use this function because you do not need
to bother with a \l{QObject::timerEvent()}{timerEvent} or to bother with a \l{QObject::timerEvent()}{timerEvent} or
create a local QTimer object. create a local QTimer object.
The \a receiver is the receiving object and the \a method is the member function. The If \a context is specified, then the \a functor will be called only if the
time interval is \a msec milliseconds. \a context object has not been destroyed before the interval occurs. The functor
will then be run the thread of \a context. The context's thread must have a
running Qt event loop.
If \a receiver is destroyed before the interval occurs, the method will not be called. If \a functor is a member
The function will be run in the thread of \a receiver. The receiver's thread must have function of \a context, then the function will be called on the object.
a running Qt event loop.
\sa start()
*/
/*! \fn template<typename PointerToMemberFunction> void QTimer::singleShot(int msec, Qt::TimerType timerType, const QObject *receiver, PointerToMemberFunction method)
\since 5.4
\overload
\reentrant
This static function calls a member function of a QObject after a given time interval.
It is very convenient to use this function because you do not need
to bother with a \l{QObject::timerEvent()}{timerEvent} or
create a local QTimer object.
The \a receiver is the receiving object and the \a method is the member function. The
time interval is \a msec milliseconds. The \a timerType affects the
accuracy of the timer.
If \a receiver is destroyed before the interval occurs, the method will not be called.
The function will be run in the thread of \a receiver. The receiver's thread must have
a running Qt event loop.
\sa start()
*/
/*! \fn template<typename Functor> void QTimer::singleShot(int msec, Functor functor)
\since 5.4
\overload
\reentrant
This static function calls \a functor after a given time interval.
It is very convenient to use this function because you do not need
to bother with a \l{QObject::timerEvent()}{timerEvent} or
create a local QTimer object.
The time interval is \a msec milliseconds.
\sa start()
*/
/*! \fn template<typename Functor> void QTimer::singleShot(int msec, Qt::TimerType timerType, Functor functor)
\since 5.4
\overload
\reentrant
This static function calls \a functor after a given time interval.
It is very convenient to use this function because you do not need
to bother with a \l{QObject::timerEvent()}{timerEvent} or
create a local QTimer object.
The time interval is \a msec milliseconds. The \a timerType affects the
accuracy of the timer.
\sa start()
*/
/*! \fn template<typename Functor> void QTimer::singleShot(int msec, const QObject *context, Functor functor)
\since 5.4
\overload
\reentrant
This static function calls \a functor after a given time interval.
It is very convenient to use this function because you do not need
to bother with a \l{QObject::timerEvent()}{timerEvent} or
create a local QTimer object.
The time interval is \a msec milliseconds.
If \a context is destroyed before the interval occurs, the method will not be called.
The function will be run in the thread of \a context. The context's thread must have
a running Qt event loop.
\sa start()
*/
/*! \fn template<typename Functor> void QTimer::singleShot(int msec, Qt::TimerType timerType, const QObject *context, Functor functor)
\since 5.4
\overload
\reentrant
This static function calls \a functor after a given time interval.
It is very convenient to use this function because you do not need
to bother with a \l{QObject::timerEvent()}{timerEvent} or
create a local QTimer object.
The time interval is \a msec milliseconds. The \a timerType affects the
accuracy of the timer.
If \a context is destroyed before the interval occurs, the method will not be called.
The function will be run in the thread of \a context. The context's thread must have
a running Qt event loop.
\sa start() \sa start()
*/ */

View File

@ -49,81 +49,50 @@ public:
static void singleShot(int msec, const QObject *receiver, const char *member); static void singleShot(int msec, const QObject *receiver, const char *member);
static void singleShot(int msec, Qt::TimerType timerType, const QObject *receiver, const char *member); static void singleShot(int msec, Qt::TimerType timerType, const QObject *receiver, const char *member);
// singleShot with context
template <typename Duration, typename Func1>
static inline void singleShot(Duration interval,
#ifdef Q_QDOC #ifdef Q_QDOC
template<typename PointerToMemberFunction> const QObject *receiver,
static void singleShot(int msec, const QObject *receiver, PointerToMemberFunction method);
template<typename PointerToMemberFunction>
static void singleShot(int msec, Qt::TimerType timerType, const QObject *receiver, PointerToMemberFunction method);
template<typename Functor>
static void singleShot(int msec, Functor functor);
template<typename Functor>
static void singleShot(int msec, Qt::TimerType timerType, Functor functor);
template<typename Functor, int>
static void singleShot(int msec, const QObject *context, Functor functor);
template<typename Functor, int>
static void singleShot(int msec, Qt::TimerType timerType, const QObject *context, Functor functor);
template <typename Functor>
QMetaObject::Connection callOnTimeout(Functor slot, Qt::ConnectionType connectionType = Qt::AutoConnection);
template <typename Functor>
QMetaObject::Connection callOnTimeout(const QObject *context, Functor slot, Qt::ConnectionType connectionType = Qt::AutoConnection);
template <typename MemberFunction>
QMetaObject::Connection callOnTimeout(const QObject *receiver, MemberFunction *slot, Qt::ConnectionType connectionType = Qt::AutoConnection);
#else #else
// singleShot to a QObject slot const typename QtPrivate::ContextTypeForFunctor<Func1>::ContextType *receiver,
template <typename Duration, typename Func1> #endif
static inline void singleShot(Duration interval, const typename QtPrivate::FunctionPointer<Func1>::Object *receiver, Func1 slot)
Func1 &&slot)
{ {
singleShot(interval, defaultTypeFor(interval), receiver, slot); singleShot(interval, defaultTypeFor(interval), receiver, std::forward<Func1>(slot));
} }
template <typename Duration, typename Func1> template <typename Duration, typename Func1>
static inline void singleShot(Duration interval, Qt::TimerType timerType, const typename QtPrivate::FunctionPointer<Func1>::Object *receiver, static inline void singleShot(Duration interval, Qt::TimerType timerType,
Func1 slot) #ifdef Q_QDOC
const QObject *receiver,
#else
const typename QtPrivate::ContextTypeForFunctor<Func1>::ContextType *receiver,
#endif
Func1 &&slot)
{ {
typedef QtPrivate::FunctionPointer<Func1> SlotType; using Prototype = void(*)();
//compilation error if the slot has arguments.
static_assert(int(SlotType::ArgumentCount) == 0,
"The slot must not have any arguments.");
singleShotImpl(interval, timerType, receiver, singleShotImpl(interval, timerType, receiver,
new QtPrivate::QSlotObject<Func1, typename SlotType::Arguments, void>(slot)); QtPrivate::makeSlotObject<Prototype>(std::forward<Func1>(slot)));
} }
// singleShot to a functor or function pointer (without context) // singleShot without context
template <typename Duration, typename Func1> template <typename Duration, typename Func1>
static inline typename std::enable_if<!QtPrivate::FunctionPointer<Func1>::IsPointerToMemberFunction && static inline void singleShot(Duration interval, Func1 &&slot)
!std::is_same<const char*, Func1>::value, void>::type
singleShot(Duration interval, Func1 slot)
{ {
singleShot(interval, defaultTypeFor(interval), nullptr, std::move(slot)); singleShot(interval, defaultTypeFor(interval), nullptr, std::forward<Func1>(slot));
} }
template <typename Duration, typename Func1> template <typename Duration, typename Func1>
static inline typename std::enable_if<!QtPrivate::FunctionPointer<Func1>::IsPointerToMemberFunction && static inline void singleShot(Duration interval, Qt::TimerType timerType, Func1 &&slot)
!std::is_same<const char*, Func1>::value, void>::type
singleShot(Duration interval, Qt::TimerType timerType, Func1 slot)
{ {
singleShot(interval, timerType, nullptr, std::move(slot)); singleShot(interval, timerType, nullptr, std::forward<Func1>(slot));
}
// singleShot to a functor or function pointer (with context)
template <typename Duration, typename Func1>
static inline typename std::enable_if<!QtPrivate::FunctionPointer<Func1>::IsPointerToMemberFunction &&
!std::is_same<const char*, Func1>::value, void>::type
singleShot(Duration interval, const QObject *context, Func1 slot)
{
singleShot(interval, defaultTypeFor(interval), context, std::move(slot));
}
template <typename Duration, typename Func1>
static inline typename std::enable_if<!QtPrivate::FunctionPointer<Func1>::IsPointerToMemberFunction &&
!std::is_same<const char*, Func1>::value, void>::type
singleShot(Duration interval, Qt::TimerType timerType, const QObject *context, Func1 slot)
{
//compilation error if the slot has arguments.
typedef QtPrivate::FunctionPointer<Func1> SlotType;
static_assert(int(SlotType::ArgumentCount) <= 0, "The slot must not have any arguments.");
singleShotImpl(interval, timerType, context,
new QtPrivate::QFunctorSlotObject<Func1, QtPrivate::List<>, void>(std::move(slot)));
} }
#ifdef Q_QDOC
template <typename Functor>
QMetaObject::Connection callOnTimeout(Functor &&slot, Qt::ConnectionType connectionType = Qt::AutoConnection);
template <typename Functor>
QMetaObject::Connection callOnTimeout(const QObject *context, Functor &&slot, Qt::ConnectionType connectionType = Qt::AutoConnection);
#else
template <typename ... Args> template <typename ... Args>
QMetaObject::Connection callOnTimeout(Args && ...args) QMetaObject::Connection callOnTimeout(Args && ...args)
{ {