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
8QT_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 The \l{widgets/tetrix}{Tetrix} example uses QBasicTimer to control
37 the rate at which pieces fall.
38
39 \sa QTimer, QTimerEvent, QObject::timerEvent(), Timers, {Affine Transformations}
40*/
41
42
43/*!
44 \fn QBasicTimer::QBasicTimer()
45
46 Constructs a basic timer.
47
48 \sa start()
49*/
50
51/*!
52 \fn QBasicTimer::QBasicTimer(QBasicTimer &&other)
53 \since 5.14
54
55 Move-constructs a basic timer from \a other, which is left
56 \l{isActive()}{inactive}.
57
58 \sa isActive(), swap()
59*/
60
61/*!
62 \fn QBasicTimer &QBasicTimer::operator=(QBasicTimer &&other)
63 \since 5.14
64
65 Move-assigns \a other to this basic timer. The timer
66 previously represented by this basic timer is stopped.
67 \a other is left as \l{isActive()}{inactive}.
68
69 \sa stop(), isActive(), swap()
70*/
71
72/*!
73 \fn QBasicTimer::~QBasicTimer()
74
75 Destroys the basic timer.
76*/
77
78/*!
79 \fn bool QBasicTimer::isActive() const
80
81 Returns \c true if the timer is running and has not been stopped; otherwise
82 returns \c false.
83
84 \sa start(), stop()
85*/
86
87/*!
88 \fn QBasicTimer::swap(QBasicTimer &other)
89 \since 5.14
90
91 Swaps the timer \a other with this timer.
92 This operation is very fast and never fails.
93*/
94
95/*!
96 \fn swap(QBasicTimer &lhs, QBasicTimer &rhs)
97 \relates QBasicTimer
98 \since 5.14
99
100 Swaps the timer \a lhs with \a rhs.
101 This operation is very fast and never fails.
102*/
103
104/*!
105 \fn int QBasicTimer::timerId() const
106
107 Returns the timer's ID.
108
109 \sa QTimerEvent::timerId()
110*/
111
112/*!
113 \fn void QBasicTimer::start(int msec, QObject *object)
114
115 \obsolete Use chrono overload instead.
116*/
117
118/*!
119 \since 6.5
120
121 Starts (or restarts) the timer with a \a duration timeout. The
122 timer will be a Qt::CoarseTimer. See Qt::TimerType for information on the
123 different timer types.
124
125 The given \a object will receive timer events.
126
127 \sa stop(), isActive(), QObject::timerEvent(), Qt::CoarseTimer
128 */
129void QBasicTimer::start(std::chrono::milliseconds duration, QObject *object)
130{
131 start(duration, timerType: Qt::CoarseTimer, obj: object);
132}
133
134/*!
135 \fn QBasicTimer::start(int msec, Qt::TimerType timerType, QObject *obj)
136 \overload
137 \obsolete
138
139 Use chrono overload instead.
140*/
141
142/*!
143 \since 6.5
144
145 Starts (or restarts) the timer with a \a duration timeout and the
146 given \a timerType. See Qt::TimerType for information on the different
147 timer types.
148
149 \a obj will receive timer events.
150
151 \sa stop(), isActive(), QObject::timerEvent(), Qt::TimerType
152 */
153void QBasicTimer::start(std::chrono::milliseconds duration, Qt::TimerType timerType, QObject *obj)
154{
155 QAbstractEventDispatcher *eventDispatcher = QAbstractEventDispatcher::instance();
156 if (Q_UNLIKELY(duration.count() < 0)) {
157 qWarning(msg: "QBasicTimer::start: Timers cannot have negative timeouts");
158 return;
159 }
160 if (Q_UNLIKELY(!eventDispatcher)) {
161 qWarning(msg: "QBasicTimer::start: QBasicTimer can only be used with threads started with QThread");
162 return;
163 }
164 if (Q_UNLIKELY(obj && obj->thread() != eventDispatcher->thread())) {
165 qWarning(msg: "QBasicTimer::start: Timers cannot be started from another thread");
166 return;
167 }
168 stop();
169 if (obj)
170 id = eventDispatcher->registerTimer(interval: duration.count(), timerType, object: obj);
171}
172
173/*!
174 Stops the timer.
175
176 \sa start(), isActive()
177*/
178void QBasicTimer::stop()
179{
180 if (id) {
181 QAbstractEventDispatcher *eventDispatcher = QAbstractEventDispatcher::instance();
182 if (eventDispatcher && !eventDispatcher->unregisterTimer(timerId: id)) {
183 qWarning(msg: "QBasicTimer::stop: Failed. Possibly trying to stop from a different thread");
184 return;
185 }
186 QAbstractEventDispatcherPrivate::releaseTimerId(id);
187 }
188 id = 0;
189}
190
191QT_END_NAMESPACE
192

source code of qtbase/src/corelib/kernel/qbasictimer.cpp