File indexing completed on 2024-05-05 05:54:31

0001 /*
0002     SPDX-FileCopyrightText: 2014 Elvis Angelaccio <elvis.angelaccio@kde.org>
0003 
0004     SPDX-License-Identifier: GPL-2.0-or-later
0005 */
0006 
0007 #include "stopwatch.h"
0008 
0009 #include <QCoreApplication>
0010 #include <QTimerEvent>
0011 
0012 Stopwatch::Stopwatch(QObject *parent) : QObject(parent) {}
0013 
0014 void Stopwatch::setGranularity(Granularity g)
0015 {
0016     m_granularity = g;
0017 
0018     // whenever granularity is changed, also apply that granularity to the timer event
0019     if (m_timerId != INACTIVE_TIMER_ID) {
0020         killTimer(m_timerId);
0021         m_timerId = startTimer(granularity());
0022     }
0023 }
0024 
0025 bool Stopwatch::isRunning() const
0026 {
0027     return m_state == State::Running;
0028 }
0029 
0030 bool Stopwatch::isPaused() const
0031 {
0032     return m_state == State::Paused;
0033 }
0034 
0035 bool Stopwatch::isInactive() const
0036 {
0037     return m_state == State::Inactive;
0038 }
0039 
0040 int Stopwatch::raw() const
0041 {
0042     return m_accumulator;
0043 }
0044 
0045 bool Stopwatch::initialize(int rawData)
0046 {
0047     if (!isInactive() || rawData <= 0) {
0048         return false;
0049     }
0050 
0051     m_accumulator = rawData;
0052     m_state = State::Paused;
0053     Q_EMIT time(m_accumulator);  // it signals that has been deserialized and can be resumed
0054 
0055     return true;
0056 }
0057 
0058 void Stopwatch::start()
0059 {
0060     if (isInactive()) {
0061         m_accumulator = 0;
0062         m_elapsedTimer.start();
0063 
0064         if (m_timerId == INACTIVE_TIMER_ID) {
0065             m_timerId = startTimer(granularity());
0066         }
0067     }
0068     else if (isPaused()) {
0069         m_elapsedTimer.restart();
0070         m_timerId = startTimer(granularity());
0071     }
0072 
0073     m_state = State::Running;
0074     Q_EMIT running();
0075 }
0076 
0077 void Stopwatch::pause()
0078 {
0079     if (m_elapsedTimer.isValid()) {
0080         m_accumulator += m_elapsedTimer.elapsed();
0081     }
0082 
0083     m_elapsedTimer.invalidate();
0084     m_state = State::Paused;
0085     Q_EMIT paused();
0086 }
0087 
0088 void Stopwatch::reset()
0089 {
0090     m_elapsedTimer.invalidate();          // if state is running, it will emit a zero time at next timerEvent() call
0091     QCoreApplication::processEvents();
0092     m_accumulator = 0;
0093     Q_EMIT time(0);
0094     m_state = State::Inactive;
0095     Q_EMIT inactive();
0096 }
0097 
0098 void Stopwatch::storeLap()
0099 {
0100     auto lapTime = m_accumulator;
0101 
0102     if (m_elapsedTimer.isValid()) {
0103         lapTime += m_elapsedTimer.elapsed();
0104     }
0105 
0106     const auto zero = QTime {0, 0};
0107     Q_EMIT lap(zero.addMSecs(lapTime));
0108 }
0109 
0110 void Stopwatch::timerEvent(QTimerEvent *event)
0111 {
0112     if (event->timerId() != m_timerId) {      // forward undesired events
0113         QObject::timerEvent(event);
0114         return;
0115     }
0116 
0117     if (m_elapsedTimer.isValid()) {
0118         Q_EMIT time(m_accumulator + m_elapsedTimer.elapsed());
0119     }
0120     else {
0121         killTimer(m_timerId);
0122         m_timerId = INACTIVE_TIMER_ID;
0123     }
0124 }
0125 
0126 int Stopwatch::granularity() const
0127 {
0128     return static_cast<int>(m_granularity);
0129 }
0130 
0131 #include "moc_stopwatch.cpp"