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 \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 \memberswap{timer}
89*/
90
91/*!
92 \fn swap(QBasicTimer &lhs, QBasicTimer &rhs)
93 \relates QBasicTimer
94 \since 5.14
95
96 Swaps the timer \a lhs with \a rhs.
97 This operation is very fast and never fails.
98*/
99
100/*!
101 \fn int QBasicTimer::timerId() const
102 \obsolete
103
104 Returns the timer's ID.
105
106 In new code use id() instead.
107
108 \sa QTimerEvent::timerId()
109*/
110
111/*!
112 \fn Qt::TimerId QBasicTimer::id() const
113 \since 6.8
114
115 Returns the timer's ID.
116
117 \sa QTimerEvent::id()
118*/
119
120/*!
121 \fn void QBasicTimer::start(int msec, QObject *object)
122
123 \obsolete Use chrono overload instead.
124*/
125
126/*!
127 \since 6.5
128
129 Starts (or restarts) the timer with a \a duration timeout. The
130 timer will be a Qt::CoarseTimer. See Qt::TimerType for information on the
131 different timer types.
132
133 The given \a object will receive timer events.
134
135 \sa stop(), isActive(), QObject::timerEvent(), Qt::CoarseTimer
136 */
137void QBasicTimer::start(std::chrono::milliseconds duration, QObject *object)
138{
139 start(duration, timerType: Qt::CoarseTimer, obj: object);
140}
141
142/*!
143 \fn QBasicTimer::start(int msec, Qt::TimerType timerType, QObject *obj)
144 \overload
145 \obsolete
146
147 Use chrono overload instead.
148*/
149
150/*!
151 \since 6.5
152
153 Starts (or restarts) the timer with a \a duration timeout and the
154 given \a timerType. See Qt::TimerType for information on the different
155 timer types.
156
157 \a obj will receive timer events.
158
159 \sa stop(), isActive(), QObject::timerEvent(), Qt::TimerType
160 */
161void QBasicTimer::start(std::chrono::milliseconds duration, Qt::TimerType timerType, QObject *obj)
162{
163 QAbstractEventDispatcher *eventDispatcher = QAbstractEventDispatcher::instance();
164 if (Q_UNLIKELY(duration.count() < 0)) {
165 qWarning(msg: "QBasicTimer::start: Timers cannot have negative timeouts");
166 return;
167 }
168 if (Q_UNLIKELY(!eventDispatcher)) {
169 qWarning(msg: "QBasicTimer::start: QBasicTimer can only be used with threads started with QThread");
170 return;
171 }
172 if (Q_UNLIKELY(obj && obj->thread() != eventDispatcher->thread())) {
173 qWarning(msg: "QBasicTimer::start: Timers cannot be started from another thread");
174 return;
175 }
176 stop();
177 if (obj)
178 m_id = eventDispatcher->registerTimer(interval: duration, timerType, object: obj);
179}
180
181/*!
182 Stops the timer.
183
184 \sa start(), isActive()
185*/
186void QBasicTimer::stop()
187{
188 if (isActive()) {
189 QAbstractEventDispatcher *eventDispatcher = QAbstractEventDispatcher::instance();
190 if (eventDispatcher && !eventDispatcher->unregisterTimer(timerId: m_id)) {
191 qWarning(msg: "QBasicTimer::stop: Failed. Possibly trying to stop from a different thread");
192 return;
193 }
194 QAbstractEventDispatcherPrivate::releaseTimerId(id: m_id);
195 }
196 m_id = Qt::TimerId::Invalid;
197}
198
199QT_END_NAMESPACE
200

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