RSeries astromech firmware
Animation.h
Go to the documentation of this file.
1 #ifndef Animation_h
2 #define Animation_h
3 
4 #include "ReelTwo.h"
5 #include "core/SetupEvent.h"
6 #include "core/AnimatedEvent.h"
7 #include "core/CommandEvent.h"
8 #include "ServoSequencer.h"
9 
10 typedef signed char (*AnimationStep)(class AnimationPlayer& animation, unsigned step, unsigned long num, unsigned long elapsedMillis);
11 
12 #define ANIMATION_FUNC_DECL(name) static signed char Animation_##name(class AnimationPlayer& animation,\
13  unsigned step, unsigned long num, unsigned long elapsedMillis)
14 #define ANIMATION(name) ANIMATION_FUNC_DECL(name) { enum { _firstStep = __COUNTER__ };
15 #define DO_START() UNUSED_ARG(num) UNUSED_ARG(elapsedMillis) switch (step+1) {
16 #define DO_CASE() case __COUNTER__-_firstStep:
17 #define DO_LABEL(label) enum { label = __COUNTER__-_firstStep }; case label: { return true; }
18 #define DO_ONCE_LABEL(label, p) enum { label = __COUNTER__-_firstStep }; case label: { p; return true; }
19 #define DO_ONCE(p) DO_CASE() { p; return true; }
20 #define DO_ONCE_AND_WAIT(p, ms) DO_CASE() { if (!animation.fRepeatStep) { p; } return (ms < elapsedMillis); }
21 #define DO_FOREVER(p) DO_CASE() { p; return false; }
22 #define DO_DURATION(ms, p) DO_CASE() { if (animation.getCurrentTimeMillis() < ms) { p; return false; } return true; }
23 #define DO_DURATION_STEP(ms, p) DO_CASE() { if (elapsedMillis < ms) { p; return false; } return true; }
24 #define DO_WAIT_MILLIS(ms) DO_CASE() { return (ms < elapsedMillis); }
25 #define DO_WAIT_SEC(sec) DO_CASE() { return (sec*1000L < long(elapsedMillis)); }
26 #define DO_GOTO(label) DO_CASE() { animation.gotoStep(label); return -1; }
27 #define DO_WHILE(cond,label) DO_CASE() { if (cond) { animation.gotoStep(label); return -1; } return true; }
28 #define DO_SEQUENCE(seq,mask) DO_CASE() { SEQUENCE_PLAY_ONCE(*animation.fServoSequencer, seq, mask); return true; }
29 #define DO_SEQUENCE_SPEED(seq,mask,speed) DO_CASE() { SEQUENCE_PLAY_ONCE_SPEED(*animation.fServoSequencer, seq, mask, speed); return true; }
30 #define DO_SEQUENCE_VARSPEED(seq,mask,minspeed, maxspeed) DO_CASE() { SEQUENCE_PLAY_ONCE_VARSPEED(*animation.fServoSequencer, seq, mask, minspeed, maxspeed); return true; }
31 #define DO_SEQUENCE_RANDOM_STEP(seq,mask) DO_CASE() { SEQUENCE_PLAY_RANDOM_STEP(*animation.fServoSequencer, seq, mask); return true; }
32 #define DO_WAIT_SEQUENCE() DO_CASE() { return animation.fServoSequencer->isFinished(); }
33 #define DO_WHILE_SEQUENCE(label) DO_CASE() { if (!animation.fServoSequencer->isFinished()) { animation.gotoStep(label); return -1; } return true; }
34 #define DO_COMMAND(cmd) DO_CASE() { CommandEvent::process(cmd); return true; }
35 #define DO_COMMAND_AND_WAIT(cmd, ms) DO_CASE() { if (!animation.fRepeatStep) { CommandEvent::process(cmd); } return (ms < elapsedMillis); }
36 #define DO_MARCDUINO(cmd) DO_CASE() { Marcduino::send(cmd); return true; }
37 #define DO_MARCDUINO_AND_WAIT(cmd, ms) DO_CASE() { if (!animation.fRepeatStep) { Marcduino::send(cmd); } return (ms < elapsedMillis); }
38 #define DO_RESET(p) case 0: { p; return true; }
39 #define DO_END() default: animation.end(); return false; } }
40 #define ANIMATION_PLAY_ONCE(player, name) player.animateOnce(Animation_##name)
41 
80 {
81 public:
85  inline AnimationPlayer() :
86  fServoSequencer(NULL)
87  {
88  reset();
89  }
90 
94  inline AnimationPlayer(ServoSequencer &sequencer) :
95  fServoSequencer(&sequencer)
96  {
97  reset();
98  }
99 
103  virtual void animate() override
104  {
105  if (fAnimation == NULL || fFlags == kEnded)
106  return;
107  unsigned long currentMillis = millis();
108  if (fFlags == kWaiting)
109  {
110  /* Time to run this step */
111  fFlags = kRunning;
112  fStepMillis = currentMillis;
113  fNum = 0;
114  }
115  if (fFlags == kRunning)
116  {
117  signed char ret = fAnimation(*this, fStep, fNum++, currentMillis - fStepMillis);
118  if (ret == 1)
119  {
120  fRepeatStep = false;
121  fNum = 0;
122  fStep++;
123  fStepMillis = currentMillis;
124  }
125  else if (ret == 0)
126  {
127  fRepeatStep = true;
128  }
129  }
130  }
131 
135  void animateOnce(AnimationStep animation)
136  {
137  // End any current animation
138  end();
139  fAnimation = animation;
140  fStartMillis = fStepMillis = millis();
141  }
142 
144  {
145  return (fFlags == kRunning) ? millis() - fStartMillis : 0;
146  }
147 
151  void nextStep()
152  {
153  gotoStep(fStep + 1);
154  }
155 
160  {
161  if (fStep > 0)
162  gotoStep(fStep - 1);
163  }
164 
168  void rewind()
169  {
170  gotoStep(0);
171  }
172 
176  void end()
177  {
178  if (fFlags == kRunning)
179  {
180  fFlags = kEnded;
181  if (fAnimation != NULL)
182  {
183  // Run reset step on current animation
184  fAnimation(*this, ~0L, 0, millis() - fStepMillis);
185  }
186  }
187  reset();
188  }
189 
193  void gotoStep(unsigned step)
194  {
195  fNum = 0;
196  fStep = (step > 0) ? step-1 : 0;
197  fFlags = kWaiting;
198  fStepMillis = millis();
199  fRepeatStep = false;
200  }
201 
205  void reset()
206  {
207  fNum = 0;
208  fStep = 0;
209  fRepeatStep = false;
210  fAnimation = NULL;
211  fFlags = kWaiting;
212  fStepMillis = millis();
213  }
214 
215  unsigned fNumSteps;
216  unsigned fStep;
219 
220 protected:
221  enum
222  {
223  kWaiting = 0,
224  kRunning = 1,
225  kEnded = 0xFF
226  };
227  uint8_t fFlags;
228  unsigned long fNum;
229  unsigned long fStepMillis;
230  unsigned long fStartMillis;
232 };
233 
234 #endif
AnimationPlayer::fFlags
uint8_t fFlags
Definition: Animation.h:227
AnimationPlayer::fServoSequencer
ServoSequencer * fServoSequencer
Definition: Animation.h:218
AnimationPlayer
Player of animation scripts.
Definition: Animation.h:79
ReelTwo.h
SetupEvent.h
AnimatedEvent
Base class for all animated devices. AnimatedEvent::animate() is called for each device once through ...
Definition: AnimatedEvent.h:18
AnimationPlayer::gotoStep
void gotoStep(unsigned step)
Go to to the specified step in the active animation script.
Definition: Animation.h:193
AnimationPlayer::fRepeatStep
bool fRepeatStep
Definition: Animation.h:217
AnimationPlayer::fNum
unsigned long fNum
Definition: Animation.h:228
AnimatedEvent.h
ServoSequencer
Plays a sequence of servo commands using a servo group mask.
Definition: ServoSequencer.h:389
AnimationPlayer::fStep
unsigned fStep
Definition: Animation.h:216
AnimationPlayer::previousStep
void previousStep()
Rewind to the previous step in the active animation script.
Definition: Animation.h:159
AnimationPlayer::getCurrentTimeMillis
long getCurrentTimeMillis()
Definition: Animation.h:143
AnimationPlayer::rewind
void rewind()
Rewind to the beginning in the active animation script.
Definition: Animation.h:168
AnimationPlayer::kRunning
@ kRunning
Definition: Animation.h:224
AnimationPlayer::fAnimation
AnimationStep fAnimation
Definition: Animation.h:231
AnimationPlayer::fNumSteps
unsigned fNumSteps
Definition: Animation.h:215
AnimationPlayer::fStartMillis
unsigned long fStartMillis
Definition: Animation.h:230
AnimationPlayer::end
void end()
Stop the active animation script.
Definition: Animation.h:176
AnimationPlayer::kWaiting
@ kWaiting
Definition: Animation.h:223
AnimationPlayer::AnimationPlayer
AnimationPlayer()
Default Constructor.
Definition: Animation.h:85
AnimationStep
signed char(* AnimationStep)(class AnimationPlayer &animation, unsigned step, unsigned long num, unsigned long elapsedMillis)
Definition: Animation.h:10
AnimationPlayer::fStepMillis
unsigned long fStepMillis
Definition: Animation.h:229
AnimationPlayer::AnimationPlayer
AnimationPlayer(ServoSequencer &sequencer)
Default Constructor.
Definition: Animation.h:94
ServoSequencer.h
CommandEvent.h
AnimationPlayer::animate
virtual void animate() override
Runs through a single step of any active animation script.
Definition: Animation.h:103
AnimationPlayer::reset
void reset()
Reset the animation player and stop any active animation script.
Definition: Animation.h:205
AnimationPlayer::animateOnce
void animateOnce(AnimationStep animation)
Play the specified animation script once.
Definition: Animation.h:135
AnimationPlayer::kEnded
@ kEnded
Definition: Animation.h:225
AnimationPlayer::nextStep
void nextStep()
Advance to the next step in the active animation script.
Definition: Animation.h:151