Now you can download a copy of these docs so you can use them offline! Download now
Command.cpp
1 /*----------------------------------------------------------------------------*/
2 /* Copyright (c) FIRST 2011. All Rights Reserved. */
3 /* Open Source Software - may be modified and shared by FRC teams. The code */
4 /* must be accompanied by the FIRST BSD license file in $(WIND_BASE)/WPILib. */
5 /*----------------------------------------------------------------------------*/
6 
7 #include "Commands/Command.h"
8 #include "Commands/CommandGroup.h"
9 #include "Commands/Scheduler.h"
10 #include "DriverStation.h"
11 #include "Timer.h"
12 #include "WPIErrors.h"
13 
14 static const char *kName = "name";
15 static const char *kRunning = "running";
16 static const char *kIsParented = "isParented";
17 
18 int Command::m_commandCounter = 0;
19 
20 void Command::InitCommand(const char *name, double timeout)
21 {
22  m_commandID = m_commandCounter++;
23  m_timeout = timeout;
24  m_locked = false;
25  m_startTime = -1;
26  m_initialized = false;
27  m_running = false;
28  m_interruptible = true;
29  m_canceled = false;
30  m_runWhenDisabled = false;
31  m_parent = NULL;
32  if (name == NULL)
33  {
34  // Don't have a way to find the subclass name like java, so use the address
35  char buf[32];
36  snprintf(buf, 32, "Command_%p", this);
37  m_name = buf;
38  }
39  else
40  {
41  m_name = name;
42  }
43  m_table = NULL;
44 }
45 
51 {
52  InitCommand(NULL, -1.0);
53 }
54 
59 Command::Command(const char *name)
60 {
61  if (name == NULL)
62  wpi_setWPIErrorWithContext(NullParameter, "name");
63  InitCommand(name, -1.0);
64 }
65 
71 Command::Command(double timeout)
72 {
73  if (timeout < 0.0)
74  wpi_setWPIErrorWithContext(ParameterOutOfRange, "timeout < 0.0");
75  InitCommand(NULL, timeout);
76 }
77 
84 Command::Command(const char *name, double timeout)
85 {
86  if (name == NULL)
87  wpi_setWPIErrorWithContext(NullParameter, "name");
88  if (timeout < 0.0)
89  wpi_setWPIErrorWithContext(ParameterOutOfRange, "timeout < 0.0");
90  InitCommand(name, timeout);
91 }
92 
93 Command::~Command()
94 {//TODO deal with cleaning up all listeners
95  /*if (m_table != NULL){
96  m_table->RemoveChangeListener(kRunning, this);
97  }*/
98 }
99 
106  return m_commandID;
107 }
108 
114 void Command::SetTimeout(double timeout)
115 {
116  if (timeout < 0.0)
117  wpi_setWPIErrorWithContext(ParameterOutOfRange, "timeout < 0.0");
118  else
119  m_timeout = timeout;
120 }
121 
128 {
129  if (m_startTime < 0.0)
130  return 0.0;
131  else
132  return Timer::GetFPGATimestamp() - m_startTime;
133 }
134 
144 void Command::Requires(Subsystem *subsystem)
145 {
146  if (!AssertUnlocked("Can not add new requirement to command"))
147  return;
148 
149  if (subsystem != NULL)
150  m_requirements.insert(subsystem);
151  else
152  wpi_setWPIErrorWithContext(NullParameter, "subsystem");
153 }
154 
159 void Command::Removed()
160 {
161  if (m_initialized)
162  {
163  if (IsCanceled())
164  {
165  Interrupted();
166  _Interrupted();
167  }
168  else
169  {
170  End();
171  _End();
172  }
173  }
174  m_initialized = false;
175  m_canceled = false;
176  m_running = false;
177  if (m_table != NULL)
178  m_table->PutBoolean(kRunning, false);
179 }
180 
187 {
188  LockChanges();
189  if (m_parent != NULL)
190  wpi_setWPIErrorWithContext(CommandIllegalUse, "Can not start a command that is part of a command group");
191 
193 }
194 
200 {
201  if (!m_runWhenDisabled && m_parent == NULL && DriverStation::GetInstance()->IsDisabled())
202  Cancel();
203 
204  if (IsCanceled())
205  return false;
206 
207  if (!m_initialized)
208  {
209  m_initialized = true;
210  StartTiming();
211  _Initialize();
212  Initialize();
213  }
214  _Execute();
215  Execute();
216  return !IsFinished();
217 }
218 
219 void Command::_Initialize()
220 {
221 }
222 
223 void Command::_Interrupted()
224 {
225 }
226 
227 void Command::_Execute()
228 {
229 }
230 
231 void Command::_End()
232 {
233 }
234 
240 void Command::StartTiming()
241 {
242  m_startTime = Timer::GetFPGATimestamp();
243 }
244 
252 {
253  return m_timeout != -1 && TimeSinceInitialized() >= m_timeout;
254 }
255 
260 Command::SubsystemSet Command::GetRequirements()
261 {
262  return m_requirements;
263 }
264 
268 void Command::LockChanges()
269 {
270  m_locked = true;
271 }
272 
278 bool Command::AssertUnlocked(const char *message)
279 {
280  if (m_locked)
281  {
282  char buf[128];
283  snprintf(buf, 128, "%s after being started or being added to a command group", message);
284  wpi_setWPIErrorWithContext(CommandIllegalUse, buf);
285  return false;
286  }
287  return true;
288 }
289 
295 {
296  if (parent == NULL)
297  {
298  wpi_setWPIErrorWithContext(NullParameter, "parent");
299  }
300  else if (m_parent != NULL)
301  {
302  wpi_setWPIErrorWithContext(CommandIllegalUse, "Can not give command to a command group after already being put in a command group");
303  }
304  else
305  {
306  LockChanges();
307  m_parent = parent;
308  if (m_table != NULL)
309  {
310  m_table->PutBoolean(kIsParented, true);
311  }
312  }
313 }
314 
326 void Command::StartRunning()
327 {
328  m_running = true;
329  m_startTime = -1;
330  if (m_table != NULL)
331  m_table->PutBoolean(kRunning, true);
332 }
333 
341 {
342  return m_running;
343 }
344 
354 {
355  if (m_parent != NULL)
356  wpi_setWPIErrorWithContext(CommandIllegalUse, "Can not cancel a command that is part of a command group");
357 
358  _Cancel();
359 }
360 
366 {
367  if (IsRunning())
368  m_canceled = true;
369 }
370 
376 {
377  return m_canceled;
378 }
379 
385 {
386  return m_interruptible;
387 }
388 
393 void Command::SetInterruptible(bool interruptible)
394 {
395  m_interruptible = interruptible;
396 }
397 
404 {
405  return m_requirements.count(system) > 0;
406 }
407 
414 {
415  return m_parent;
416 }
417 
425 {
426  m_runWhenDisabled = run;
427 }
428 
434 {
435  return m_runWhenDisabled;
436 }
437 
438 std::string Command::GetName()
439 {
440  return m_name;
441 }
442 
444 {
445  return "Command";
446 }
447 
449 {
450  if(m_table!=NULL)
451  m_table->RemoveTableListener(this);
452  m_table = table;
453  if(m_table!=NULL){
454  m_table->PutString(kName, GetName());
455  m_table->PutBoolean(kRunning, IsRunning());
456  m_table->PutBoolean(kIsParented, m_parent != NULL);
457  m_table->AddTableListener(kRunning, this, false);
458  }
459 }
460 
462  return m_table;
463 }
464 
465 void Command::ValueChanged(ITable* source, const std::string& key, EntryValue value, bool isNew)
466 {
467  if (value.b){
468  if(!IsRunning())
469  Start();
470  }
471  else{
472  if(IsRunning())
473  Cancel();
474  }
475 }
void SetInterruptible(bool interruptible)
Definition: Command.cpp:393
virtual void RemoveTableListener(ITableListener *listener)=0
virtual void _Cancel()
Definition: Command.cpp:365
bool AssertUnlocked(const char *message)
Definition: Command.cpp:278
virtual void Execute()=0
bool IsInterruptible()
Definition: Command.cpp:384
virtual void Interrupted()=0
Definition: ITable.h:26
virtual void AddTableListener(ITableListener *listener)=0
bool IsTimedOut()
Definition: Command.cpp:251
void Requires(Subsystem *s)
Definition: Command.cpp:144
void Start()
Definition: Command.cpp:186
double TimeSinceInitialized()
Definition: Command.cpp:127
void SetParent(CommandGroup *parent)
Definition: Command.cpp:294
void AddCommand(Command *command)
Definition: Scheduler.cpp:63
virtual std::string GetName()
Definition: Command.cpp:438
virtual void ValueChanged(ITable *source, const std::string &key, EntryValue value, bool isNew)
Definition: Command.cpp:465
virtual void PutBoolean(std::string key, bool value)=0
virtual ITable * GetTable()
Definition: Command.cpp:461
bool DoesRequire(Subsystem *subsystem)
Definition: Command.cpp:403
void Cancel()
Definition: Command.cpp:353
virtual void End()=0
bool WillRunWhenDisabled()
Definition: Command.cpp:433
int GetID()
Definition: Command.cpp:105
bool Run()
Definition: Command.cpp:199
static DriverStation * GetInstance()
virtual void Initialize()=0
Command()
Definition: Command.cpp:50
void SetTimeout(double timeout)
Definition: Command.cpp:114
bool IsRunning()
Definition: Command.cpp:340
void SetRunWhenDisabled(bool run)
Definition: Command.cpp:424
virtual void InitTable(ITable *table)
Definition: Command.cpp:448
CommandGroup * GetGroup()
Definition: Command.cpp:413
Definition: ITable.h:13
static Scheduler * GetInstance()
Definition: Scheduler.cpp:47
virtual bool IsFinished()=0
bool IsCanceled()
Definition: Command.cpp:375
virtual void PutString(std::string key, std::string value)=0
virtual std::string GetSmartDashboardType()
Definition: Command.cpp:443
SubsystemSet GetRequirements()
Definition: Command.cpp:260

Generated on Sat Apr 26 2014 12:26:45 for WPILibC++ by doxygen 1.8.6