1 | // Copyright (C) 2020 The Qt Company Ltd. |
2 | // SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only |
3 | |
4 | #include "qbasictimer.h" |
5 | #include "qabstracteventdispatcher.h" |
6 | #include "qabstracteventdispatcher_p.h" |
7 | |
8 | QT_BEGIN_NAMESPACE |
9 | |
10 | /*! |
11 | \class QBasicTimer |
12 | \inmodule QtCore |
13 | \brief The QBasicTimer class provides timer events for objects. |
14 | |
15 | \ingroup events |
16 | |
17 | This is a fast, lightweight, and low-level class used by Qt |
18 | internally. We recommend using the higher-level QTimer class |
19 | rather than this class if you want to use timers in your |
20 | applications. Note that this timer is a repeating timer that |
21 | will send subsequent timer events unless the stop() function is called. |
22 | |
23 | To use this class, create a QBasicTimer, and call its start() |
24 | function with a timeout interval and with a pointer to a QObject |
25 | subclass. When the timer times out it will send a timer event to |
26 | the QObject subclass. The timer can be stopped at any time using |
27 | stop(). isActive() returns \c true for a timer that is running; |
28 | i.e. it has been started, has not reached the timeout time, and |
29 | has not been stopped. The timer's ID can be retrieved using |
30 | timerId(). |
31 | |
32 | Objects of this class cannot be copied, but can be moved, so you |
33 | can maintain a list of basic timers by holding them in container |
34 | that supports move-only types, e.g. std::vector. |
35 | |
36 | \sa QTimer, QChronoTimer, QTimerEvent, QObject::timerEvent(), |
37 | Timers, {Affine Transformations} |
38 | */ |
39 | |
40 | |
41 | /*! |
42 | \fn QBasicTimer::QBasicTimer() |
43 | |
44 | Constructs a basic timer. |
45 | |
46 | \sa start() |
47 | */ |
48 | |
49 | /*! |
50 | \fn QBasicTimer::QBasicTimer(QBasicTimer &&other) |
51 | \since 5.14 |
52 | |
53 | Move-constructs a basic timer from \a other, which is left |
54 | \l{isActive()}{inactive}. |
55 | |
56 | \sa isActive(), swap() |
57 | */ |
58 | |
59 | /*! |
60 | \fn QBasicTimer &QBasicTimer::operator=(QBasicTimer &&other) |
61 | \since 5.14 |
62 | |
63 | Move-assigns \a other to this basic timer. The timer |
64 | previously represented by this basic timer is stopped. |
65 | \a other is left as \l{isActive()}{inactive}. |
66 | |
67 | \sa stop(), isActive(), swap() |
68 | */ |
69 | |
70 | /*! |
71 | \fn QBasicTimer::~QBasicTimer() |
72 | |
73 | Destroys the basic timer. |
74 | */ |
75 | |
76 | /*! |
77 | \fn bool QBasicTimer::isActive() const |
78 | |
79 | Returns \c true if the timer is running and has not been stopped; otherwise |
80 | returns \c false. |
81 | |
82 | \sa start(), stop() |
83 | */ |
84 | |
85 | /*! |
86 | \fn QBasicTimer::swap(QBasicTimer &other) |
87 | \since 5.14 |
88 | |
89 | Swaps the timer \a other with this timer. |
90 | This operation is very fast and never fails. |
91 | */ |
92 | |
93 | /*! |
94 | \fn swap(QBasicTimer &lhs, QBasicTimer &rhs) |
95 | \relates QBasicTimer |
96 | \since 5.14 |
97 | |
98 | Swaps the timer \a lhs with \a rhs. |
99 | This operation is very fast and never fails. |
100 | */ |
101 | |
102 | /*! |
103 | \fn int QBasicTimer::timerId() const |
104 | \obsolete |
105 | |
106 | Returns the timer's ID. |
107 | |
108 | In new code use id() instead. |
109 | |
110 | \sa QTimerEvent::timerId() |
111 | */ |
112 | |
113 | /*! |
114 | \fn Qt::TimerId QBasicTimer::id() const |
115 | \since 6.8 |
116 | |
117 | Returns the timer's ID. |
118 | |
119 | \sa QTimerEvent::id() |
120 | */ |
121 | |
122 | /*! |
123 | \fn void QBasicTimer::start(int msec, QObject *object) |
124 | |
125 | \obsolete Use chrono overload instead. |
126 | */ |
127 | |
128 | /*! |
129 | \since 6.5 |
130 | |
131 | Starts (or restarts) the timer with a \a duration timeout. The |
132 | timer will be a Qt::CoarseTimer. See Qt::TimerType for information on the |
133 | different timer types. |
134 | |
135 | The given \a object will receive timer events. |
136 | |
137 | \sa stop(), isActive(), QObject::timerEvent(), Qt::CoarseTimer |
138 | */ |
139 | void QBasicTimer::start(std::chrono::milliseconds duration, QObject *object) |
140 | { |
141 | start(duration, timerType: Qt::CoarseTimer, obj: object); |
142 | } |
143 | |
144 | /*! |
145 | \fn QBasicTimer::start(int msec, Qt::TimerType timerType, QObject *obj) |
146 | \overload |
147 | \obsolete |
148 | |
149 | Use chrono overload instead. |
150 | */ |
151 | |
152 | /*! |
153 | \since 6.5 |
154 | |
155 | Starts (or restarts) the timer with a \a duration timeout and the |
156 | given \a timerType. See Qt::TimerType for information on the different |
157 | timer types. |
158 | |
159 | \a obj will receive timer events. |
160 | |
161 | \sa stop(), isActive(), QObject::timerEvent(), Qt::TimerType |
162 | */ |
163 | void QBasicTimer::start(std::chrono::milliseconds duration, Qt::TimerType timerType, QObject *obj) |
164 | { |
165 | QAbstractEventDispatcher *eventDispatcher = QAbstractEventDispatcher::instance(); |
166 | if (Q_UNLIKELY(duration.count() < 0)) { |
167 | qWarning(msg: "QBasicTimer::start: Timers cannot have negative timeouts" ); |
168 | return; |
169 | } |
170 | if (Q_UNLIKELY(!eventDispatcher)) { |
171 | qWarning(msg: "QBasicTimer::start: QBasicTimer can only be used with threads started with QThread" ); |
172 | return; |
173 | } |
174 | if (Q_UNLIKELY(obj && obj->thread() != eventDispatcher->thread())) { |
175 | qWarning(msg: "QBasicTimer::start: Timers cannot be started from another thread" ); |
176 | return; |
177 | } |
178 | stop(); |
179 | if (obj) |
180 | m_id = eventDispatcher->registerTimer(interval: duration, timerType, object: obj); |
181 | } |
182 | |
183 | /*! |
184 | Stops the timer. |
185 | |
186 | \sa start(), isActive() |
187 | */ |
188 | void QBasicTimer::stop() |
189 | { |
190 | if (isActive()) { |
191 | QAbstractEventDispatcher *eventDispatcher = QAbstractEventDispatcher::instance(); |
192 | if (eventDispatcher && !eventDispatcher->unregisterTimer(timerId: m_id)) { |
193 | qWarning(msg: "QBasicTimer::stop: Failed. Possibly trying to stop from a different thread" ); |
194 | return; |
195 | } |
196 | QAbstractEventDispatcherPrivate::releaseTimerId(id: m_id); |
197 | } |
198 | m_id = Qt::TimerId::Invalid; |
199 | } |
200 | |
201 | QT_END_NAMESPACE |
202 | |