RSeries astromech firmware
CommandEvent.h
Go to the documentation of this file.
1 #ifndef CommandEvent_h
2 #define CommandEvent_h
3 
4 #include "ReelTwo.h"
5 #include "core/AnimatedEvent.h"
6 
18 {
19 public:
25  {
26  fNext = *tail();
27  *tail() = this;
28  }
29 
33  static void process(char* cmd)
34  {
35  if (*cmd != 0)
36  {
37  // trim trailing whitespace and line feed
38  int len = strlen(cmd);
39  while (len > 0 && (isspace(cmd[len-1]) || cmd[len-1] == '\n'))
40  cmd[--len] = '\0';
41  if (len > 0)
42  {
43  for (CommandEvent* evt = *tail(); evt != NULL; evt = evt->fNext)
44  {
45  evt->handleCommand(cmd);
46  }
47  }
48  }
49  }
50 
54  static void process(const char* cmd)
55  {
56  if (*cmd != 0)
57  {
58  for (CommandEvent* evt = *tail(); evt != NULL; evt = evt->fNext)
59  {
60  evt->handleCommand(cmd);
61  }
62  }
63  }
64 
68  static void process(PROGMEMString pcmd)
69  {
70  char buffer[20];
71  const char* cmd = reinterpret_cast<const char *>(pcmd);
72  const char* cmd_end = cmd + strlen_P(cmd);
73  while (cmd < cmd_end)
74  {
75  char ch;
76  const char* pch = cmd;
77  do
78  {
79  if (((ch = pgm_read_byte(pch++)) == 0) || ch == '\n')
80  {
81  size_t len = min(size_t(pch - cmd - 1), sizeof(buffer)-1);
82  strncpy_P(buffer, cmd, len);
83  buffer[len] = 0;
84  cmd = pch;
85  // trim trailing whitespace and newline
86  while (len > 0)
87  {
88  ch = buffer[len-1];
89  if (isspace(ch) || ch == '\n')
90  buffer[--len] = '\0';
91  else
92  break;
93  }
94  if (len > 0)
95  {
96  for (CommandEvent* evt = *tail(); evt != NULL; evt = evt->fNext)
97  {
98  evt->handleCommand(buffer);
99  }
100  }
101  }
102  }
103  while (cmd < cmd_end && ch != 0);
104  }
105  }
106 
111  virtual void handleCommand(const char* cmd) = 0;
112 
117  virtual void handleCommand(String cmd)
118  {
119  handleCommand(cmd.c_str());
120  }
121 
122 private:
123  CommandEvent* fNext;
124 
125  static CommandEvent** tail()
126  {
127  static CommandEvent* sTail;
128  return &sTail;
129  }
130 };
131 
132 template<uint16_t BUFFER_SIZE=64> class CommandEventSerial : public AnimatedEvent
133 {
134 public:
135  CommandEventSerial(HardwareSerial &serial) :
136  fStream(&serial),
137  fPos(0)
138  {
139  }
140 
141  CommandEventSerial(Stream* stream) :
142  fStream(stream),
143  fPos(0)
144  {
145  }
146 
147  virtual void animate()
148  {
149  if (fStream->available())
150  {
151  int ch = fStream->read();
152  if (ch == '\r' || ch == '\n' || ch == 0)
153  {
154  fBuffer[fPos] = '\0';
155  fPos = 0;
156  if (*fBuffer != '\0')
157  {
158  CommandEvent::process(fBuffer);
159  }
160  }
161  else if (fPos < SizeOfArray(fBuffer))
162  {
163  fBuffer[fPos++] = ch;
164  }
165  if (fPos == SizeOfArray(fBuffer))
166  {
167  fBuffer[fPos-1] = '\0';
168  fPos = 0;
169  if (*fBuffer != '\0')
170  {
171  CommandEvent::process(fBuffer);
172  }
173  }
174  }
175  }
176 
177 private:
178  Stream* fStream;
179  char fBuffer[BUFFER_SIZE];
180  unsigned fPos;
181 };
182 
183 #endif
CommandEvent::process
static void process(char *cmd)
Calls handleCommand() for each created CommandEvent subclass.
Definition: CommandEvent.h:33
CommandEvent
Base class for all command enabled devices. CommandEvent::handleCommand() is called for each device e...
Definition: CommandEvent.h:17
ReelTwo.h
AnimatedEvent
Base class for all animated devices. AnimatedEvent::animate() is called for each device once through ...
Definition: AnimatedEvent.h:18
AnimatedEvent.h
CommandEventSerial::CommandEventSerial
CommandEventSerial(Stream *stream)
Definition: CommandEvent.h:141
CommandEventSerial::animate
virtual void animate()
Subclasses must implement this function to run through a single frame of animation/activity.
Definition: CommandEvent.h:147
CommandEvent::process
static void process(const char *cmd)
Calls handleCommand() for each created CommandEvent subclass.
Definition: CommandEvent.h:54
CommandEventSerial
Definition: CommandEvent.h:132
CommandEvent::process
static void process(PROGMEMString pcmd)
Calls handleCommand() for each created CommandEvent subclass.
Definition: CommandEvent.h:68
CommandEvent::handleCommand
virtual void handleCommand(const char *cmd)=0
Subclasses should implement this function to process commands specific to their device.
CommandEventSerial::CommandEventSerial
CommandEventSerial(HardwareSerial &serial)
Definition: CommandEvent.h:135
PROGMEMString
const typedef __FlashStringHelper * PROGMEMString
Definition: ReelTwo.h:235
CommandEvent::CommandEvent
CommandEvent()
Default Constructor.
Definition: CommandEvent.h:24
CommandEvent::handleCommand
virtual void handleCommand(String cmd)
Subclasses should implement this function to process commands specific to their device.
Definition: CommandEvent.h:117
SizeOfArray
#define SizeOfArray(arr)
Definition: ReelTwo.h:213