forked from profezzorn/ProffieOS
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathloop.h
105 lines (96 loc) · 2.42 KB
/
loop.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
#ifndef TRANSITIONS_LOOP_H
#define TRANSITIONS_LOOP_H
// Usage: TrLoop<TRANSITION>
// TRANSITION: TRANSITION
// Return Value: TRANSITION
// Runs the specified transition in a loop forever.
template<class TR>
class TrLoop : public TR {
public:
void run(BladeBase* blade) {
if (TR::done()) TR::begin();
TR::run(blade);
}
bool done() { return false; }
};
// Usage: TrLoopNX<N_FUNCTION, TRANSITION>
// or: TrLoopN<N, TRANSITION>
// N_FUNCTION: FUNCTION (number of Loops)
// N: a number (Loops)
// TRANSITION: TRANSITION
// Return Value: TRANSITION
// Runs the specified transition N times.
template<class N, class TRANSITION>
class TrLoopNX : public TRANSITION {
public:
void run(BladeBase* blade) {
n_.run(blade);
if (loops_ < 0) loops_ = n_.calculate(blade) + 1;
if (loops_ > 0 && TRANSITION::done()) {
if (loops_ > 1) TRANSITION::begin();
loops_--;
}
TRANSITION::run(blade);
}
void begin() {
TRANSITION::begin();
loops_ = -1;
}
bool done() { return loops_ == 0; }
private:
int loops_ = 0;
PONUA SVFWrapper<N> n_;
};
template<int N, class TRANSITION> using TrLoopN = TrLoopNX<Int<N>, TRANSITION>;
// Usage: TrLoopUntil<PULSE, TRANSITION, OUT>
// TRANSITION, OUT: TRANSITION
// PULSE: FUNCTION (pulse)
// Return Value: TRANSITION
// Runs the specified transition until the pulse occurs.
// When the pulse occurs, the loop continues, but OUT is used to
// transition away from it, and when OUT is done, the transition is done.
template<class PULSE, class TR, class OUT>
class TrLoopUntil {
public:
void begin() {
transition_.begin();
pulsed_ = false;
}
bool done() {
return pulsed_ && out_.done();
}
void run(BladeBase* blade) {
pulse_.run(blade);
if (transition_.done()) {
transition_.begin();
}
transition_.run(blade);
if (!pulsed_) {
if (pulse_.calculate(blade)) {
out_.begin();
pulsed_ = true;
}
}
if (pulsed_) {
out_.run(blade);
}
}
private:
bool pulsed_ = false;
PONUA SVFWrapper<PULSE> pulse_;
PONUA TR transition_;
PONUA TR out_;
public:
template<class X, class Y>
auto getColor(const X& a, const Y& b, int led) ->
decltype(MixColors(transition_.getColor(a, a, 1),
out_.getColor(transition_.getColor(a, a, 1), b, 1), 1,1))
{
if (pulsed_) {
return out_.getColor(transition_.getColor(a, a, led), b, led);
} else {
return transition_.getColor(a, a, led);
}
}
};
#endif