aboutsummaryrefslogtreecommitdiff
path: root/src/models/timer.hpp
blob: fcaec1a2d99226ffd5d483b6d1818deb56ba9d5b (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
#pragma once

#include <stdint.h>
#include <string>

class FreqTimer {
	public:

	FreqTimer();

	/*
	 * Starts the timer if stopped
	 */
	void toggleStart();

	/*
	 * Timer is running
	 */
	[[nodiscard]] bool running() const { return _state == State::RUNNING; }

	/*
	 * Timer has been started
	 */
	[[nodiscard]] bool started() const {
		return _state == State::RUNNING or _state == State::STOPPED;
	}

	/*
	 * Current preset in ms
	 */
	[[nodiscard]] int64_t preset_ms() const noexcept { return _preset_ms; }

	/*
	 * Whether the preset time has been exceeded
	 */
	[[nodiscard]] bool overtime() const { return time_ms() < 0; }

	/*
	 * Reset the time
	 */
	void reset();

	/*
	 * Reset the time and preset
	 */
	void clear();

	[[nodiscard]] std::string counter_display_value() const;

	[[nodiscard]] std::string record_floor_display() const;

	/*
	 * Lowest frequency which can be measured
	 * in the interval (as measured in events/min
	 * or multiples of 60 Hz)
	 */
	[[nodiscard]] double record_floor() const;


	[[nodiscard]] double overtime_record_floor() const;

	/*
	 * Without a preset, the timer acts like a
	 * stopwatch and counts freely from zero.
	 * With a preset, the timer acts like a timer
	 * counting down to zero, then counts up to
	 * measure the number of seconds since the
	 * timing has ended.
	 */
	[[nodiscard]] bool has_preset() const;

	/*
	 * The current duration in milliseconds.
	 *
	 * If the timer has exceeded the preset,
	 * this time will be negative.
	 */
	[[nodiscard]] int64_t time_ms() const;

	[[nodiscard]] uint64_t total_duration_ms() const;


	/*
	 * Increment the timer's preset by the specified
	 * amount (in milisec.) Subsequent calls between
	 * timings increment the time. Incrementing a
	 * timing after a timing has been restarted will
	 * reset the timing and start from zero.
	 */
	void increment_preset_ms(uint64_t amount_ms);

	private:

	enum class State {
		// The timer initially starts in
		// "setting" mode and the preset
		// can be modified by incrementing
		// it by values (measured in seconds)
		//
		// Once it is started, this preset
		// is "sticky" and a reset returns
		// the timer to the preset value.
		// Incrementing the preset or clearing
		// the timer moves the timer back
		// into setting mode.
		SETTING,
		// Timer is active
		RUNNING,
		// Timer is temporarily stopped
		STOPPED,
		// Reset
		RESET,
	};

	State _state;

	uint64_t _time_offset_ms;
	uint64_t _time_start_ms;

	int64_t _preset_ms;

	[[nodiscard]] uint64_t _duration_since_last_stop_ms() const;


	void _stop();
	void _start();

};