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()
const
46 return updateCurrentTime() < timers.
at(0)->
timeout;
50{
return a->timeout <
b->timeout; };
65 return ceil<milliseconds>(
val);
89 auto secs = duration_cast<seconds>(interval);
90 const nanoseconds frac = interval - secs;
116 const auto timeoutInSecs = time_point_cast<seconds>(
t->timeout);
118 auto recalculate = [&](
const milliseconds frac) {
119 t->timeout = timeoutInSecs + frac;
120 if (
t->timeout <
now)
121 t->timeout +=
t->interval;
126 const milliseconds absMaxRounding = interval / 20;
128 auto fracMsec = duration_cast<milliseconds>(
t->timeout - timeoutInSecs);
130 if (interval < 100ms && interval != 25ms && interval != 50ms && interval != 75ms) {
131 auto fracCount = fracMsec.count();
133 if (interval < 50ms) {
136 bool roundUp = (fracCount % 50) >= 25;
138 fracCount |= roundUp;
143 bool roundUp = (fracCount % 100) >= 50;
145 fracCount |= roundUp;
148 fracMsec = milliseconds{fracCount};
149 recalculate(fracMsec);
153 milliseconds min = std::max(0ms, fracMsec - absMaxRounding);
154 milliseconds max = std::min(1000ms, fracMsec + absMaxRounding);
161 recalculate(fracMsec);
163 }
else if (max == 1000ms) {
165 recalculate(fracMsec);
169 milliseconds wantedBoundaryMultiple{25};
175 if ((interval % 500) == 0ms) {
176 if (interval >= 5
s) {
177 fracMsec = fracMsec >= 500ms ? max : min;
178 recalculate(fracMsec);
181 wantedBoundaryMultiple = 500ms;
183 }
else if ((interval % 50) == 0ms) {
185 milliseconds mult50 = interval / 50;
186 if ((mult50 % 4) == 0ms) {
188 wantedBoundaryMultiple = 200ms;
189 }
else if ((mult50 % 2) == 0ms) {
191 wantedBoundaryMultiple = 100ms;
192 }
else if ((mult50 % 5) == 0ms) {
194 wantedBoundaryMultiple = 250ms;
197 wantedBoundaryMultiple = 50ms;
201 milliseconds
base = (fracMsec / wantedBoundaryMultiple) * wantedBoundaryMultiple;
202 milliseconds middlepoint =
base + wantedBoundaryMultiple / 2;
203 if (fracMsec < middlepoint)
206 fracMsec =
qMin(
base + wantedBoundaryMultiple, max);
208 recalculate(fracMsec);
213 switch (
t->timerType) {
216 t->timeout +=
t->interval;
217 if (
t->timeout <
now) {
219 t->timeout +=
t->interval;
227 t->timeout +=
t->interval;
228 if (
t->timeout <=
now)
229 t->timeout = time_point_cast<seconds>(
now +
t->interval);
240 steady_clock::time_point
now = updateCurrentTime();
242 auto isWaiting = [](
QTimerInfo *tinfo) {
return !tinfo->activateRef; };
244 auto it = std::find_if(timers.
cbegin(), timers.
cend(), isWaiting);
249 if (timeToWait > 0
ns)
261 const steady_clock::time_point
now = updateCurrentTime();
264 if (
it == timers.
cend()) {
266 qWarning(
"QTimerInfoList::timerRemainingTime: timer id %i not found",
int(timerId));
268 return Duration::min();
273 return t->timeout -
now;
288 else if (interval <= 20ms)
310 const auto currentTimeInSecs = floor<seconds>(
currentTime);
311 t->timeout = currentTimeInSecs +
t->interval;
328 if (
t == firstTimerInfo)
329 firstTimerInfo =
nullptr;
331 *(
t->activateRef) =
nullptr;
342 auto associatedWith = [
this](
QObject *
o) {
343 return [
this,
o](
auto &
t) {
345 if (
t == firstTimerInfo)
346 firstTimerInfo =
nullptr;
348 *(
t->activateRef) =
nullptr;
362 QList<TimerInfo>
list;
363 for (
const auto &
t : timers) {
364 if (
t->obj ==
object)
378 firstTimerInfo =
nullptr;
380 const steady_clock::time_point
now = updateCurrentTime();
385 auto it = std::find_if(timers.
cbegin(), timers.
cend(), stillActive);
395 if (now < currentTimerInfo->
timeout)
398 if (!firstTimerInfo) {
399 firstTimerInfo = currentTimerInfo;
400 }
else if (firstTimerInfo == currentTimerInfo) {
403 }
else if (currentTimerInfo->interval < firstTimerInfo->
interval
404 || currentTimerInfo->interval == firstTimerInfo->
interval) {
405 firstTimerInfo = currentTimerInfo;
410 if (timers.
size() > 1) {
413 auto afterCurrentIt = timers.
begin() + 1;
414 auto iter = std::upper_bound(afterCurrentIt, timers.
end(), currentTimerInfo,
byTimeout);
415 currentTimerInfo = *std::rotate(timers.
begin(), afterCurrentIt,
iter);
418 if (currentTimerInfo->interval > 0ms)
422 if (!currentTimerInfo->activateRef) {
423 currentTimerInfo->activateRef = ¤tTimerInfo;
431 if (currentTimerInfo)
432 currentTimerInfo->activateRef =
nullptr;
436 firstTimerInfo =
nullptr;
static bool sendEvent(QObject *receiver, QEvent *event)
Sends event event directly to receiver receiver, using the notify() function.
qsizetype size() const noexcept
bool isEmpty() const noexcept
iterator erase(const_iterator begin, const_iterator end)
iterator insert(qsizetype i, parameter_type t)
const_reference at(qsizetype i) const noexcept
qsizetype removeIf(Predicate pred)
reference emplaceBack(Args &&... args)
const T & constFirst() const noexcept
const_iterator cend() const noexcept
const_iterator cbegin() const noexcept
bool unregisterTimer(Qt::TimerId timerId)
std::chrono::steady_clock::time_point currentTime
void timerInsert(QTimerInfo *)
Duration remainingDuration(Qt::TimerId timerId) const
bool unregisterTimers(QObject *object)
std::optional< Duration > timerWait()
QAbstractEventDispatcher::Duration Duration
auto findTimerById(Qt::TimerId timerId) const
void registerTimer(Qt::TimerId timerId, Duration interval, Qt::TimerType timerType, QObject *object)
QList< TimerInfo > registeredTimers(QObject *object) const
QSet< QString >::iterator it
Combined button and popup list for selecting options.
DBusConnection const char DBusError DBusBusType DBusError return DBusConnection DBusHandleMessageFunction void DBusFreeFunction return DBusConnection return DBusConnection return const char DBusError return DBusConnection DBusMessage dbus_uint32_t return DBusConnection dbus_bool_t DBusConnection DBusAddWatchFunction DBusRemoveWatchFunction DBusWatchToggledFunction void DBusFreeFunction return DBusConnection DBusDispatchStatusFunction void DBusFreeFunction DBusTimeout return DBusTimeout return DBusWatch return DBusWatch unsigned int return DBusError const DBusError return const DBusMessage return DBusMessage return DBusMessage return DBusMessage return DBusMessage return DBusMessage return DBusMessageIter * iter
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)
GLboolean GLboolean GLboolean b
GLboolean GLboolean GLboolean GLboolean a
[7]
GLenum GLenum GLsizei count
GLbitfield GLuint64 timeout
[4]
QT_BEGIN_NAMESPACE Q_CORE_EXPORT bool qt_disable_lowpriority_timers
static constexpr milliseconds roundToMillisecond(nanoseconds val)
static bool byTimeout(const QTimerInfo *a, const QTimerInfo *b)
static void calculateNextTimeout(QTimerInfo *t, steady_clock::time_point now)
static void calculateCoarseTimerTimeout(QTimerInfo *t, steady_clock::time_point now)
static constexpr seconds roundToSecs(nanoseconds interval)
QT_BEGIN_NAMESPACE constexpr std::underlying_type_t< Enum > qToUnderlying(Enum e) noexcept
\variable QAbstractEventDispatcher::TimerInfo::timerId
std::chrono::time_point< std::chrono::steady_clock, Duration > TimePoint