chronometer.cpp 3.34 KB
Newer Older
Loren Burkholder's avatar
Loren Burkholder committed
1
2
#include "chronometer.h"

3
#include <QString>
4
5
6
#include <QDebug>

Chronometer::Chronometer(QObject *parent)
Loren Burkholder's avatar
Loren Burkholder committed
7
8
    : QObject(parent), m_totalElapsed{ 0 },
      m_isRunning{ false }, m_timerInterval{ 1 }
9
{
10
11
    m_updateTimer.setSingleShot(false);
    connect(&m_updateTimer, SIGNAL(timeout()), this, SLOT(updateElapsed()));
12
13
}

14
Chronometer::Chronometer(bool startNow, int interval, QObject *parent)
15
    : QObject(parent), m_totalElapsed{ 0 }, m_isRunning{ startNow }, m_timerInterval{ interval }
Loren Burkholder's avatar
Loren Burkholder committed
16
{
17
}
Loren Burkholder's avatar
Loren Burkholder committed
18

19
20
21
22
void Chronometer::start()
{
    m_beginning = std::chrono::steady_clock::now();
    m_isRunning = true;
23
    m_updateTimer.start(m_timerInterval);
24
25
    emit disableStart(true);
    emit disableStopLap(false);
26
    emit disableReset(false);
27
    qDebug() << tr("Chronometer started");
28
}
Loren Burkholder's avatar
Loren Burkholder committed
29

30
31
void Chronometer::stop()
{
Loren Burkholder's avatar
Loren Burkholder committed
32
33
    if (!m_isRunning)
        return;
34
    m_end = std::chrono::steady_clock::now();
35
    m_updateTimer.stop();
36
37
    m_isRunning = false;
    m_totalElapsed += m_end - m_beginning;
38
39
    emit disableStart(false);
    emit disableStopLap(true);
40
    updateElapsed();
41
    qDebug() << tr("Chronometer stopped");
42
}
Loren Burkholder's avatar
Loren Burkholder committed
43

44
45
void Chronometer::reset()
{
46
    this->stop();
47
48
    m_totalElapsed -= m_totalElapsed; // KLUDGE: there's no simple way to set a std::chrono::duration to zero so I just did this instead
    m_beginning = std::chrono::steady_clock::now();
49
    for (int i = m_laps.size(); i > 0; --i) // KLUDGE: the size of m_laps decreases every pop_back(), so it's not reliable
50
        m_laps.pop_back();
51
    updateElapsed();
52
    emit disableReset(true);
53
    emit newLap(0, "", ""); // zero meaning we've reset
54
    qDebug() << tr("Chronometer reset");
55
}
Loren Burkholder's avatar
Loren Burkholder committed
56

57
58
void Chronometer::lap()
{
Loren Burkholder's avatar
Loren Burkholder committed
59
60
61
62
    // for simplicity, don't allow laps while stopped
    if (!m_isRunning)
        return;

63
64
65
66
67
68
69
    // so all calculations use the same value
    auto time = elapsed();

    std::chrono::duration<double> totalLapTime; // this calculates the total amount of time lapped
    for (auto &x: m_laps) // and removes it from the total elapsed to get what hasn't been lapped yet
        totalLapTime += x;

Loren Burkholder's avatar
Loren Burkholder committed
70
    // first lap, starts from beginning
71
    if (m_laps.size() == 0)
72
            m_laps.push_back(time);
Loren Burkholder's avatar
Loren Burkholder committed
73

74
    else // start from beginning of last lap
75
        m_laps.push_back(time - totalLapTime);
76

77
78
79
80
81
82
83
    QString lapNum, lapString, splitString; // lapString is the whole thing put together
    lapString.setNum(m_laps.back().count(), 'f');
    lapString.append(tr(" s")); // TRANSLATOR: This and the below " s" are simply marking seconds, change accordingly
    // add this lap to total time
    totalLapTime += m_laps.back();
    splitString.setNum(totalLapTime.count(), 'f');
    splitString.append(tr(" s"));
Loren Burkholder's avatar
Loren Burkholder committed
84

85
    // emit now so the string doesn't have the "Lap x: " prepended
86
    emit newLap(m_laps.size(), lapString, splitString);
87

88
89
90
    lapNum.setNum(m_laps.size());
    lapNum.prepend(tr("Lap "));
    lapNum.append(": "); // TRANSLATOR: punctuation, just copy-paste
Loren Burkholder's avatar
Loren Burkholder committed
91

92
    lapString.prepend(lapNum);
93
    qDebug() << tr("New lap: ") << lapString;
94
}
Loren Burkholder's avatar
Loren Burkholder committed
95
96

std::chrono::duration<double> Chronometer::elapsed()
97
98
{
    std::chrono::duration<double> elapsedTime;
99
    m_isRunning ? elapsedTime = (std::chrono::steady_clock::now() - m_beginning) + m_totalElapsed : elapsedTime = m_totalElapsed;
Loren Burkholder's avatar
Loren Burkholder committed
100
    return elapsedTime;
Loren Burkholder's avatar
Loren Burkholder committed
101
}
102
103
104

void Chronometer::updateElapsed()
{
105
    QString s;
Loren Burkholder's avatar
Loren Burkholder committed
106
    s.setNum(elapsed().count(), 'f');
107
    s.append(tr(" seconds"));
108
    emit newElapsedTime(s);
109
}