forked from ctlbox/controlbox-cpp
-
Notifications
You must be signed in to change notification settings - Fork 4
/
ValueTicks.h
134 lines (111 loc) · 3.66 KB
/
ValueTicks.h
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
129
130
131
132
133
134
/*
* Copyright 2014-2015 Matthew McGowan.
*
* This file is part of Nice Firmware.
*
* BrewPi is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with BrewPi. If not, see <http://www.gnu.org/licenses/>.
*/
#pragma once
#include "Ticks.h"
#include "StreamUtil.h"
/*
* Allows time to run normally, or allows external code to manipulate time for testing and simulation.
* The original ticks instance has been renamed baseticks, and this provides the current (real) time
* for the platform, which is used by this class to compute the scaled time.
*
* The current time and scale are not persisted to eeprom.
*/
class ScaledTicksValue : public WritableValue
{
ticks_millis_t logicalStart;
ticks_millis_t timerStart;
uint16_t scale;
public:
ScaledTicksValue() : logicalStart(0), timerStart(0), scale(1) {}
ticks_millis_t millis() {
uint32_t now_offset = baseticks.millis()-timerStart;
return logicalStart + (now_offset*scale);
}
ticks_millis_t millis(ticks_millis_t& currentTime) {
uint32_t now_offset = currentTime-timerStart;
return logicalStart + (now_offset*scale);
}
ticks_seconds_t seconds() { return millis()/1000; }
void readTo(DataOut& out) {
ticks_millis_t time = baseticks.millis();
time = millis(time);
writePlatformEndianBytes(&time, sizeof(time), out);
writePlatformEndianBytes(&scale, sizeof(scale), out);
}
void writeMaskedFrom(DataIn& in, DataIn& mask) {
// write the start and scale
ticks_millis_t time = baseticks.millis();
logicalStart = millis(time);
timerStart = time;
readPlatformEndianMaskedBytes(&logicalStart, sizeof(logicalStart), in, mask);
readPlatformEndianMaskedBytes(&scale, sizeof(scale), in, mask);
}
/**
* Stream written/read is
* 4-bytes uint32 The number of milliseconds passed since poweron.
* 2-bytes uint16 The time scaling. a 16-bit integer.
*/
uint8_t streamSize() { return 6; }
// return time that has passed since timeStamp, take overflow into account
ticks_seconds_t timeSince(ticks_seconds_t previousTime) {
ticks_seconds_t currentTime = seconds();
return ::timeSince(currentTime, previousTime);
}
};
/**
* Time is critical to so many components that this is provided as a system-level service.
* The SystemProfile maintains this instance and persists changes to eeprom.
*/
extern ScaledTicksValue ticks;
/**
* Fetches the current millisecond count from the {@code Ticks} static instance.
* TODO: now that ScaledTicksValue is part of the system container, we don't really need this?
* It was mainly for testing, so can be replaced.
*/
class CurrentTicksValue : public Value
{
public:
void readTo(DataOut& out)
{
ticks_millis_t millis = ticks.millis();
writePlatformEndianBytes(&millis, 4, out);
}
uint8_t streamSize()
{
return sizeof(ticks_millis_t);
}
static Object* create(ObjectDefinition& def) {
// no parameters required
return new_object(CurrentTicksValue());
}
};
/**
* Remembers the time at the start of the current cycle.
*/
class CurrentCycleTicksValue : public CurrentTicksValue
{
ticks_millis_t cycle_ticks;
public:
void update() {
cycle_ticks = ticks.millis();
}
void readTo(DataOut& out) {
out.writeBuffer(&cycle_ticks, sizeof(cycle_ticks));
}
};