-
Notifications
You must be signed in to change notification settings - Fork 4
Expand file tree
/
Copy pathTimeline.cpp
More file actions
193 lines (158 loc) · 5.55 KB
/
Copy pathTimeline.cpp
File metadata and controls
193 lines (158 loc) · 5.55 KB
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
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
#include <Timeline.h>
#if defined(ARDUINO) && ARDUINO >= 100
#include "Arduino.h"
#else
#include "WProgram.h"
#endif
TweenDuino::Timeline::TimelineEntry::TimelineEntry(): tween(nullptr) {}
TweenDuino::Timeline::TimelineEntry::~TimelineEntry() {
// If the Timeline didn't make this tween, it's not the timeline's leak to worry about.
if (tlManagedTween && tween != nullptr) {
delete tween;
tween = nullptr;
}
}
TweenDuino::Timeline::Timeline():
totalDuration(0),
totalTime(0),
startTime(0),
completed(false),
initialized(false),
lastUpdateTime(0) {}
void TweenDuino::Timeline::wipe() {
totalDuration = 0;
totalTime = 0;
startTime = 0;
completed = false;
initialized = false;
lastUpdateTime = 0;
for (int i = 0; i < TWEEN_TIMELINE_SIZE; i++) {
if (tweens[i].tween) {
delete tweens[i].tween;
tweens[i].tween = nullptr;
}
}
}
int TweenDuino::Timeline::maxChildren() {
return TWEEN_TIMELINE_SIZE;
}
bool TweenDuino::Timeline::isActive() {
return initialized && lastUpdateTime >= startTime && !completed;
}
bool TweenDuino::Timeline::isComplete() {
return completed;
}
TweenDuino::Tween* TweenDuino::Timeline::addTo(float& target, float to, unsigned long duration) {
Tween* tween = TweenDuino::Tween::to(target, duration, to);
if (!addEntry(*tween, true)) {
// Oops, no room!
delete tween;
tween = nullptr;
}
return tween;
}
TweenDuino::Tween* TweenDuino::Timeline::addTo(float& target, float to, unsigned long duration, TweenDuino::Tween::Ease e, TweenDuino::Tween::EaseType type) {
Tween* tween = TweenDuino::Tween::to(target, duration, to, e, type);
if (!addEntry(*tween, true)) {
// Oops, no room!
delete tween;
tween = nullptr;
}
return tween;
}
bool TweenDuino::Timeline::add(TweenDuino::Tween &tween) {
return addEntry(tween);
}
/**
* Add tweens to this timeline.
*
* Child tweens will be unaware of any delays or timeline restarts; the 1st tween
* will always think it's starting at 0 millis, the 2nd exactly at the end of the
* 1st tween, etc.
*
* Managed tweens get their tween deleted during destroy.
*/
bool TweenDuino::Timeline::addEntry(TweenDuino::Tween &tween, bool managed) {
unsigned long nextStartTime = 0;
int entryIndex = 0;
// Maintence Note: Very similar looping logic in TweenDuino::Timeline::update & restart.
// If you change this line here, you might need to change it there.
for (; entryIndex < TWEEN_TIMELINE_SIZE && tweens[entryIndex].tween != nullptr; entryIndex++) {
unsigned long duration = tweens[entryIndex].tween->getDuration();
nextStartTime += duration;
}
TweenDuino::Timeline::TimelineEntry &entry = tweens[entryIndex];
if (entryIndex >= TWEEN_TIMELINE_SIZE) {
// We didn't have room for the tween.
return false;
}
// i is pointing at an "empty" TimelineEntry at this point. This tween's new home!
entry.tween = &tween;
entry.tween->begin(nextStartTime);
totalDuration += entry.tween->getDuration();
if (managed) {
entry.tlManagedTween = true;
}
return true;
}
void TweenDuino::Timeline::begin(unsigned long timeMs) {
startTime = timeMs;
totalTime = timeMs;
initialized = true;
}
void TweenDuino::Timeline::update(unsigned long newTime) {
if (!initialized) {
begin(newTime);
}
unsigned long prevTime = totalTime;
if (newTime >= totalDuration + startTime) {
totalTime = totalDuration + startTime;
completed = true;
} else {
totalTime = newTime;
}
lastUpdateTime = newTime;
// Save ourselves some cycles if we haven't moved ahead in time.
if (totalTime == prevTime) {
return;
}
unsigned long curTime = totalTime - startTime;
// Serial.print("curTime: "); Serial.println(curTime);
// Maintenance Note: Very similar looping logic in TweenDuino::Timeline::add & restart.
// If you change this line here, you might need to change it there.
for (int i = 0; i < TWEEN_TIMELINE_SIZE && tweens[i].tween != nullptr; i++) {
TweenDuino::Timeline::TimelineEntry &entry = tweens[i];
Tween *tween = entry.tween;
//Serial.print("About to check next start"); delay(100);
const unsigned long started = tween->getStartTime();
//Serial.print("Start is: "); delay(1000); Serial.println(started);
// TODO: Remove pointless elses. Left in for future debug for now.
// Serial.print("tween starting time: "); Serial.println(started);
if (curTime >= started) {
if (!tween->isComplete()) {
// Serial.print("updating with: "); Serial.println(curTime);
tween->update(curTime);
} else {
}
} else {
}
}
}
unsigned long TweenDuino::Timeline::getDuration() {
return totalDuration;
}
void TweenDuino::Timeline::restartFrom(unsigned long newTime) {
completed = false;
startTime = newTime;
lastUpdateTime = newTime;
totalTime = 0;
unsigned long entryStart = 0;
// Maintenance Note: Very similar looping logic in TweenDuino::Timeline::add & update
// If you change this line here, you might need to change it there.
for (int i = 0; i < TWEEN_TIMELINE_SIZE && tweens[i].tween != nullptr; i++) {
TweenDuino::Timeline::TimelineEntry &entry = tweens[i];
entry.tween->restartFrom(entryStart);
// Next entry starts at...
entryStart += entry.tween->getDuration();
}
}