1 | // Copyright (C) 2016 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 "qabstracteventdispatcher.h" |
5 | #include "qabstracteventdispatcher_p.h" |
6 | #include "qabstractnativeeventfilter.h" |
7 | |
8 | #include "qthread.h" |
9 | #include <private/qthread_p.h> |
10 | #include <private/qcoreapplication_p.h> |
11 | #include <private/qfreelist_p.h> |
12 | |
13 | #include <QtCore/q26numeric.h> |
14 | |
15 | QT_BEGIN_NAMESPACE |
16 | |
17 | using namespace std::chrono_literals; |
18 | |
19 | // we allow for 2^24 = 8^8 = 16777216 simultaneously running timers |
20 | struct QtTimerIdFreeListConstants : public QFreeListDefaultConstants |
21 | { |
22 | enum |
23 | { |
24 | InitialNextValue = 1, |
25 | BlockCount = 6 |
26 | }; |
27 | |
28 | static const int Sizes[BlockCount]; |
29 | }; |
30 | |
31 | enum { |
32 | Offset0 = 0x00000000, |
33 | Offset1 = 0x00000040, |
34 | Offset2 = 0x00000100, |
35 | Offset3 = 0x00001000, |
36 | Offset4 = 0x00010000, |
37 | Offset5 = 0x00100000, |
38 | |
39 | Size0 = Offset1 - Offset0, |
40 | Size1 = Offset2 - Offset1, |
41 | Size2 = Offset3 - Offset2, |
42 | Size3 = Offset4 - Offset3, |
43 | Size4 = Offset5 - Offset4, |
44 | Size5 = QtTimerIdFreeListConstants::MaxIndex - Offset5 |
45 | }; |
46 | |
47 | Q_CONSTINIT const int QtTimerIdFreeListConstants::Sizes[QtTimerIdFreeListConstants::BlockCount] = { |
48 | Size0, |
49 | Size1, |
50 | Size2, |
51 | Size3, |
52 | Size4, |
53 | Size5 |
54 | }; |
55 | |
56 | typedef QFreeList<void, QtTimerIdFreeListConstants> QtTimerIdFreeList; |
57 | Q_GLOBAL_STATIC(QtTimerIdFreeList, timerIdFreeList) |
58 | |
59 | template <typename T> static T fromDuration(std::chrono::nanoseconds interval) |
60 | { |
61 | using namespace std::chrono; |
62 | qint64 value = ceil<milliseconds>(d: interval).count(); |
63 | return q26::saturate_cast<T>(value); |
64 | } |
65 | |
66 | #if QT_VERSION < QT_VERSION_CHECK(7, 0, 0) |
67 | static inline QAbstractEventDispatcherV2 *v2(QAbstractEventDispatcher *self) |
68 | { |
69 | if (QAbstractEventDispatcherPrivate::get(o: self)->isV2) |
70 | return static_cast<QAbstractEventDispatcherV2 *>(self); |
71 | return nullptr; |
72 | } |
73 | |
74 | static inline const QAbstractEventDispatcherV2 *v2(const QAbstractEventDispatcher *self) |
75 | { |
76 | if (QAbstractEventDispatcherPrivate::get(o: self)->isV2) |
77 | return static_cast<const QAbstractEventDispatcherV2 *>(self); |
78 | return nullptr; |
79 | } |
80 | #endif // Qt 7 |
81 | |
82 | QAbstractEventDispatcherPrivate::QAbstractEventDispatcherPrivate() |
83 | { |
84 | // Create the timer ID free list here to make sure that it is destroyed |
85 | // after any global static thread that may be using it. |
86 | // See also QTBUG-58732. |
87 | if (!timerIdFreeList.isDestroyed()) |
88 | (void)timerIdFreeList(); |
89 | } |
90 | |
91 | QAbstractEventDispatcherPrivate::~QAbstractEventDispatcherPrivate() |
92 | = default; |
93 | |
94 | int QAbstractEventDispatcherPrivate::allocateTimerId() |
95 | { |
96 | // This function may be called after timerIdFreeList() has been destructed |
97 | // for example in case when application exits without waiting for |
98 | // running threads to exit and running thread finished() has been connected |
99 | // to a slot which triggers a sequence that registers new timer. |
100 | // See https://bugreports.qt-project.org/browse/QTBUG-38957. |
101 | if (QtTimerIdFreeList *fl = timerIdFreeList()) |
102 | return fl->next(); |
103 | return 0; // Note! returning 0 generates a warning |
104 | } |
105 | |
106 | void QAbstractEventDispatcherPrivate::releaseTimerId(int timerId) |
107 | { |
108 | // this function may be called by a global destructor after |
109 | // timerIdFreeList() has been destructed |
110 | if (QtTimerIdFreeList *fl = timerIdFreeList()) |
111 | fl->release(id: timerId); |
112 | } |
113 | |
114 | /*! |
115 | \class QAbstractEventDispatcher |
116 | \inmodule QtCore |
117 | \brief The QAbstractEventDispatcher class provides an interface to manage Qt's event queue. |
118 | |
119 | \ingroup events |
120 | |
121 | An event dispatcher receives events from the window system and other |
122 | sources. It then sends them to the QCoreApplication or QApplication |
123 | instance for processing and delivery. QAbstractEventDispatcher provides |
124 | fine-grained control over event delivery. |
125 | |
126 | For simple control of event processing use |
127 | QCoreApplication::processEvents(). |
128 | |
129 | For finer control of the application's event loop, call |
130 | instance() and call functions on the QAbstractEventDispatcher |
131 | object that is returned. If you want to use your own instance of |
132 | QAbstractEventDispatcher or of a QAbstractEventDispatcher |
133 | subclass, you must install it with QCoreApplication::setEventDispatcher() |
134 | or QThread::setEventDispatcher() \e before a default event dispatcher has |
135 | been installed. |
136 | |
137 | The main event loop is started by calling |
138 | QCoreApplication::exec(), and stopped by calling |
139 | QCoreApplication::exit(). Local event loops can be created using |
140 | QEventLoop. |
141 | |
142 | Programs that perform long operations can call processEvents() |
143 | with a bitwise OR combination of various QEventLoop::ProcessEventsFlag |
144 | values to control which events should be delivered. |
145 | |
146 | QAbstractEventDispatcher also allows the integration of an |
147 | external event loop with the Qt event loop. |
148 | |
149 | \sa QEventLoop, QCoreApplication, QThread |
150 | */ |
151 | /*! |
152 | \typedef QAbstractEventDispatcher::Duration |
153 | |
154 | A \c{std::chrono::duration} type that is used in various API in this class. |
155 | This type exists to facilitate a possible transition to a higher or lower |
156 | granularity. |
157 | |
158 | In all current platforms, it is \c nanoseconds. |
159 | */ |
160 | |
161 | /*! |
162 | Constructs a new event dispatcher with the given \a parent. |
163 | */ |
164 | QAbstractEventDispatcher::QAbstractEventDispatcher(QObject *parent) |
165 | : QObject(*new QAbstractEventDispatcherPrivate, parent) {} |
166 | |
167 | /*! |
168 | \internal |
169 | */ |
170 | QAbstractEventDispatcher::QAbstractEventDispatcher(QAbstractEventDispatcherPrivate &dd, |
171 | QObject *parent) |
172 | : QObject(dd, parent) {} |
173 | |
174 | /*! |
175 | Destroys the event dispatcher. |
176 | */ |
177 | QAbstractEventDispatcher::~QAbstractEventDispatcher() |
178 | { } |
179 | |
180 | /*! |
181 | Returns a pointer to the event dispatcher object for the specified |
182 | \a thread. If \a thread is \nullptr, the current thread is used. If no |
183 | event dispatcher exists for the specified thread, this function |
184 | returns \nullptr. |
185 | |
186 | \b{Note:} If Qt is built without thread support, the \a thread |
187 | argument is ignored. |
188 | */ |
189 | QAbstractEventDispatcher *QAbstractEventDispatcher::instance(QThread *thread) |
190 | { |
191 | QThreadData *data = thread ? QThreadData::get2(thread) : QThreadData::current(); |
192 | return data->eventDispatcher.loadRelaxed(); |
193 | } |
194 | |
195 | /*! |
196 | \fn bool QAbstractEventDispatcher::processEvents(QEventLoop::ProcessEventsFlags flags) |
197 | |
198 | Processes pending events that match \a flags until there are no |
199 | more events to process. Returns \c true if an event was processed; |
200 | otherwise returns \c false. |
201 | |
202 | This function is especially useful if you have a long running |
203 | operation, and want to show its progress without allowing user |
204 | input by using the QEventLoop::ExcludeUserInputEvents flag. |
205 | |
206 | If the QEventLoop::WaitForMoreEvents flag is set in \a flags, the |
207 | behavior of this function is as follows: |
208 | |
209 | \list |
210 | |
211 | \li If events are available, this function returns after processing |
212 | them. |
213 | |
214 | \li If no events are available, this function will wait until more |
215 | are available and return after processing newly available events. |
216 | |
217 | \endlist |
218 | |
219 | If the QEventLoop::WaitForMoreEvents flag is not set in \a flags, |
220 | and no events are available, this function will return |
221 | immediately. |
222 | |
223 | \b{Note:} This function does not process events continuously; it |
224 | returns after all available events are processed. |
225 | */ |
226 | |
227 | /*! |
228 | \internal |
229 | |
230 | \note processEvents() only processes events queued before the function |
231 | is called. Events that are posted while the function runs will be queued |
232 | until a later round of event processing. This only applies to posted Qt |
233 | events. For timers and system level events, the situation is unknown. |
234 | */ |
235 | |
236 | /*! |
237 | \fn void QAbstractEventDispatcher::registerSocketNotifier(QSocketNotifier *notifier) |
238 | |
239 | Registers \a notifier with the event loop. Subclasses must |
240 | implement this method to tie a socket notifier into another |
241 | event loop. |
242 | */ |
243 | |
244 | /*! \fn void QAbstractEventDispatcher::unregisterSocketNotifier(QSocketNotifier *notifier) |
245 | |
246 | Unregisters \a notifier from the event dispatcher. Subclasses must |
247 | reimplement this method to tie a socket notifier into another |
248 | event loop. Reimplementations must call the base |
249 | implementation. |
250 | */ |
251 | |
252 | /*! |
253 | \obsolete [6.8] This function will be removed in Qt 7. Use the overload taking \l Duration. |
254 | |
255 | Registers a timer with the specified \a interval and \a timerType for the |
256 | given \a object and returns the timer id. |
257 | */ |
258 | int QAbstractEventDispatcher::registerTimer(qint64 interval, Qt::TimerType timerType, QObject *object) |
259 | { |
260 | return int(registerTimer(interval: interval * 1ms, timerType, object)); |
261 | } |
262 | |
263 | /*! |
264 | \since 6.8 |
265 | \overload |
266 | |
267 | Registers a timer with the specified \a interval and \a timerType for the |
268 | given \a object and returns the timer id. |
269 | */ |
270 | Qt::TimerId QAbstractEventDispatcher::registerTimer(Duration interval, Qt::TimerType timerType, |
271 | QObject *object) |
272 | { |
273 | auto id = Qt::TimerId(QAbstractEventDispatcherPrivate::allocateTimerId()); |
274 | #if QT_VERSION < QT_VERSION_CHECK(7, 0, 0) |
275 | if (QAbstractEventDispatcherV2 *self = v2(self: this)) |
276 | self->registerTimer(timerId: id, interval, timerType, object); |
277 | else |
278 | registerTimer(timerId: qToUnderlying(e: id), interval: fromDuration<qint64>(interval), timerType, object); |
279 | #else |
280 | registerTimer(id, interval, timerType, object); |
281 | #endif |
282 | return id; |
283 | } |
284 | |
285 | #if QT_VERSION < QT_VERSION_CHECK(7, 0, 0) |
286 | /*! |
287 | \fn void QAbstractEventDispatcher::registerTimer(int timerId, qint64 interval, Qt::TimerType timerType, QObject *object) |
288 | |
289 | Register a timer with the specified \a timerId, \a interval, and \a |
290 | timerType for the given \a object. |
291 | */ |
292 | |
293 | /*! |
294 | \fn bool QAbstractEventDispatcher::unregisterTimer(int timerId) |
295 | |
296 | Unregisters the timer with the given \a timerId. |
297 | Returns \c true if successful; otherwise returns \c false. |
298 | |
299 | \sa registerTimer(), unregisterTimers() |
300 | */ |
301 | |
302 | /*! |
303 | \fn QList<TimerInfo> QAbstractEventDispatcher::registeredTimers(QObject *object) const |
304 | |
305 | Returns a list of registered timers for \a object. The TimerInfo struct has |
306 | \c timerId, \c interval, and \c timerType members. |
307 | |
308 | \sa Qt::TimerType |
309 | */ |
310 | |
311 | /*! |
312 | \fn int QAbstractEventDispatcher::remainingTime(int timerId) |
313 | |
314 | Returns the remaining time in milliseconds with the given \a timerId. |
315 | If the timer is inactive, the returned value will be -1. If the timer is |
316 | overdue, the returned value will be 0. |
317 | |
318 | \sa Qt::TimerType |
319 | */ |
320 | #else // Qt 7 |
321 | /*! |
322 | \fn void QAbstractEventDispatcher::registerTimer(Qt::TimerId timerId, Duration interval, Qt::TimerType timerType, QObject *object) |
323 | \since 6.8 |
324 | |
325 | Register a timer with the specified \a timerId, \a interval, and \a |
326 | timerType for the given \a object. |
327 | |
328 | \sa unregisterTimer(), timersForObject() |
329 | */ |
330 | |
331 | /*! |
332 | \fn bool QAbstractEventDispatcher::unregisterTimer(Qt::TimerId timerId) |
333 | \since 6.8 |
334 | |
335 | Unregisters the timer with the given \a timerId. |
336 | Returns \c true if successful; otherwise returns \c false. |
337 | |
338 | \sa registerTimer(), unregisterTimers() |
339 | */ |
340 | |
341 | /*! |
342 | \fn QList<TimerInfoV2> QAbstractEventDispatcher::timersForObject(QObject *object) const |
343 | \since 6.8 |
344 | |
345 | Returns a list of registered timers for \a object. The TimerInfoV2 struct has |
346 | \c timerId, \c interval, and \c timerType members. |
347 | |
348 | \sa Qt::TimerType, registerTimer(), unregisterTimer() |
349 | */ |
350 | |
351 | /*! |
352 | \fn QAbstractEventDispatcher::remainingTime(Qt::TimerId timerId) const |
353 | |
354 | Returns the remaining time of the timer with the given \a timerId. |
355 | If the timer is inactive, the returned value will be negative. If the timer |
356 | is overdue, the returned value will be 0. |
357 | |
358 | \sa Qt::TimerType, registerTimer(), unregisterTimer() |
359 | */ |
360 | #endif |
361 | |
362 | /*! |
363 | \fn bool QAbstractEventDispatcher::unregisterTimers(QObject *object) |
364 | |
365 | Unregisters all the timers associated with the given \a object. Returns \c |
366 | true if all timers were successfully removed; otherwise returns \c false. |
367 | |
368 | \sa unregisterTimer(), registeredTimers() |
369 | */ |
370 | |
371 | |
372 | /*! \fn void QAbstractEventDispatcher::wakeUp() |
373 | \threadsafe |
374 | |
375 | Wakes up the event loop. |
376 | |
377 | \omit |
378 | ### FIXME - QTBUG-70229 |
379 | On Unix and Glib event dispatchers, if the dispatcher is already awake when |
380 | this function is called, it is ensured that the current iteration won't block |
381 | waiting for more events, but will instead do another event loop iteration. |
382 | |
383 | ### TODO - does other event dispatchers behave the same? |
384 | \endomit |
385 | |
386 | \sa awake() |
387 | */ |
388 | |
389 | /*! |
390 | \fn void QAbstractEventDispatcher::interrupt() |
391 | |
392 | Interrupts event dispatching. The event dispatcher will |
393 | return from processEvents() as soon as possible. |
394 | */ |
395 | |
396 | // ### DOC: Are these called when the _application_ starts/stops or just |
397 | // when the current _event loop_ starts/stops? |
398 | /*! |
399 | \internal |
400 | */ |
401 | void QAbstractEventDispatcher::startingUp() |
402 | { } |
403 | |
404 | /*! |
405 | \internal |
406 | */ |
407 | void QAbstractEventDispatcher::closingDown() |
408 | { } |
409 | |
410 | /*! |
411 | \class QAbstractEventDispatcher::TimerInfo |
412 | \deprecated [6.8] Use TimerInfoV2 |
413 | \inmodule QtCore |
414 | |
415 | This struct represents information about a timer: |
416 | \l{QAbstractEventDispatcher::TimerInfo::timerId}{timerId}, |
417 | \l{QAbstractEventDispatcher::TimerInfo::interval}{interval}, and |
418 | \l{QAbstractEventDispatcher::TimerInfo::timerType}{timerType}. |
419 | |
420 | \sa registeredTimers(), QAbstractEventDispatcher::TimerInfoV2, timersForObject() |
421 | */ |
422 | /*! \fn QAbstractEventDispatcher::TimerInfo::TimerInfo(int timerId, int interval, Qt::TimerType timerType) |
423 | |
424 | Constructs a TimerInfo struct with the given \a timerId, \a interval, and |
425 | \a timerType. |
426 | */ |
427 | /*! |
428 | \variable QAbstractEventDispatcher::TimerInfo::timerId |
429 | |
430 | The timer's unique id. |
431 | */ |
432 | /*! |
433 | \variable QAbstractEventDispatcher::TimerInfo::interval |
434 | |
435 | The timer's interval. |
436 | */ |
437 | /*! |
438 | \variable QAbstractEventDispatcher::TimerInfo::timerType |
439 | |
440 | The timer's type |
441 | |
442 | \sa Qt::TimerType |
443 | */ |
444 | |
445 | /*! |
446 | \class QAbstractEventDispatcher::TimerInfoV2 |
447 | \inmodule QtCore |
448 | |
449 | This struct represents information about a timer: |
450 | \l{QAbstractEventDispatcher::TimerInfoV2::timerId}{timerId}, |
451 | \l{QAbstractEventDispatcher::TimerInfoV2::interval}{interval}, and |
452 | \l{QAbstractEventDispatcher::TimerInfoV2::timerType}{timerType}. |
453 | |
454 | \sa timersForObject() |
455 | */ |
456 | /*! |
457 | \variable QAbstractEventDispatcher::TimerInfoV2::timerId |
458 | |
459 | The timer's unique id. This is created by registerTimer() upon creation and |
460 | uniquely identifies a timer while it is active. It is also used by |
461 | QTimer::id() and returned by QObject::startTimer(). |
462 | */ |
463 | /*! |
464 | \variable QAbstractEventDispatcher::TimerInfoV2::interval |
465 | |
466 | The timer's interval. |
467 | */ |
468 | /*! |
469 | \variable QAbstractEventDispatcher::TimerInfoV2::timerType |
470 | |
471 | The timer's type |
472 | |
473 | \sa Qt::TimerType |
474 | */ |
475 | |
476 | /*! |
477 | Installs an event filter \a filterObj for all native events received by the application. |
478 | |
479 | The event filter \a filterObj receives events via its \l {QAbstractNativeEventFilter::}{nativeEventFilter()} |
480 | function, which is called for all events received by all threads. |
481 | |
482 | The \l {QAbstractNativeEventFilter::}{nativeEventFilter()} function should return true |
483 | if the event should be filtered, (in this case, stopped). It should return false to allow |
484 | normal Qt processing to continue: the native event can then be translated |
485 | into a QEvent and handled by the standard Qt \l{QEvent} {event} filtering, |
486 | e.g. QObject::installEventFilter(). |
487 | |
488 | If multiple event filters are installed, the filter that was installed last |
489 | is activated first. |
490 | |
491 | \note The filter function set here receives native messages, |
492 | that is, MSG or XEvent structs. |
493 | |
494 | For maximum portability, you should always try to use QEvent objects |
495 | and QObject::installEventFilter() whenever possible. |
496 | |
497 | \sa QObject::installEventFilter() |
498 | |
499 | \since 5.0 |
500 | */ |
501 | void QAbstractEventDispatcher::installNativeEventFilter(QAbstractNativeEventFilter *filterObj) |
502 | { |
503 | Q_D(QAbstractEventDispatcher); |
504 | |
505 | // clean up unused items in the list |
506 | d->eventFilters.removeAll(t: nullptr); |
507 | d->eventFilters.removeAll(t: filterObj); |
508 | d->eventFilters.prepend(t: filterObj); |
509 | } |
510 | |
511 | /*! |
512 | Removes the event filter \a filter from this object. The |
513 | request is ignored if such an event filter has not been installed. |
514 | |
515 | All event filters for this object are automatically removed when |
516 | this object is destroyed. |
517 | |
518 | It is always safe to remove an event filter, even during event filter |
519 | filter activation (that is, even from within the \l {QAbstractNativeEventFilter::}{nativeEventFilter()} function). |
520 | |
521 | \sa installNativeEventFilter(), QAbstractNativeEventFilter |
522 | \since 5.0 |
523 | */ |
524 | void QAbstractEventDispatcher::removeNativeEventFilter(QAbstractNativeEventFilter *filter) |
525 | { |
526 | Q_D(QAbstractEventDispatcher); |
527 | for (int i = 0; i < d->eventFilters.size(); ++i) { |
528 | if (d->eventFilters.at(i) == filter) { |
529 | d->eventFilters[i] = nullptr; |
530 | break; |
531 | } |
532 | } |
533 | } |
534 | |
535 | /*! |
536 | Sends \a message through the event filters that were set by |
537 | installNativeEventFilter(). This function returns \c true as soon as an |
538 | event filter returns \c true, and false otherwise to indicate that |
539 | the processing of the event should continue. |
540 | |
541 | Subclasses of QAbstractEventDispatcher \e must call this function |
542 | for \e all messages received from the system to ensure |
543 | compatibility with any extensions that may be used in the |
544 | application. The type of event \a eventType is specific to the platform |
545 | plugin chosen at run-time, and can be used to cast message to the right type. |
546 | The \a result pointer is only used on Windows, and corresponds to the LRESULT pointer. |
547 | |
548 | Note that the type of \a message is platform dependent. See |
549 | QAbstractNativeEventFilter for details. |
550 | |
551 | \sa installNativeEventFilter(), QAbstractNativeEventFilter::nativeEventFilter() |
552 | \since 5.0 |
553 | */ |
554 | bool QAbstractEventDispatcher::filterNativeEvent(const QByteArray &eventType, void *message, qintptr *result) |
555 | { |
556 | Q_D(QAbstractEventDispatcher); |
557 | if (!d->eventFilters.isEmpty()) { |
558 | // Raise the loopLevel so that deleteLater() calls in or triggered |
559 | // by event_filter() will be processed from the main event loop. |
560 | QScopedScopeLevelCounter scopeLevelCounter(d->threadData.loadAcquire()); |
561 | for (int i = 0; i < d->eventFilters.size(); ++i) { |
562 | QAbstractNativeEventFilter *filter = d->eventFilters.at(i); |
563 | if (!filter) |
564 | continue; |
565 | if (filter->nativeEventFilter(eventType, message, result)) |
566 | return true; |
567 | } |
568 | } |
569 | return false; |
570 | } |
571 | |
572 | /*! \fn void QAbstractEventDispatcher::awake() |
573 | |
574 | This signal is emitted after the event loop returns from a |
575 | function that could block. |
576 | |
577 | \sa wakeUp(), aboutToBlock() |
578 | */ |
579 | |
580 | /*! \fn void QAbstractEventDispatcher::aboutToBlock() |
581 | |
582 | This signal is emitted before the event loop calls a function that |
583 | could block. |
584 | |
585 | \sa awake() |
586 | */ |
587 | |
588 | #if QT_VERSION < QT_VERSION_CHECK(7, 0, 0) |
589 | void QAbstractEventDispatcher::registerTimer(Qt::TimerId timerId, Duration interval, |
590 | Qt::TimerType timerType, QObject *object) |
591 | { |
592 | if (QAbstractEventDispatcherV2 *self = v2(self: this)) |
593 | self->registerTimer(timerId, interval, timerType, object); |
594 | else |
595 | registerTimer(timerId: int(timerId), interval: fromDuration<qint64>(interval), timerType, object); |
596 | } |
597 | |
598 | bool QAbstractEventDispatcher::unregisterTimer(Qt::TimerId timerId) |
599 | { |
600 | if (QAbstractEventDispatcherV2 *self = v2(self: this)) |
601 | return self->unregisterTimer(timerId); |
602 | return unregisterTimer(timerId: int(timerId)); |
603 | } |
604 | |
605 | QList<QAbstractEventDispatcher::TimerInfoV2> |
606 | QAbstractEventDispatcher::timersForObject(QObject *object) const |
607 | { |
608 | if (const QAbstractEventDispatcherV2 *self = v2(self: this)) |
609 | return self->timersForObject(object); |
610 | QList<TimerInfo> timers = registeredTimers(object); |
611 | QList<TimerInfoV2> result; |
612 | result.reserve(asize: timers.size()); |
613 | for (const TimerInfo &t : timers) |
614 | result.emplaceBack(args: TimerInfoV2{ .interval: t.interval * 1ms, .timerId: Qt::TimerId(t.timerId), .timerType: t.timerType }); |
615 | return result; |
616 | } |
617 | |
618 | QAbstractEventDispatcher::Duration |
619 | QAbstractEventDispatcher::remainingTime(Qt::TimerId timerId) const |
620 | { |
621 | if (const QAbstractEventDispatcherV2 *self = v2(self: this)) |
622 | return self->remainingTime(timerId); |
623 | return const_cast<QAbstractEventDispatcher *>(this)->remainingTime(timerId: int(timerId)) * 1ms; |
624 | } |
625 | |
626 | /*! |
627 | \class QAbstractEventDispatcherV2 |
628 | \inmodule QtCore |
629 | |
630 | This class is a temporary hack to enable transition to an API based on |
631 | \c{std::chrono} for the Qt event dispatcher. In Qt 7, it will be merged |
632 | with QAbstractEventDispatcher, replacing the pure virtuals there with the |
633 | ones defined here. |
634 | |
635 | It is recommended applications and libraries port to the new API before |
636 | that future release to simplify work when the time comes. |
637 | */ |
638 | |
639 | /*! |
640 | Constructs a new event dispatcher with the given \a parent. |
641 | */ |
642 | QAbstractEventDispatcherV2::QAbstractEventDispatcherV2(QObject *parent) |
643 | : QAbstractEventDispatcherV2(*new QAbstractEventDispatcherPrivate, parent) |
644 | { |
645 | } |
646 | |
647 | /*! |
648 | \internal |
649 | */ |
650 | QAbstractEventDispatcherV2::QAbstractEventDispatcherV2(QAbstractEventDispatcherPrivate &dd, |
651 | QObject *parent) |
652 | : QAbstractEventDispatcher((dd.isV2 = true, dd), parent) |
653 | { |
654 | } |
655 | |
656 | /*! |
657 | Destroys the event dispatcher. |
658 | */ |
659 | QAbstractEventDispatcherV2::~QAbstractEventDispatcherV2() = default; |
660 | |
661 | /*! |
662 | \internal |
663 | Temporary compatibility override. |
664 | */ |
665 | void QAbstractEventDispatcherV2::registerTimer(int timerId, qint64 interval, |
666 | Qt::TimerType timerType, QObject *object) |
667 | { |
668 | auto self = static_cast<QAbstractEventDispatcherV2 *>(this); |
669 | self->registerTimer(timerId: Qt::TimerId(timerId), interval: interval * 1ms, timerType, object); |
670 | } |
671 | |
672 | /*! |
673 | \internal |
674 | Temporary compatibility override. |
675 | */ |
676 | bool QAbstractEventDispatcherV2::unregisterTimer(int timerId) |
677 | { |
678 | auto self = static_cast<QAbstractEventDispatcherV2 *>(this); |
679 | return self->unregisterTimer(timerId: Qt::TimerId(timerId)); |
680 | } |
681 | |
682 | /*! |
683 | \internal |
684 | Temporary compatibility override. |
685 | */ |
686 | auto QAbstractEventDispatcherV2::registeredTimers(QObject *object) const -> QList<TimerInfo> |
687 | { |
688 | auto self = static_cast<const QAbstractEventDispatcherV2 *>(this); |
689 | QList<TimerInfoV2> timers = self->timersForObject(object); |
690 | QList<TimerInfo> result; |
691 | result.reserve(asize: timers.size()); |
692 | for (const TimerInfoV2 &t : timers) |
693 | result.emplaceBack(args: qToUnderlying(e: t.timerId), args: fromDuration<int>(interval: t.interval), args: t.timerType); |
694 | return result; |
695 | } |
696 | |
697 | /*! |
698 | \internal |
699 | Temporary compatibility override. |
700 | */ |
701 | int QAbstractEventDispatcherV2::remainingTime(int timerId) |
702 | { |
703 | auto self = static_cast<QAbstractEventDispatcherV2 *>(this); |
704 | return fromDuration<int>(interval: self->remainingTime(timerId: Qt::TimerId(timerId))); |
705 | } |
706 | |
707 | /*! |
708 | \internal |
709 | Temporary compatibility override. |
710 | */ |
711 | bool QAbstractEventDispatcherV2::processEventsWithDeadline(QEventLoop::ProcessEventsFlags flags, QDeadlineTimer deadline) |
712 | { |
713 | Q_UNUSED(deadline); |
714 | return processEvents(flags); |
715 | } |
716 | #endif // ! Qt 7 |
717 | |
718 | QT_END_NAMESPACE |
719 | |
720 | #include "moc_qabstracteventdispatcher.cpp" |
721 |
Definitions
- QtTimerIdFreeListConstants
- Sizes
- timerIdFreeList
- fromDuration
- v2
- v2
- QAbstractEventDispatcherPrivate
- ~QAbstractEventDispatcherPrivate
- allocateTimerId
- releaseTimerId
- QAbstractEventDispatcher
- QAbstractEventDispatcher
- ~QAbstractEventDispatcher
- instance
- registerTimer
- registerTimer
- startingUp
- closingDown
- installNativeEventFilter
- removeNativeEventFilter
- filterNativeEvent
- registerTimer
- unregisterTimer
- timersForObject
- remainingTime
- QAbstractEventDispatcherV2
- QAbstractEventDispatcherV2
- ~QAbstractEventDispatcherV2
- registerTimer
- unregisterTimer
- registeredTimers
- remainingTime
Learn to use CMake with our Intro Training
Find out more