Skip to content

Commit

Permalink
core/clock: expose date as a QDateTime
Browse files Browse the repository at this point in the history
  • Loading branch information
outfoxxed committed Jan 25, 2025
1 parent 325be88 commit d9679f0
Show file tree
Hide file tree
Showing 2 changed files with 47 additions and 35 deletions.
33 changes: 13 additions & 20 deletions src/core/clock.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -48,19 +48,16 @@ void SystemClock::update() {
void SystemClock::setTime(const QDateTime& targetTime) {
auto currentTime = QDateTime::currentDateTime();
auto offset = currentTime.msecsTo(targetTime);
auto dtime = offset > -500 && offset < 500 ? targetTime : currentTime;
auto time = dtime.time();
this->currentTime = offset > -500 && offset < 500 ? targetTime : currentTime;

auto secondPrecision = this->mPrecision >= SystemClock::Seconds;
auto secondChanged = this->setSeconds(secondPrecision ? time.second() : 0);

auto minutePrecision = this->mPrecision >= SystemClock::Minutes;
auto minuteChanged = this->setMinutes(minutePrecision ? time.minute() : 0);
auto time = this->currentTime.time();
this->currentTime.setTime(QTime(
this->mPrecision >= SystemClock::Hours ? time.hour() : 0,
this->mPrecision >= SystemClock::Minutes ? time.minute() : 0,
this->mPrecision >= SystemClock::Seconds ? time.second() : 0
));

auto hourPrecision = this->mPrecision >= SystemClock::Hours;
auto hourChanged = this->setHours(hourPrecision ? time.hour() : 0);

DropEmitter::call(secondChanged, minuteChanged, hourChanged);
emit this->dateChanged();
}

void SystemClock::schedule(const QDateTime& targetTime) {
Expand All @@ -76,11 +73,11 @@ void SystemClock::schedule(const QDateTime& targetTime) {
auto nextTime = offset > 0 && offset < 500 ? targetTime : currentTime;

auto baseTimeT = nextTime.time();
nextTime.setTime(
{hourPrecision ? baseTimeT.hour() : 0,
minutePrecision ? baseTimeT.minute() : 0,
secondPrecision ? baseTimeT.second() : 0}
);
nextTime.setTime(QTime(
hourPrecision ? baseTimeT.hour() : 0,
minutePrecision ? baseTimeT.minute() : 0,
secondPrecision ? baseTimeT.second() : 0
));

if (secondPrecision) nextTime = nextTime.addSecs(1);
else if (minutePrecision) nextTime = nextTime.addSecs(60);
Expand All @@ -91,7 +88,3 @@ void SystemClock::schedule(const QDateTime& targetTime) {
this->timer.start(static_cast<qint32>(delay));
this->targetTime = nextTime;
}

DEFINE_MEMBER_GETSET(SystemClock, hours, setHours);
DEFINE_MEMBER_GETSET(SystemClock, minutes, setMinutes);
DEFINE_MEMBER_GETSET(SystemClock, seconds, setSeconds);
49 changes: 34 additions & 15 deletions src/core/clock.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -7,9 +7,26 @@
#include <qtmetamacros.h>
#include <qtypes.h>

#include "util.hpp"

///! System clock accessor.
/// SystemClock is a view into the system's clock.
/// It updates at hour, minute, or second intervals depending on @@precision.
///
/// # Examples
/// ```qml
/// SystemClock {
/// id: clock
/// precision: SystemClock.Seconds
/// }
///
/// @@QtQuick.Text {
/// text: Qt.formatDateTime(clock.date, "hh:mm:ss - yyyy-MM-dd")
/// }
/// ```
///
/// > [!WARNING] Clock updates will trigger within 50ms of the system clock changing,
/// > however this can be either before or after the clock changes (+-50ms). If you
/// > need a date object, use @@date instead of constructing a new one, or the time
/// > of the constructed object could be off by up to a second.
class SystemClock: public QObject {
Q_OBJECT;
/// If the clock should update. Defaults to true.
Expand All @@ -18,12 +35,17 @@ class SystemClock: public QObject {
Q_PROPERTY(bool enabled READ enabled WRITE setEnabled NOTIFY enabledChanged);
/// The precision the clock should measure at. Defaults to `SystemClock.Seconds`.
Q_PROPERTY(SystemClock::Enum precision READ precision WRITE setPrecision NOTIFY precisionChanged);
/// The current date and time.
///
/// > [!TIP] You can use @@QtQml.Qt.formatDateTime() to get the time as a string in
/// > your format of choice.
Q_PROPERTY(QDateTime date READ date NOTIFY dateChanged);
/// The current hour.
Q_PROPERTY(quint32 hours READ hours NOTIFY hoursChanged);
Q_PROPERTY(quint32 hours READ hours NOTIFY dateChanged);
/// The current minute, or 0 if @@precision is `SystemClock.Hours`.
Q_PROPERTY(quint32 minutes READ minutes NOTIFY minutesChanged);
Q_PROPERTY(quint32 minutes READ minutes NOTIFY dateChanged);
/// The current second, or 0 if @@precision is `SystemClock.Hours` or `SystemClock.Minutes`.
Q_PROPERTY(quint32 seconds READ seconds NOTIFY secondsChanged);
Q_PROPERTY(quint32 seconds READ seconds NOTIFY dateChanged);
QML_ELEMENT;

public:
Expand All @@ -43,30 +65,27 @@ class SystemClock: public QObject {
[[nodiscard]] SystemClock::Enum precision() const;
void setPrecision(SystemClock::Enum precision);

[[nodiscard]] QDateTime date() const { return this->currentTime; }
[[nodiscard]] quint32 hours() const { return this->currentTime.time().hour(); }
[[nodiscard]] quint32 minutes() const { return this->currentTime.time().minute(); }
[[nodiscard]] quint32 seconds() const { return this->currentTime.time().second(); }

signals:
void enabledChanged();
void precisionChanged();
void hoursChanged();
void minutesChanged();
void secondsChanged();
void dateChanged();

private slots:
void onTimeout();

private:
bool mEnabled = true;
SystemClock::Enum mPrecision = SystemClock::Seconds;
quint32 mHours = 0;
quint32 mMinutes = 0;
quint32 mSeconds = 0;
QTimer timer;
QDateTime currentTime;
QDateTime targetTime;

void update();
void setTime(const QDateTime& targetTime);
void schedule(const QDateTime& targetTime);

DECLARE_PRIVATE_MEMBER(SystemClock, hours, setHours, mHours, hoursChanged);
DECLARE_PRIVATE_MEMBER(SystemClock, minutes, setMinutes, mMinutes, minutesChanged);
DECLARE_PRIVATE_MEMBER(SystemClock, seconds, setSeconds, mSeconds, secondsChanged);
};

0 comments on commit d9679f0

Please sign in to comment.