8#include "private/qcore_unix_p.h"
9#include "private/qtimerinfo_unix_p.h"
10#include "private/qobject_p.h"
11#include "private/qabstracteventdispatcher_p.h"
15using namespace std::chrono;
17using namespace std::chrono_literals;
30steady_clock::time_point QTimerInfoList::updateCurrentTime()
67 return ceil<milliseconds>(
val);
91 auto secs = duration_cast<seconds>(msecs);
92 const milliseconds frac = msecs - secs;
118 const auto timeoutInSecs = time_point_cast<seconds>(
t->timeout);
120 auto recalculate = [&](
const milliseconds frac) {
121 t->timeout = timeoutInSecs + frac;
122 if (
t->timeout <
now)
123 t->timeout +=
t->interval;
127 const milliseconds absMaxRounding =
t->interval / 20;
129 auto fracMsec = duration_cast<milliseconds>(
t->timeout - timeoutInSecs);
131 if (
t->interval < 100ms &&
t->interval != 25ms &&
t->interval != 50ms &&
t->interval != 75ms) {
132 auto fracCount = fracMsec.count();
134 if (
t->interval < 50ms) {
137 bool roundUp = (fracCount % 50) >= 25;
139 fracCount |= roundUp;
144 bool roundUp = (fracCount % 100) >= 50;
146 fracCount |= roundUp;
149 fracMsec = milliseconds{fracCount};
150 recalculate(fracMsec);
154 milliseconds min = std::max(0ms, fracMsec - absMaxRounding);
155 milliseconds max = std::min(1000ms, fracMsec + absMaxRounding);
162 recalculate(fracMsec);
164 }
else if (max == 1000ms) {
166 recalculate(fracMsec);
170 milliseconds wantedBoundaryMultiple{25};
176 if ((
t->interval % 500) == 0ms) {
177 if (
t->interval >= 5
s) {
178 fracMsec = fracMsec >= 500ms ? max : min;
179 recalculate(fracMsec);
182 wantedBoundaryMultiple = 500ms;
184 }
else if ((
t->interval % 50) == 0ms) {
186 milliseconds mult50 =
t->interval / 50;
187 if ((mult50 % 4) == 0ms) {
189 wantedBoundaryMultiple = 200ms;
190 }
else if ((mult50 % 2) == 0ms) {
192 wantedBoundaryMultiple = 100ms;
193 }
else if ((mult50 % 5) == 0ms) {
195 wantedBoundaryMultiple = 250ms;
198 wantedBoundaryMultiple = 50ms;
202 milliseconds
base = (fracMsec / wantedBoundaryMultiple) * wantedBoundaryMultiple;
203 milliseconds middlepoint =
base + wantedBoundaryMultiple / 2;
204 if (fracMsec < middlepoint)
207 fracMsec =
qMin(
base + wantedBoundaryMultiple, max);
209 recalculate(fracMsec);
214 switch (
t->timerType) {
217 t->timeout +=
t->interval;
218 if (
t->timeout <
now) {
220 t->timeout +=
t->interval;
228 t->timeout +=
t->interval;
229 if (
t->timeout <=
now)
230 t->timeout = time_point_cast<seconds>(
now +
t->interval);
237 steady_clock::time_point
now = updateCurrentTime();
239 auto isWaiting = [](
QTimerInfo *tinfo) {
return !tinfo->activateRef; };
246 nanoseconds timeToWait =
t->timeout -
now;
247 if (timeToWait > 0
ns)
267 const steady_clock::time_point
now = updateCurrentTime();
272 qWarning(
"QTimerInfoList::timerRemainingTime: timer id %i not found", timerId);
293 t->interval = interval;
294 t->timerType = timerType;
296 t->activateRef =
nullptr;
298 steady_clock::time_point
expected = updateCurrentTime() + interval;
312 if (interval >= 20
s) {
316 if (interval <= 20ms) {
319 }
else if (interval <= 20
s) {
327 const auto currentTimeInSecs = floor<seconds>(
currentTime);
328 t->timeout = currentTimeInSecs +
t->interval;
345 if (
t == firstTimerInfo)
346 firstTimerInfo =
nullptr;
348 *(
t->activateRef) =
nullptr;
358 for (
int i = 0;
i <
size(); ++
i) {
360 if (
t->obj ==
object) {
363 if (
t == firstTimerInfo)
364 firstTimerInfo =
nullptr;
366 *(
t->activateRef) =
nullptr;
378 for (
const QTimerInfo *
const t : std::as_const(*
this)) {
379 if (
t->obj ==
object)
393 firstTimerInfo =
nullptr;
395 const steady_clock::time_point
now = updateCurrentTime();
410 if (now < currentTimerInfo->
timeout)
413 if (!firstTimerInfo) {
414 firstTimerInfo = currentTimerInfo;
415 }
else if (firstTimerInfo == currentTimerInfo) {
420 firstTimerInfo = currentTimerInfo;
431 if (currentTimerInfo->
interval > 0ms)
444 if (currentTimerInfo)
449 firstTimerInfo =
nullptr;
static bool sendEvent(QObject *receiver, QEvent *event)
Sends event event directly to receiver receiver, using the notify() function.
qsizetype size() const noexcept
void removeFirst() noexcept
bool isEmpty() const noexcept
void removeAt(qsizetype i)
iterator erase(const_iterator begin, const_iterator end)
iterator insert(qsizetype i, parameter_type t)
reference emplaceBack(Args &&... args)
const QTimerInfo * & constFirst() const noexcept
const_iterator cend() const noexcept
const_iterator cbegin() const noexcept
std::chrono::milliseconds remainingDuration(int timerId)
std::chrono::steady_clock::time_point currentTime
bool timerWait(timespec &)
void timerInsert(QTimerInfo *)
qint64 timerRemainingTime(int timerId)
bool unregisterTimers(QObject *object)
void registerTimer(int timerId, qint64 interval, Qt::TimerType timerType, QObject *object)
QList::const_iterator findTimerById(int timerId) const
QList< QAbstractEventDispatcher::TimerInfo > registeredTimers(QObject *object) const
bool unregisterTimer(int timerId)
QSet< QString >::iterator it
Combined button and popup list for selecting options.
timespec durationToTimespec(std::chrono::nanoseconds timeout) noexcept
static ULONG calculateNextTimeout(WinTimerInfo *t, quint64 currentTime)
constexpr const T & qMin(const T &a, const T &b)
constexpr const T & qMax(const T &a, const T &b)
GLbitfield GLuint64 timeout
[4]
static constexpr seconds roundToSecs(milliseconds msecs)
QT_BEGIN_NAMESPACE Q_CORE_EXPORT bool qt_disable_lowpriority_timers
static constexpr milliseconds roundToMillisecond(nanoseconds val)
static void calculateNextTimeout(QTimerInfo *t, steady_clock::time_point now)
static void calculateCoarseTimerTimeout(QTimerInfo *t, steady_clock::time_point now)
std::chrono::steady_clock::time_point timeout
QTimerInfo ** activateRef
std::chrono::milliseconds interval