Skip to content

Commit 1d2bf5d

Browse files
committed
core/clock: fix behavior with odd time changes
1 parent 815867c commit 1d2bf5d

File tree

2 files changed

+29
-25
lines changed

2 files changed

+29
-25
lines changed

src/core/clock.cpp

Lines changed: 26 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -31,20 +31,25 @@ void SystemClock::setPrecision(SystemClock::Enum precision) {
3131
}
3232

3333
void SystemClock::onTimeout() {
34-
this->setTime(this->nextTime);
35-
this->schedule(this->nextTime);
34+
this->setTime(this->targetTime);
35+
this->schedule(this->targetTime);
3636
}
3737

3838
void SystemClock::update() {
3939
if (this->mEnabled) {
40-
this->setTime(QTime::currentTime());
41-
this->schedule(QTime::currentTime());
40+
this->setTime(QDateTime::fromMSecsSinceEpoch(0));
41+
this->schedule(QDateTime::fromMSecsSinceEpoch(0));
4242
} else {
4343
this->timer.stop();
4444
}
4545
}
4646

47-
void SystemClock::setTime(QTime time) {
47+
void SystemClock::setTime(const QDateTime& targetTime) {
48+
auto currentTime = QDateTime::currentDateTime();
49+
auto offset = currentTime.msecsTo(targetTime);
50+
auto dtime = offset > -500 && offset < 500 ? targetTime : currentTime;
51+
auto time = dtime.time();
52+
4853
auto secondPrecision = this->mPrecision >= SystemClock::Seconds;
4954
auto secondChanged = this->setSeconds(secondPrecision ? time.second() : 0);
5055

@@ -57,34 +62,33 @@ void SystemClock::setTime(QTime time) {
5762
DropEmitter::call(secondChanged, minuteChanged, hourChanged);
5863
}
5964

60-
void SystemClock::schedule(QTime floor) {
65+
void SystemClock::schedule(const QDateTime& targetTime) {
6166
auto secondPrecision = this->mPrecision >= SystemClock::Seconds;
6267
auto minutePrecision = this->mPrecision >= SystemClock::Minutes;
6368
auto hourPrecision = this->mPrecision >= SystemClock::Hours;
6469

65-
setnext:
66-
auto nextTime = QTime(
67-
hourPrecision ? floor.hour() : 0,
68-
minutePrecision ? floor.minute() : 0,
69-
secondPrecision ? floor.second() : 0
70+
auto currentTime = QDateTime::currentDateTime();
71+
72+
auto offset = currentTime.msecsTo(targetTime);
73+
74+
// timer skew
75+
auto nextTime = offset > 0 && offset < 500 ? targetTime : currentTime;
76+
77+
auto baseTimeT = nextTime.time();
78+
nextTime.setTime(
79+
{hourPrecision ? baseTimeT.hour() : 0,
80+
minutePrecision ? baseTimeT.minute() : 0,
81+
secondPrecision ? baseTimeT.second() : 0}
7082
);
7183

7284
if (secondPrecision) nextTime = nextTime.addSecs(1);
7385
else if (minutePrecision) nextTime = nextTime.addSecs(60);
7486
else if (hourPrecision) nextTime = nextTime.addSecs(3600);
7587

76-
auto delay = QTime::currentTime().msecsTo(nextTime);
77-
78-
// If off by more than 2 hours we likely wrapped around midnight.
79-
if (delay < -7200000) delay += 86400000;
80-
else if (delay < 0) {
81-
// Otherwise its just the timer being unstable.
82-
floor = QTime::currentTime();
83-
goto setnext;
84-
}
88+
auto delay = currentTime.msecsTo(nextTime);
8589

86-
this->timer.start(delay);
87-
this->nextTime = nextTime;
90+
this->timer.start(static_cast<qint32>(delay));
91+
this->targetTime = nextTime;
8892
}
8993

9094
DEFINE_MEMBER_GETSET(SystemClock, hours, setHours);

src/core/clock.hpp

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -59,11 +59,11 @@ private slots:
5959
quint32 mMinutes = 0;
6060
quint32 mSeconds = 0;
6161
QTimer timer;
62-
QTime nextTime;
62+
QDateTime targetTime;
6363

6464
void update();
65-
void setTime(QTime time);
66-
void schedule(QTime floor);
65+
void setTime(const QDateTime& targetTime);
66+
void schedule(const QDateTime& targetTime);
6767

6868
DECLARE_PRIVATE_MEMBER(SystemClock, hours, setHours, mHours, hoursChanged);
6969
DECLARE_PRIVATE_MEMBER(SystemClock, minutes, setMinutes, mMinutes, minutesChanged);

0 commit comments

Comments
 (0)