Now you can download a copy of these docs so you can use them offline! Download now
CommandGroup.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/CommandGroup.h"
8 #include "WPIErrors.h"
9 
14 {
15  m_currentCommandIndex = -1;
16 }
17 
22 CommandGroup::CommandGroup(const char *name) :
23  Command(name)
24 {
25  m_currentCommandIndex = -1;
26 }
27 
28 CommandGroup::~CommandGroup()
29 {
30 }
31 
45 {
46  if (command == NULL)
47  {
48  wpi_setWPIErrorWithContext(NullParameter, "command");
49  return;
50  }
51  if (!AssertUnlocked("Cannot add new command to command group"))
52  return;
53 
54  command->SetParent(this);
55 
56  m_commands.push_back(CommandGroupEntry(command, CommandGroupEntry::kSequence_InSequence));
57  // Iterate through command->GetRequirements() and call Requires() on each required subsystem
58  Command::SubsystemSet requirements = command->GetRequirements();
59  Command::SubsystemSet::iterator iter = requirements.begin();
60  for (; iter != requirements.end(); iter++)
61  Requires(*iter);
62 }
63 
81 void CommandGroup::AddSequential(Command *command, double timeout)
82 {
83  if (command == NULL)
84  {
85  wpi_setWPIErrorWithContext(NullParameter, "command");
86  return;
87  }
88  if (!AssertUnlocked("Cannot add new command to command group"))
89  return;
90  if (timeout < 0.0)
91  {
92  wpi_setWPIErrorWithContext(ParameterOutOfRange, "timeout < 0.0");
93  return;
94  }
95 
96  command->SetParent(this);
97 
98  m_commands.push_back(CommandGroupEntry(command, CommandGroupEntry::kSequence_InSequence, timeout));
99  // Iterate through command->GetRequirements() and call Requires() on each required subsystem
100  Command::SubsystemSet requirements = command->GetRequirements();
101  Command::SubsystemSet::iterator iter = requirements.begin();
102  for (; iter != requirements.end(); iter++)
103  Requires(*iter);
104 }
105 
126 {
127  if (command == NULL)
128  {
129  wpi_setWPIErrorWithContext(NullParameter, "command");
130  return;
131  }
132  if (!AssertUnlocked("Cannot add new command to command group"))
133  return;
134 
135  command->SetParent(this);
136 
137  m_commands.push_back(CommandGroupEntry(command, CommandGroupEntry::kSequence_BranchChild));
138  // Iterate through command->GetRequirements() and call Requires() on each required subsystem
139  Command::SubsystemSet requirements = command->GetRequirements();
140  Command::SubsystemSet::iterator iter = requirements.begin();
141  for (; iter != requirements.end(); iter++)
142  Requires(*iter);
143 }
144 
169 void CommandGroup::AddParallel(Command *command, double timeout)
170 {
171  if (command == NULL)
172  {
173  wpi_setWPIErrorWithContext(NullParameter, "command");
174  return;
175  }
176  if (!AssertUnlocked("Cannot add new command to command group"))
177  return;
178  if (timeout < 0.0)
179  {
180  wpi_setWPIErrorWithContext(ParameterOutOfRange, "timeout < 0.0");
181  return;
182  }
183 
184  command->SetParent(this);
185 
186  m_commands.push_back(CommandGroupEntry(command, CommandGroupEntry::kSequence_BranchChild, timeout));
187  // Iterate through command->GetRequirements() and call Requires() on each required subsystem
188  Command::SubsystemSet requirements = command->GetRequirements();
189  Command::SubsystemSet::iterator iter = requirements.begin();
190  for (; iter != requirements.end(); iter++)
191  Requires(*iter);
192 }
193 
194 void CommandGroup::_Initialize()
195 {
196  m_currentCommandIndex = -1;
197 }
198 
199 void CommandGroup::_Execute()
200 {
201  CommandGroupEntry entry;
202  Command *cmd = NULL;
203  bool firstRun = false;
204 
205  if (m_currentCommandIndex == -1)
206  {
207  firstRun = true;
208  m_currentCommandIndex = 0;
209  }
210 
211  while ((unsigned)m_currentCommandIndex < m_commands.size())
212  {
213  if (cmd != NULL)
214  {
215  if (entry.IsTimedOut())
216  cmd->_Cancel();
217 
218  if (cmd->Run())
219  {
220  break;
221  }
222  else
223  {
224  cmd->Removed();
225  m_currentCommandIndex++;
226  firstRun = true;
227  cmd = NULL;
228  continue;
229  }
230  }
231 
232  entry = m_commands[m_currentCommandIndex];
233  cmd = NULL;
234 
235  switch (entry.m_state)
236  {
237  case CommandGroupEntry::kSequence_InSequence:
238  cmd = entry.m_command;
239  if (firstRun)
240  {
241  cmd->StartRunning();
242  CancelConflicts(cmd);
243  firstRun = false;
244  }
245  break;
246 
247  case CommandGroupEntry::kSequence_BranchPeer:
248  m_currentCommandIndex++;
249  entry.m_command->Start();
250  break;
251 
252  case CommandGroupEntry::kSequence_BranchChild:
253  m_currentCommandIndex++;
254  CancelConflicts(entry.m_command);
255  entry.m_command->StartRunning();
256  m_children.push_back(entry);
257  break;
258  }
259  }
260 
261  // Run Children
262  CommandList::iterator iter = m_children.begin();
263  for (; iter != m_children.end();)
264  {
265  entry = *iter;
266  Command *child = entry.m_command;
267  if (entry.IsTimedOut())
268  child->_Cancel();
269 
270  if (!child->Run())
271  {
272  child->Removed();
273  iter = m_children.erase(iter);
274  }
275  else
276  {
277  iter++;
278  }
279  }
280 }
281 
282 void CommandGroup::_End()
283 {
284  // Theoretically, we don't have to check this, but we do if teams override the IsFinished method
285  if (m_currentCommandIndex != -1 && (unsigned)m_currentCommandIndex < m_commands.size())
286  {
287  Command *cmd = m_commands[m_currentCommandIndex].m_command;
288  cmd->_Cancel();
289  cmd->Removed();
290  }
291 
292  CommandList::iterator iter = m_children.begin();
293  for (; iter != m_children.end(); iter++)
294  {
295  Command *cmd = iter->m_command;
296  cmd->_Cancel();
297  cmd->Removed();
298  }
299  m_children.clear();
300 }
301 
302 void CommandGroup::_Interrupted()
303 {
304  _End();
305 }
306 
307 // Can be overwritten by teams
309 {
310 }
311 
312 // Can be overwritten by teams
314 {
315 }
316 
317 // Can be overwritten by teams
319 {
320 }
321 
322 // Can be overwritten by teams
324 {
325 }
326 
328 {
329  return (unsigned)m_currentCommandIndex >= m_commands.size() && m_children.empty();
330 }
331 
332 bool CommandGroup::IsInterruptible()
333 {
335  return false;
336 
337  if (m_currentCommandIndex != -1 && (unsigned)m_currentCommandIndex < m_commands.size())
338  {
339  Command *cmd = m_commands[m_currentCommandIndex].m_command;
340  if (!cmd->IsInterruptible())
341  return false;
342  }
343 
344  CommandList::iterator iter = m_children.begin();
345  for (; iter != m_children.end(); iter++)
346  {
347  if (!iter->m_command->IsInterruptible())
348  return false;
349  }
350 
351  return true;
352 }
353 
354 void CommandGroup::CancelConflicts(Command *command)
355 {
356  CommandList::iterator childIter = m_children.begin();
357  for (; childIter != m_children.end();)
358  {
359  Command *child = childIter->m_command;
360  bool erased = false;
361 
362  Command::SubsystemSet requirements = command->GetRequirements();
363  Command::SubsystemSet::iterator requirementIter = requirements.begin();
364  for (; requirementIter != requirements.end(); requirementIter++)
365  {
366  if (child->DoesRequire(*requirementIter))
367  {
368  child->_Cancel();
369  child->Removed();
370  childIter = m_children.erase(childIter);
371  erased = true;
372  break;
373  }
374  }
375  if (!erased)
376  childIter++;
377  }
378 }
379 
380 int CommandGroup::GetSize()
381 {
382  return m_children.size();
383 }
virtual void _Cancel()
Definition: Command.cpp:365
void AddSequential(Command *command)
bool AssertUnlocked(const char *message)
Definition: Command.cpp:278
virtual void End()
bool IsInterruptible()
Definition: Command.cpp:384
void Requires(Subsystem *s)
Definition: Command.cpp:144
void Start()
Definition: Command.cpp:186
virtual void Interrupted()
void AddParallel(Command *command)
void SetParent(CommandGroup *parent)
Definition: Command.cpp:294
virtual void Execute()
bool DoesRequire(Subsystem *subsystem)
Definition: Command.cpp:403
virtual void Initialize()
bool Run()
Definition: Command.cpp:199
virtual bool IsFinished()
SubsystemSet GetRequirements()
Definition: Command.cpp:260

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