SensESP 3.0.1
Universal Signal K sensor toolkit ESP32
Loading...
Searching...
No Matches
zip.h
Go to the documentation of this file.
1#ifndef SENSESP_SRC_SENSESP_TRANSFORMS_ZIP_H_
2#define SENSESP_SRC_SENSESP_TRANSFORMS_ZIP_H_
3
4#include <elapsedMillis.h>
5#include <tuple>
6
9#include "transform.h"
10
11namespace sensesp {
12
14// Base class for Zip. This is needed until Arduino ESP32 Core supports C++14
15// and template pack indices: https://stackoverflow.com/a/55807564/2999754
16
17template <int N>
18class ZipBase {
19 public:
20 ZipBase(long max_age = 0) : max_age_{max_age} {
21 for (int i = 0; i < N; i++) {
22 age_[i] = max_age;
23 fresh_[i] = false;
24 }
25 }
26
27 protected:
28 elapsedMillis age_[N];
29 bool fresh_[N];
31
32 virtual void emit_tuple() = 0;
33
34 virtual void check_emit() {
35 for (int i = 0; i < N; i++) {
36 if ((max_age_ != 0 && age_[i] > max_age_) || !fresh_[i]) {
37 return;
38 }
39 }
40 emit_tuple();
41
42 for (int i = 0; i < N; i++) {
43 fresh_[i] = false;
44 }
45 }
46};
47
56template <typename T1, typename T2>
57class Zip : public ZipBase<2>, public ValueProducer<std::tuple<T1, T2>> {
58 public:
59 Zip(long max_age = 0) : ZipBase<2>(max_age) {}
60
61 std::tuple<LambdaConsumer<T1>, LambdaConsumer<T2>> consumers = {
62 LambdaConsumer<T1>([this](T1 value) {
63 std::get<0>(values) = value;
64 age_[0] = 0;
65 fresh_[0] = true;
66 check_emit();
67 }),
68 LambdaConsumer<T2>([this](T2 value) {
69 std::get<1>(values) = value;
70 age_[1] = 0;
71 fresh_[1] = true;
72 check_emit();
73 })};
74
75 protected:
76 std::tuple<T1, T2> values;
77
78 void emit_tuple() override { this->emit(values); }
79};
80
88template <typename T1, typename T2, typename T3>
89class Zip3 : public ZipBase<3>, public ValueProducer<std::tuple<T1, T2, T3>> {
90 public:
91 Zip3(long max_age = 0) : ZipBase<3>(max_age) {}
92
93 std::tuple<LambdaConsumer<T1>, LambdaConsumer<T2>, LambdaConsumer<T3>>
94 consumers = {LambdaConsumer<T1>([this](T1 value) {
95 std::get<0>(values) = value;
96 age_[0] = 0;
97 fresh_[0] = true;
98 check_emit();
99 }),
100 LambdaConsumer<T2>([this](T2 value) {
101 std::get<1>(values) = value;
102 age_[1] = 0;
103 fresh_[1] = true;
104 check_emit();
105 }),
106 LambdaConsumer<T3>([this](T3 value) {
107 std::get<2>(values) = value;
108 age_[2] = 0;
109 fresh_[2] = true;
110 check_emit();
111 })};
112
113 protected:
114 std::tuple<T1, T2, T3> values;
115
116 void emit_tuple() override { this->emit(values); }
117};
118
126template <typename T1, typename T2, typename T3, typename T4>
127class Zip4 : public ZipBase<4>,
128 public ValueProducer<std::tuple<T1, T2, T3, T4>> {
129 public:
130 Zip4(long max_age = 0) : ZipBase<4>(max_age) {}
131
132 std::tuple<LambdaConsumer<T1>, LambdaConsumer<T2>, LambdaConsumer<T3>,
134 consumers = {LambdaConsumer<T1>([this](T1 value) {
135 std::get<0>(values) = value;
136 age_[0] = 0;
137 fresh_[0] = true;
138 check_emit();
139 }),
140 LambdaConsumer<T2>([this](T2 value) {
141 std::get<1>(values) = value;
142 age_[1] = 0;
143 fresh_[1] = true;
144 check_emit();
145 }),
146 LambdaConsumer<T3>([this](T3 value) {
147 std::get<2>(values) = value;
148 age_[2] = 0;
149 fresh_[2] = true;
150 check_emit();
151 }),
152 LambdaConsumer<T4>([this](T4 value) {
153 std::get<3>(values) = value;
154 age_[3] = 0;
155 fresh_[3] = true;
156 check_emit();
157 })};
158
159 protected:
160 std::tuple<T1, T2, T3, T4> values;
161
162 void emit_tuple() override { this->emit(values); }
163};
164
172template <typename T1, typename T2, typename T3, typename T4, typename T5>
173class Zip5 : public ZipBase<5>,
174 public ValueProducer<std::tuple<T1, T2, T3, T4, T5>> {
175 public:
176 Zip5(long max_age = 0) : ZipBase<5>(max_age) {}
177
178 // The consumers member is a tuple of LambdaConsumers. Each LambdaConsumer
179 // has a different type, hence necessitating the use of a tuple.
180 std::tuple<LambdaConsumer<T1>, LambdaConsumer<T2>, LambdaConsumer<T3>,
182 consumers = {LambdaConsumer<T1>([this](T1 value) {
183 std::get<0>(values) = value;
184 age_[0] = 0;
185 fresh_[0] = true;
186 check_emit();
187 }),
188 LambdaConsumer<T2>([this](T2 value) {
189 std::get<1>(values) = value;
190 age_[1] = 0;
191 fresh_[1] = true;
192 check_emit();
193 }),
194 LambdaConsumer<T3>([this](T3 value) {
195 std::get<2>(values) = value;
196 age_[2] = 0;
197 fresh_[2] = true;
198 check_emit();
199 }),
200 LambdaConsumer<T4>([this](T4 value) {
201 std::get<3>(values) = value;
202 age_[3] = 0;
203 fresh_[3] = true;
204 check_emit();
205 }),
206 LambdaConsumer<T5>([this](T5 value) {
207 std::get<4>(values) = value;
208 age_[4] = 0;
209 fresh_[4] = true;
210 check_emit();
211 })};
212
213 protected:
214 std::tuple<T1, T2, T3, T4, T5> values;
215
216 void emit_tuple() override { this->emit(values); }
217};
218
219} // namespace sensesp
220
221#endif
Provides an easy way of calling a function based on the output of any ValueProducer.
A base class for any sensor or piece of code that outputs a value for consumption elsewhere.
void emit(const std::tuple< T1, T2 > &new_value)
Zip three producer values into a tuple.
Definition zip.h:89
std::tuple< LambdaConsumer< T1 >, LambdaConsumer< T2 >, LambdaConsumer< T3 > > consumers
Definition zip.h:94
std::tuple< T1, T2, T3 > values
Definition zip.h:114
void emit_tuple() override
Definition zip.h:116
Zip3(long max_age=0)
Definition zip.h:91
Zip four producer values into a tuple.
Definition zip.h:128
std::tuple< LambdaConsumer< T1 >, LambdaConsumer< T2 >, LambdaConsumer< T3 >, LambdaConsumer< T4 > > consumers
Definition zip.h:134
void emit_tuple() override
Definition zip.h:162
std::tuple< T1, T2, T3, T4 > values
Definition zip.h:160
Zip4(long max_age=0)
Definition zip.h:130
Zip five producer values into a tuple.
Definition zip.h:174
Zip5(long max_age=0)
Definition zip.h:176
std::tuple< LambdaConsumer< T1 >, LambdaConsumer< T2 >, LambdaConsumer< T3 >, LambdaConsumer< T4 >, LambdaConsumer< T5 > > consumers
Definition zip.h:182
void emit_tuple() override
Definition zip.h:216
std::tuple< T1, T2, T3, T4, T5 > values
Definition zip.h:214
virtual void check_emit()
Definition zip.h:34
ZipBase(long max_age=0)
Definition zip.h:20
long max_age_
Definition zip.h:30
bool fresh_[N]
Definition zip.h:29
elapsedMillis age_[N]
Definition zip.h:28
virtual void emit_tuple()=0
Zip two producer values into a tuple.
Definition zip.h:57
std::tuple< T1, T2 > values
Definition zip.h:76
Zip(long max_age=0)
Definition zip.h:59
void emit_tuple() override
Definition zip.h:78
std::tuple< LambdaConsumer< T1 >, LambdaConsumer< T2 > > consumers
Definition zip.h:61