1 /****************************************************************************
2 **
3 ** Copyright (C) 2016 The Qt Company Ltd.
4 ** Contact: https://www.qt.io/licensing/
5 **
6 ** This file is part of the QtCore module of the Qt Toolkit.
7 **
8 ** $QT_BEGIN_LICENSE:LGPL$
9 ** Commercial License Usage
10 ** Licensees holding valid commercial Qt licenses may use this file in
11 ** accordance with the commercial license agreement provided with the
12 ** Software or, alternatively, in accordance with the terms contained in
13 ** a written agreement between you and The Qt Company. For licensing terms
14 ** and conditions see https://www.qt.io/terms-conditions. For further
15 ** information use the contact form at https://www.qt.io/contact-us.
16 **
17 ** GNU Lesser General Public License Usage
18 ** Alternatively, this file may be used under the terms of the GNU Lesser
19 ** General Public License version 3 as published by the Free Software
20 ** Foundation and appearing in the file LICENSE.LGPL3 included in the
21 ** packaging of this file. Please review the following information to
22 ** ensure the GNU Lesser General Public License version 3 requirements
23 ** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
24 **
25 ** GNU General Public License Usage
26 ** Alternatively, this file may be used under the terms of the GNU
27 ** General Public License version 2.0 or (at your option) the GNU General
28 ** Public license version 3 or any later version approved by the KDE Free
29 ** Qt Foundation. The licenses are as published by the Free Software
30 ** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
31 ** included in the packaging of this file. Please review the following
32 ** information to ensure the GNU General Public License requirements will
33 ** be met: https://www.gnu.org/licenses/gpl-2.0.html and
34 ** https://www.gnu.org/licenses/gpl-3.0.html.
35 **
36 ** $QT_END_LICENSE$
37 **
38 ****************************************************************************/
39 
40 #include "qbasictimer.h"
41 #include "qabstracteventdispatcher.h"
42 #include "qabstracteventdispatcher_p.h"
43 
44 QT_BEGIN_NAMESPACE
45 
46 /*!
47     \class QBasicTimer
48     \inmodule QtCore
49     \brief The QBasicTimer class provides timer events for objects.
50 
51     \ingroup events
52 
53     This is a fast, lightweight, and low-level class used by Qt
54     internally. We recommend using the higher-level QTimer class
55     rather than this class if you want to use timers in your
56     applications. Note that this timer is a repeating timer that
57     will send subsequent timer events unless the stop() function is called.
58 
59     To use this class, create a QBasicTimer, and call its start()
60     function with a timeout interval and with a pointer to a QObject
61     subclass. When the timer times out it will send a timer event to
62     the QObject subclass. The timer can be stopped at any time using
63     stop(). isActive() returns \c true for a timer that is running;
64     i.e. it has been started, has not reached the timeout time, and
65     has not been stopped. The timer's ID can be retrieved using
66     timerId().
67 
68     Objects of this class cannot be copied, but can be moved, so you
69     can maintain a list of basic timers by holding them in container
70     that supports move-only types, e.g. std::vector.
71 
72     The \l{widgets/wiggly}{Wiggly} example uses QBasicTimer to repaint
73     a widget at regular intervals.
74 
75     \sa QTimer, QTimerEvent, QObject::timerEvent(), Timers, {Wiggly Example}
76 */
77 
78 
79 /*!
80     \fn QBasicTimer::QBasicTimer()
81 
82     Contructs a basic timer.
83 
84     \sa start()
85 */
86 
87 /*!
88     \fn QBasicTimer::QBasicTimer(QBasicTimer &&other)
89     \since 5.14
90 
91     Move-constructs a basic timer from \a other, which is left
92     \l{isActive()}{inactive}.
93 
94     \sa isActive(), swap()
95 */
96 
97 /*!
98     \fn QBasicTimer &QBasicTimer::operator=(QBasicTimer &&other)
99     \since 5.14
100 
101     Move-assigns \a other to this basic timer. The timer
102     previously represented by this basic timer is stopped.
103     \a other is left as \l{isActive()}{inactive}.
104 
105     \sa stop(), isActive(), swap()
106 */
107 
108 #if QT_DEPRECATED_SINCE(5, 14)
109 #if QT_VERSION < QT_VERSION_CHECK(6, 0, 0)
110 /*!
111     \internal
112 */
QBasicTimer(const QBasicTimer & other)113 QBasicTimer::QBasicTimer(const QBasicTimer &other)
114     : id{other.id}
115 {
116     qWarning("QBasicTimer can't be copied");
117 }
118 
119 /*!
120     \internal
121 */
operator =(const QBasicTimer & other)122 QBasicTimer &QBasicTimer::operator=(const QBasicTimer &other)
123 {
124     id = other.id;
125     qWarning("QBasicTimer can't be assigned to");
126     return *this;
127 }
128 #endif
129 #endif
130 
131 /*!
132     \fn QBasicTimer::~QBasicTimer()
133 
134     Destroys the basic timer.
135 */
136 
137 /*!
138     \fn bool QBasicTimer::isActive() const
139 
140     Returns \c true if the timer is running and has not been stopped; otherwise
141     returns \c false.
142 
143     \sa start(), stop()
144 */
145 
146 /*!
147     \fn QBasicTimer::swap(QBasicTimer &other)
148     \fn swap(QBasicTimer &lhs, QBasicTimer &rhs)
149     \since 5.14
150 
151     Swaps string \a other with this string, or \a lhs with \a rhs.
152     This operation is very fast and never fails.
153 */
154 
155 /*!
156     \fn int QBasicTimer::timerId() const
157 
158     Returns the timer's ID.
159 
160     \sa QTimerEvent::timerId()
161 */
162 
163 /*!
164     \fn void QBasicTimer::start(int msec, QObject *object)
165 
166     Starts (or restarts) the timer with a \a msec milliseconds timeout. The
167     timer will be a Qt::CoarseTimer. See Qt::TimerType for information on the
168     different timer types.
169 
170     The given \a object will receive timer events.
171 
172     \sa stop(), isActive(), QObject::timerEvent(), Qt::CoarseTimer
173  */
start(int msec,QObject * obj)174 void QBasicTimer::start(int msec, QObject *obj)
175 {
176     start(msec, Qt::CoarseTimer, obj);
177 }
178 
179 /*!
180     \overload
181 
182     Starts (or restarts) the timer with a \a msec milliseconds timeout and the
183     given \a timerType. See Qt::TimerType for information on the different
184     timer types.
185 
186     \a obj will receive timer events.
187 
188     \sa stop(), isActive(), QObject::timerEvent(), Qt::TimerType
189  */
start(int msec,Qt::TimerType timerType,QObject * obj)190 void QBasicTimer::start(int msec, Qt::TimerType timerType, QObject *obj)
191 {
192     QAbstractEventDispatcher *eventDispatcher = QAbstractEventDispatcher::instance();
193     if (Q_UNLIKELY(msec < 0)) {
194         qWarning("QBasicTimer::start: Timers cannot have negative timeouts");
195         return;
196     }
197     if (Q_UNLIKELY(!eventDispatcher)) {
198         qWarning("QBasicTimer::start: QBasicTimer can only be used with threads started with QThread");
199         return;
200     }
201     if (Q_UNLIKELY(obj && obj->thread() != eventDispatcher->thread())) {
202         qWarning("QBasicTimer::start: Timers cannot be started from another thread");
203         return;
204     }
205     stop();
206     if (obj)
207         id = eventDispatcher->registerTimer(msec, timerType, obj);
208 }
209 
210 /*!
211     Stops the timer.
212 
213     \sa start(), isActive()
214 */
stop()215 void QBasicTimer::stop()
216 {
217     if (id) {
218         QAbstractEventDispatcher *eventDispatcher = QAbstractEventDispatcher::instance();
219         if (eventDispatcher && !eventDispatcher->unregisterTimer(id)) {
220             qWarning("QBasicTimer::stop: Failed. Possibly trying to stop from a different thread");
221             return;
222         }
223         QAbstractEventDispatcherPrivate::releaseTimerId(id);
224     }
225     id = 0;
226 }
227 
228 QT_END_NAMESPACE
229