Now you can download a copy of these docs so you can use them offline! Download now
CommandGroup.cpp
00001 /*----------------------------------------------------------------------------*/ 00002 /* Copyright (c) FIRST 2011. All Rights Reserved. */ 00003 /* Open Source Software - may be modified and shared by FRC teams. The code */ 00004 /* must be accompanied by the FIRST BSD license file in $(WIND_BASE)/WPILib. */ 00005 /*----------------------------------------------------------------------------*/ 00006 00007 #include "Commands/CommandGroup.h" 00008 #include "WPIErrors.h" 00009 00013 CommandGroup::CommandGroup() 00014 { 00015 m_currentCommandIndex = -1; 00016 } 00017 00022 CommandGroup::CommandGroup(const char *name) : 00023 Command(name) 00024 { 00025 m_currentCommandIndex = -1; 00026 } 00027 00028 CommandGroup::~CommandGroup() 00029 { 00030 } 00031 00044 void CommandGroup::AddSequential(Command *command) 00045 { 00046 if (command == NULL) 00047 { 00048 wpi_setWPIErrorWithContext(NullParameter, "command"); 00049 return; 00050 } 00051 if (!AssertUnlocked("Cannot add new command to command group")) 00052 return; 00053 00054 command->SetParent(this); 00055 00056 m_commands.push_back(CommandGroupEntry(command, CommandGroupEntry::kSequence_InSequence)); 00057 // Iterate through command->GetRequirements() and call Requires() on each required subsystem 00058 Command::SubsystemSet requirements = command->GetRequirements(); 00059 Command::SubsystemSet::iterator iter = requirements.begin(); 00060 for (; iter != requirements.end(); iter++) 00061 Requires(*iter); 00062 } 00063 00081 void CommandGroup::AddSequential(Command *command, double timeout) 00082 { 00083 if (command == NULL) 00084 { 00085 wpi_setWPIErrorWithContext(NullParameter, "command"); 00086 return; 00087 } 00088 if (!AssertUnlocked("Cannot add new command to command group")) 00089 return; 00090 if (timeout < 0.0) 00091 { 00092 wpi_setWPIErrorWithContext(ParameterOutOfRange, "timeout < 0.0"); 00093 return; 00094 } 00095 00096 command->SetParent(this); 00097 00098 m_commands.push_back(CommandGroupEntry(command, CommandGroupEntry::kSequence_InSequence, timeout)); 00099 // Iterate through command->GetRequirements() and call Requires() on each required subsystem 00100 Command::SubsystemSet requirements = command->GetRequirements(); 00101 Command::SubsystemSet::iterator iter = requirements.begin(); 00102 for (; iter != requirements.end(); iter++) 00103 Requires(*iter); 00104 } 00105 00125 void CommandGroup::AddParallel(Command *command) 00126 { 00127 if (command == NULL) 00128 { 00129 wpi_setWPIErrorWithContext(NullParameter, "command"); 00130 return; 00131 } 00132 if (!AssertUnlocked("Cannot add new command to command group")) 00133 return; 00134 00135 command->SetParent(this); 00136 00137 m_commands.push_back(CommandGroupEntry(command, CommandGroupEntry::kSequence_BranchChild)); 00138 // Iterate through command->GetRequirements() and call Requires() on each required subsystem 00139 Command::SubsystemSet requirements = command->GetRequirements(); 00140 Command::SubsystemSet::iterator iter = requirements.begin(); 00141 for (; iter != requirements.end(); iter++) 00142 Requires(*iter); 00143 } 00144 00169 void CommandGroup::AddParallel(Command *command, double timeout) 00170 { 00171 if (command == NULL) 00172 { 00173 wpi_setWPIErrorWithContext(NullParameter, "command"); 00174 return; 00175 } 00176 if (!AssertUnlocked("Cannot add new command to command group")) 00177 return; 00178 if (timeout < 0.0) 00179 { 00180 wpi_setWPIErrorWithContext(ParameterOutOfRange, "timeout < 0.0"); 00181 return; 00182 } 00183 00184 command->SetParent(this); 00185 00186 m_commands.push_back(CommandGroupEntry(command, CommandGroupEntry::kSequence_BranchChild, timeout)); 00187 // Iterate through command->GetRequirements() and call Requires() on each required subsystem 00188 Command::SubsystemSet requirements = command->GetRequirements(); 00189 Command::SubsystemSet::iterator iter = requirements.begin(); 00190 for (; iter != requirements.end(); iter++) 00191 Requires(*iter); 00192 } 00193 00194 void CommandGroup::_Initialize() 00195 { 00196 m_currentCommandIndex = -1; 00197 } 00198 00199 void CommandGroup::_Execute() 00200 { 00201 CommandGroupEntry entry; 00202 Command *cmd = NULL; 00203 bool firstRun = false; 00204 00205 if (m_currentCommandIndex == -1) 00206 { 00207 firstRun = true; 00208 m_currentCommandIndex = 0; 00209 } 00210 00211 while ((unsigned)m_currentCommandIndex < m_commands.size()) 00212 { 00213 if (cmd != NULL) 00214 { 00215 if (entry.IsTimedOut()) 00216 cmd->_Cancel(); 00217 00218 if (cmd->Run()) 00219 { 00220 break; 00221 } 00222 else 00223 { 00224 cmd->Removed(); 00225 m_currentCommandIndex++; 00226 firstRun = true; 00227 cmd = NULL; 00228 continue; 00229 } 00230 } 00231 00232 entry = m_commands[m_currentCommandIndex]; 00233 cmd = NULL; 00234 00235 switch (entry.m_state) 00236 { 00237 case CommandGroupEntry::kSequence_InSequence: 00238 cmd = entry.m_command; 00239 if (firstRun) 00240 { 00241 cmd->StartRunning(); 00242 CancelConflicts(cmd); 00243 firstRun = false; 00244 } 00245 break; 00246 00247 case CommandGroupEntry::kSequence_BranchPeer: 00248 m_currentCommandIndex++; 00249 entry.m_command->Start(); 00250 break; 00251 00252 case CommandGroupEntry::kSequence_BranchChild: 00253 m_currentCommandIndex++; 00254 CancelConflicts(entry.m_command); 00255 entry.m_command->StartRunning(); 00256 m_children.push_back(entry); 00257 break; 00258 } 00259 } 00260 00261 // Run Children 00262 CommandList::iterator iter = m_children.begin(); 00263 for (; iter != m_children.end();) 00264 { 00265 entry = *iter; 00266 Command *child = entry.m_command; 00267 if (entry.IsTimedOut()) 00268 child->_Cancel(); 00269 00270 if (!child->Run()) 00271 { 00272 child->Removed(); 00273 iter = m_children.erase(iter); 00274 } 00275 else 00276 { 00277 iter++; 00278 } 00279 } 00280 } 00281 00282 void CommandGroup::_End() 00283 { 00284 // Theoretically, we don't have to check this, but we do if teams override the IsFinished method 00285 if (m_currentCommandIndex != -1 && (unsigned)m_currentCommandIndex < m_commands.size()) 00286 { 00287 Command *cmd = m_commands[m_currentCommandIndex].m_command; 00288 cmd->_Cancel(); 00289 cmd->Removed(); 00290 } 00291 00292 CommandList::iterator iter = m_children.begin(); 00293 for (; iter != m_children.end(); iter++) 00294 { 00295 Command *cmd = iter->m_command; 00296 cmd->_Cancel(); 00297 cmd->Removed(); 00298 } 00299 m_children.clear(); 00300 } 00301 00302 void CommandGroup::_Interrupted() 00303 { 00304 _End(); 00305 } 00306 00307 // Can be overwritten by teams 00308 void CommandGroup::Initialize() 00309 { 00310 } 00311 00312 // Can be overwritten by teams 00313 void CommandGroup::Execute() 00314 { 00315 } 00316 00317 // Can be overwritten by teams 00318 void CommandGroup::End() 00319 { 00320 } 00321 00322 // Can be overwritten by teams 00323 void CommandGroup::Interrupted() 00324 { 00325 } 00326 00327 bool CommandGroup::IsFinished() 00328 { 00329 return (unsigned)m_currentCommandIndex >= m_commands.size() && m_children.empty(); 00330 } 00331 00332 bool CommandGroup::IsInterruptible() 00333 { 00334 if (!Command::IsInterruptible()) 00335 return false; 00336 00337 if (m_currentCommandIndex != -1 && (unsigned)m_currentCommandIndex < m_commands.size()) 00338 { 00339 Command *cmd = m_commands[m_currentCommandIndex].m_command; 00340 if (!cmd->IsInterruptible()) 00341 return false; 00342 } 00343 00344 CommandList::iterator iter = m_children.begin(); 00345 for (; iter != m_children.end(); iter++) 00346 { 00347 if (!iter->m_command->IsInterruptible()) 00348 return false; 00349 } 00350 00351 return true; 00352 } 00353 00354 void CommandGroup::CancelConflicts(Command *command) 00355 { 00356 CommandList::iterator childIter = m_children.begin(); 00357 for (; childIter != m_children.end();) 00358 { 00359 Command *child = childIter->m_command; 00360 bool erased = false; 00361 00362 Command::SubsystemSet requirements = command->GetRequirements(); 00363 Command::SubsystemSet::iterator requirementIter = requirements.begin(); 00364 for (; requirementIter != requirements.end(); requirementIter++) 00365 { 00366 if (child->DoesRequire(*requirementIter)) 00367 { 00368 child->_Cancel(); 00369 child->Removed(); 00370 childIter = m_children.erase(childIter); 00371 erased = true; 00372 break; 00373 } 00374 } 00375 if (!erased) 00376 childIter++; 00377 } 00378 } 00379 00380 int CommandGroup::GetSize() 00381 { 00382 return m_children.size(); 00383 }
Generated on Thu Jan 12 2012 22:35:18 for WPILibC++ by
1.7.1