Qt
Internal/Contributor docs for the Qt SDK. <b>Note:</b> These are NOT official API docs; those are found <a href='https://doc.qt.io/'>here</a>.
Loading...
Searching...
No Matches
qsingleshottimer_p.h
Go to the documentation of this file.
1// Copyright (C) 2022 The Qt Company Ltd.
2// Copyright (C) 2016 Intel Corporation.
3// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
4
5#ifndef QSINGLESHOTTIMER_P_H
6#define QSINGLESHOTTIMER_P_H
7
8//
9// W A R N I N G
10// -------------
11//
12// This file is not part of the Qt API. It exists purely as an
13// implementation detail. This header file may change from version to
14// version without notice, or even be removed.
15//
16// We mean it.
17//
18
20#include "qcoreapplication.h"
21#include "qmetaobject_p.h"
22#include "private/qnumeric_p.h"
23
24#include <chrono>
25
27
29{
31
33
34public:
35 // use the same duration type
37
38 inline ~QSingleShotTimer();
39 inline QSingleShotTimer(Duration interval, Qt::TimerType timerType,
40 const QObject *r, const char *member);
41 inline QSingleShotTimer(Duration interval, Qt::TimerType timerType,
42 const QObject *r, QtPrivate::QSlotObjectBase *slotObj);
43
44 inline void startTimerForReceiver(Duration interval, Qt::TimerType timerType,
45 const QObject *receiver);
46
47 static Duration fromMsecs(std::chrono::milliseconds ms)
48 {
49 using namespace std::chrono;
50 using ratio = std::ratio_divide<std::milli, Duration::period>;
51 static_assert(ratio::den == 1);
52
53 Duration::rep r;
54 if (qMulOverflow<ratio::num>(ms.count(), &r)) {
55 qWarning("QTimer::singleShot(std::chrono::milliseconds, ...): "
56 "interval argument overflowed when converted to nanoseconds.");
57 return Duration::max();
58 }
59 return Duration{r};
60 }
62 void timeout();
63
64private:
65 inline void timerEvent(QTimerEvent *) override;
66};
67
69 const QObject *r, const char *member)
71{
72 connect(this, SIGNAL(timeout()), r, member);
73 startTimerForReceiver(interval, timerType, r);
74}
75
77 const QObject *r, QtPrivate::QSlotObjectBase *slotObj)
79{
80 int signal_index = QMetaObjectPrivate::signalOffset(&staticMetaObject);
81 Q_ASSERT(QMetaObjectPrivate::signal(&staticMetaObject, signal_index).name() == "timeout");
82 QObjectPrivate::connectImpl(this, signal_index, r ? r : this, nullptr, slotObj,
83 Qt::AutoConnection, nullptr, &staticMetaObject);
84
85 startTimerForReceiver(interval, timerType, r);
86}
87
93
94/*
95 Move the timer, and the dispatching and handling of the timer event, into
96 the same thread as where it will be handled, so that it fires reliably even
97 if the thread that set up the timer is busy.
98*/
100 const QObject *receiver)
101{
102 if (receiver && receiver->thread() != thread()) {
103 // Avoid leaking the QSingleShotTimer instance in case the application exits before the
104 // timer fires
107 setParent(nullptr);
108 moveToThread(receiver->thread());
109
110 QDeadlineTimer deadline(interval, timerType);
111 auto invokable = [this, deadline, timerType] {
112 if (deadline.hasExpired()) {
113 Q_EMIT timeout();
114 } else {
116 }
117 };
119 } else {
120 timerId = Qt::TimerId{startTimer(interval, timerType)};
121 }
122}
123
125{
126 // need to kill the timer _before_ we emit timeout() in case the
127 // slot connected to timeout calls processEvents()
128 if (timerId > Qt::TimerId::Invalid)
129 killTimer(std::exchange(timerId, Qt::TimerId::Invalid));
130
131 Q_EMIT timeout();
132
133 // we would like to use delete later here, but it feels like a
134 // waste to post a new event to handle this event, so we just unset the flag
135 // and explicitly delete...
136 delete this;
137}
138
140
141#endif // QSINGLESHOTTIMER_P_H
std::chrono::nanoseconds Duration
A {std::chrono::duration} type that is used in various API in this class.
static QCoreApplication * instance() noexcept
Returns a pointer to the application's QCoreApplication (or QGuiApplication/QApplication) instance.
void aboutToQuit(QPrivateSignal)
This signal is emitted when the application is about to quit the main event loop, e....
\inmodule QtCore
bool hasExpired() const noexcept
Returns true if this QDeadlineTimer object has expired, false if there remains time left.
std::chrono::nanoseconds remainingTimeAsDuration() const noexcept
Returns the time remaining before the deadline.
static QMetaObject::Connection connectImpl(const QObject *sender, int signal_index, const QObject *receiver, void **slot, QtPrivate::QSlotObjectBase *slotObj, int type, const int *types, const QMetaObject *senderMetaObject)
Definition qobject.cpp:5241
\inmodule QtCore
Definition qobject.h:103
int startTimer(int interval, Qt::TimerType timerType=Qt::CoarseTimer)
This is an overloaded function that will start a timer of type timerType and a timeout of interval mi...
Definition qobject.cpp:1817
static QMetaObject::Connection connect(const QObject *sender, const char *signal, const QObject *receiver, const char *member, Qt::ConnectionType=Qt::AutoConnection)
\threadsafe
Definition qobject.cpp:2960
void setParent(QObject *parent)
Makes the object a child of parent.
Definition qobject.cpp:2195
QThread * thread() const
Returns the thread in which the object lives.
Definition qobject.cpp:1598
bool moveToThread(QThread *thread QT6_DECL_NEW_OVERLOAD_TAIL)
Changes the thread affinity for this object and its children and returns true on success.
Definition qobject.cpp:1643
void killTimer(int id)
Kills the timer with timer identifier, id.
Definition qobject.cpp:1912
void deleteLater()
\threadsafe
Definition qobject.cpp:2435
QAbstractEventDispatcher::Duration Duration
void startTimerForReceiver(Duration interval, Qt::TimerType timerType, const QObject *receiver)
void timerEvent(QTimerEvent *) override
This event handler can be reimplemented in a subclass to receive timer events for the object.
static Duration fromMsecs(std::chrono::milliseconds ms)
QSingleShotTimer(Duration interval, Qt::TimerType timerType, const QObject *r, const char *member)
\inmodule QtCore
Definition qcoreevent.h:366
Combined button and popup list for selecting options.
TimerType
@ AutoConnection
@ QueuedConnection
#define qWarning
Definition qlogging.h:166
#define SIGNAL(a)
Definition qobjectdefs.h:53
GLboolean r
[2]
GLuint name
#define Q_ASSERT(cond)
Definition qrandom.cpp:47
#define Q_OBJECT
#define Q_EMIT
#define Q_SIGNALS
QDeadlineTimer deadline(30s)
static int signalOffset(const QMetaObject *m)
static Q_CORE_EXPORT QMetaMethod signal(const QMetaObject *m, int signal_index)
static bool invokeMethod(QObject *obj, const char *member, Qt::ConnectionType, QGenericReturnArgument ret, QGenericArgument val0=QGenericArgument(nullptr), QGenericArgument val1=QGenericArgument(), QGenericArgument val2=QGenericArgument(), QGenericArgument val3=QGenericArgument(), QGenericArgument val4=QGenericArgument(), QGenericArgument val5=QGenericArgument(), QGenericArgument val6=QGenericArgument(), QGenericArgument val7=QGenericArgument(), QGenericArgument val8=QGenericArgument(), QGenericArgument val9=QGenericArgument())
\threadsafe This is an overloaded member function, provided for convenience. It differs from the abov...