RSeries astromech firmware
Marcduino.h
Go to the documentation of this file.
1 #ifndef Marcduino_h
2 #define Marcduino_h
3 
4 #include "ReelTwo.h"
5 #include "core/Animation.h"
6 #include "core/JawaCommander.h"
7 
8 #define MARCDUINO_ANIMATION(name, marc) \
9  ANIMATION_FUNC_DECL(name); \
10  const char _marc_msg_##name[] PROGMEM = #marc; \
11  Marcduino Marc_##name(Animation_##name, _marc_msg_##name); \
12  ANIMATION(name)
13 
14 #define MARCDUINO_ACTION(name, marc, p) \
15  MARCDUINO_ANIMATION(name, marc) \
16  { \
17  DO_START() \
18  DO_ONCE(p) \
19  DO_END() \
20  }
21 
22 class Marcduino
23 {
24 public:
25  Marcduino(AnimationStep animation, const char* marc /* PROGMEM */) :
26  fMarc(marc),
27  fAnimation(animation),
28  fNext(NULL)
29  {
30  if (*head() == NULL)
31  *head() = this;
32  if (*tail() != NULL)
33  (*tail())->fNext = this;
34  *tail() = this;
35  }
36 
37  static void processCommand(AnimationPlayer& player, const char* cmd)
38  {
39  bool found = false;
40  for (Marcduino* marc = *head(); marc != NULL; marc = marc->fNext)
41  {
42  int len = strlen_P(marc->fMarc);
43  if (strncmp_P(cmd, marc->fMarc, len) == 0 ||
44  (marc->fMarc[0] == '@' && isdigit(cmd[0]) && strncmp_P(cmd, marc->fMarc+1, len-1) == 0 && len--))
45  {
46  AnimationStep animation = marc->fAnimation;
47  if (animation != NULL)
48  {
49  *command() = cmd + len;
50  player.animateOnce(animation);
51  found = true;
52  }
53  }
54  }
55  // Check for unprocess Jawa lite command
56  if (!found && *cmd == '@')
57  {
59  if (base != NULL)
60  {
61  base->process(cmd+1);
62  }
63  }
64  }
65 
66  static void send(PROGMEMString cmd)
67  {
68  #ifndef USE_SMQ
69  UNUSED_ARG(cmd)
70  #else
71  if (SMQ::sendTopic("MARC"))
72  {
73  SMQ::send_string(F("cmd"), cmd);
74  SMQ::send_end();
75  }
76  #endif
77  }
78 
79  static void send(const char* cmd)
80  {
81  #ifndef USE_SMQ
82  UNUSED_ARG(cmd)
83  #else
84  if (SMQ::sendTopic("MARC"))
85  {
86  SMQ::send_string(F("cmd"), cmd);
87  SMQ::send_end();
88  }
89  #endif
90  }
91 
92  static const char* getCommand()
93  {
94  return *command();
95  }
96 
97 private:
98  const char* fMarc;
99  AnimationStep fAnimation;
100  Marcduino* fNext;
101 
102  static const char** command()
103  {
104  static const char* sCmd;
105  return &sCmd;
106  }
107 
108  static Marcduino** head()
109  {
110  static Marcduino* sHead;
111  return &sHead;
112  }
113 
114  static Marcduino** tail()
115  {
116  static Marcduino* sTail;
117  return &sTail;
118  }
119 };
120 
121 template<uint16_t BUFFER_SIZE=64> class MarcduinoSerial : public AnimatedEvent
122 {
123 public:
124  MarcduinoSerial(HardwareSerial &serial, AnimationPlayer &player) :
125  fStream(&serial),
126  fPlayer(player),
127  fPos(0)
128  {
129  }
130 
131  MarcduinoSerial(Stream* stream, AnimationPlayer &player) :
132  fStream(stream),
133  fPlayer(player),
134  fPos(0)
135  {
136  }
137 
139  fStream(nullptr),
140  fPlayer(player),
141  fPos(0)
142  {
143  }
144 
145  void setStream(Stream* stream, Stream* outStream = nullptr)
146  {
147  fStream = stream;
148  fOutStream = outStream;
149  }
150 
151  virtual void animate()
152  {
153  if (fStream != nullptr && fStream->available())
154  {
155  int ch = fStream->read();
156  if (ch != -1)
157  {
158  // Pass any bytes to the next stream
159  if (fOutStream != nullptr)
160  {
161  uint8_t buf;
162  buf = ch;
163  fOutStream->write(&buf, 1);
164  }
165  if (ch == 0x0D)
166  {
167  fBuffer[fPos] = '\0';
168  fPos = 0;
169  if (*fBuffer != '\0')
170  {
171  Marcduino::processCommand(fPlayer, fBuffer);
172  }
173  }
174  else if (fPos < SizeOfArray(fBuffer)-1)
175  {
176  fBuffer[fPos++] = ch;
177  }
178  }
179  }
180  }
181 
182 private:
183  Stream* fStream;
184  Stream* fOutStream = nullptr;
185  AnimationPlayer& fPlayer;
186  char fBuffer[BUFFER_SIZE];
187  unsigned fPos;
188 };
189 
190 #endif
MarcduinoSerial::MarcduinoSerial
MarcduinoSerial(AnimationPlayer &player)
Definition: Marcduino.h:138
AnimationPlayer
Player of animation scripts.
Definition: Animation.h:79
ReelTwo.h
AnimatedEvent
Base class for all animated devices. AnimatedEvent::animate() is called for each device once through ...
Definition: AnimatedEvent.h:18
SMQ::send_end
static void send_end()
Definition: ReelTwoSMQ.h:463
SMQ::sendTopic
static bool sendTopic(const smq_id id)
Definition: ReelTwoSMQ.h:155
Marcduino::getCommand
static const char * getCommand()
Definition: Marcduino.h:92
JawaCommanderBase::get
static JawaCommanderBase * get()
Definition: JawaCommander.h:173
Marcduino::processCommand
static void processCommand(AnimationPlayer &player, const char *cmd)
Definition: Marcduino.h:37
MarcduinoSerial
Definition: Marcduino.h:121
Marcduino::Marcduino
Marcduino(AnimationStep animation, const char *marc)
Definition: Marcduino.h:25
Marcduino::send
static void send(const char *cmd)
Definition: Marcduino.h:79
MarcduinoSerial::MarcduinoSerial
MarcduinoSerial(Stream *stream, AnimationPlayer &player)
Definition: Marcduino.h:131
JawaCommanderBase
Definition: JawaCommander.h:6
Marcduino::send
static void send(PROGMEMString cmd)
Definition: Marcduino.h:66
MarcduinoSerial::animate
virtual void animate()
Subclasses must implement this function to run through a single frame of animation/activity.
Definition: Marcduino.h:151
Animation.h
Marcduino
Definition: Marcduino.h:22
AnimationStep
signed char(* AnimationStep)(class AnimationPlayer &animation, unsigned step, unsigned long num, unsigned long elapsedMillis)
Definition: Animation.h:10
MarcduinoSerial::setStream
void setStream(Stream *stream, Stream *outStream=nullptr)
Definition: Marcduino.h:145
JawaCommander.h
PROGMEMString
const typedef __FlashStringHelper * PROGMEMString
Definition: ReelTwo.h:235
UNUSED_ARG
#define UNUSED_ARG(arg)
Definition: ReelTwo.h:25
MarcduinoSerial::MarcduinoSerial
MarcduinoSerial(HardwareSerial &serial, AnimationPlayer &player)
Definition: Marcduino.h:124
SizeOfArray
#define SizeOfArray(arr)
Definition: ReelTwo.h:213
SMQ::send_string
static void send_string(const char *str)
Definition: ReelTwoSMQ.h:106
AnimationPlayer::animateOnce
void animateOnce(AnimationStep animation)
Play the specified animation script once.
Definition: Animation.h:135
JawaCommanderBase::process
void process(const char ch)
Append a single character to the parsers input buffer.
Definition: JawaCommander.h:139