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
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 */
139void 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 */
163void 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*/
188void 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
201QT_END_NAMESPACE
202

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