Now you can download a copy of these docs so you can use them offline! Download now
Command.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/Command.h" 00008 #include "Commands/CommandGroup.h" 00009 #include "Commands/Scheduler.h" 00010 #include "DriverStation.h" 00011 #include "NetworkTables/NetworkTable.h" 00012 #include "Timer.h" 00013 #include "WPIErrors.h" 00014 00015 static const char *kName = "name"; 00016 static const char *kRunning = "running"; 00017 static const char *kIsParented = "isParented"; 00018 00019 void Command::InitCommand(const char *name, double timeout) 00020 { 00021 m_timeout = timeout; 00022 m_locked = false; 00023 m_startTime = -1; 00024 m_initialized = false; 00025 m_running = false; 00026 m_interruptible = true; 00027 m_canceled = false; 00028 m_runWhenDisabled = false; 00029 m_parent = NULL; 00030 m_table = NULL; 00031 if (name == NULL) 00032 { 00033 // Don't have a way to find the subclass name like java, so use the address 00034 char buf[32]; 00035 snprintf(buf, 32, "Command_%p", this); 00036 m_name = buf; 00037 } 00038 else 00039 { 00040 m_name = name; 00041 } 00042 } 00043 00048 Command::Command() 00049 { 00050 InitCommand(NULL, -1.0); 00051 } 00052 00057 Command::Command(const char *name) 00058 { 00059 if (name == NULL) 00060 wpi_setWPIErrorWithContext(NullParameter, "name"); 00061 InitCommand(name, -1.0); 00062 } 00063 00069 Command::Command(double timeout) 00070 { 00071 if (timeout < 0.0) 00072 wpi_setWPIErrorWithContext(ParameterOutOfRange, "timeout < 0.0"); 00073 InitCommand(NULL, timeout); 00074 } 00075 00082 Command::Command(const char *name, double timeout) 00083 { 00084 if (name == NULL) 00085 wpi_setWPIErrorWithContext(NullParameter, "name"); 00086 if (timeout < 0.0) 00087 wpi_setWPIErrorWithContext(ParameterOutOfRange, "timeout < 0.0"); 00088 InitCommand(name, timeout); 00089 } 00090 00091 Command::~Command() 00092 { 00093 if (m_table != NULL) 00094 { 00095 m_table->RemoveChangeListener(kRunning, this); 00096 } 00097 } 00098 00104 void Command::SetTimeout(double timeout) 00105 { 00106 if (timeout < 0.0) 00107 wpi_setWPIErrorWithContext(ParameterOutOfRange, "timeout < 0.0"); 00108 else 00109 m_timeout = timeout; 00110 } 00111 00117 double Command::TimeSinceInitialized() 00118 { 00119 if (m_startTime < 0.0) 00120 return 0.0; 00121 else 00122 return Timer::GetFPGATimestamp() - m_startTime; 00123 } 00124 00134 void Command::Requires(Subsystem *subsystem) 00135 { 00136 if (!AssertUnlocked("Can not add new requirement to command")) 00137 return; 00138 00139 if (subsystem != NULL) 00140 m_requirements.insert(subsystem); 00141 else 00142 wpi_setWPIErrorWithContext(NullParameter, "subsystem"); 00143 } 00144 00149 void Command::Removed() 00150 { 00151 if (m_initialized) 00152 { 00153 if (IsCanceled()) 00154 { 00155 Interrupted(); 00156 _Interrupted(); 00157 } 00158 else 00159 { 00160 End(); 00161 _End(); 00162 } 00163 } 00164 m_initialized = false; 00165 m_canceled = false; 00166 m_running = false; 00167 if (m_table != NULL) 00168 m_table->PutBoolean(kRunning, false); 00169 } 00170 00176 void Command::Start() 00177 { 00178 LockChanges(); 00179 if (m_parent != NULL) 00180 wpi_setWPIErrorWithContext(CommandIllegalUse, "Can not start a command that is part of a command group"); 00181 00182 Scheduler::GetInstance()->AddCommand(this); 00183 } 00184 00189 bool Command::Run() 00190 { 00191 if (!m_runWhenDisabled && m_parent == NULL && DriverStation::GetInstance()->IsDisabled()) 00192 Cancel(); 00193 00194 if (IsCanceled()) 00195 return false; 00196 00197 if (!m_initialized) 00198 { 00199 m_initialized = true; 00200 StartTiming(); 00201 _Initialize(); 00202 Initialize(); 00203 } 00204 _Execute(); 00205 Execute(); 00206 return !IsFinished(); 00207 } 00208 00209 void Command::_Initialize() 00210 { 00211 } 00212 00213 void Command::_Interrupted() 00214 { 00215 } 00216 00217 void Command::_Execute() 00218 { 00219 } 00220 00221 void Command::_End() 00222 { 00223 } 00224 00230 void Command::StartTiming() 00231 { 00232 m_startTime = Timer::GetFPGATimestamp(); 00233 } 00234 00241 bool Command::IsTimedOut() 00242 { 00243 return m_timeout != -1 && TimeSinceInitialized() >= m_timeout; 00244 } 00245 00250 Command::SubsystemSet Command::GetRequirements() 00251 { 00252 return m_requirements; 00253 } 00254 00258 void Command::LockChanges() 00259 { 00260 m_locked = true; 00261 } 00262 00268 bool Command::AssertUnlocked(const char *message) 00269 { 00270 if (m_locked) 00271 { 00272 char buf[128]; 00273 snprintf(buf, 128, "%s after being started or being added to a command group", message); 00274 wpi_setWPIErrorWithContext(CommandIllegalUse, buf); 00275 return false; 00276 } 00277 return true; 00278 } 00279 00284 void Command::SetParent(CommandGroup *parent) 00285 { 00286 if (parent == NULL) 00287 { 00288 wpi_setWPIErrorWithContext(NullParameter, "parent"); 00289 } 00290 else if (m_parent != NULL) 00291 { 00292 wpi_setWPIErrorWithContext(CommandIllegalUse, "Can not give command to a command group after already being put in a command group"); 00293 } 00294 else 00295 { 00296 LockChanges(); 00297 m_parent = parent; 00298 if (m_table != NULL) 00299 { 00300 m_table->PutBoolean(kIsParented, true); 00301 } 00302 } 00303 } 00304 00316 void Command::StartRunning() 00317 { 00318 m_running = true; 00319 m_startTime = -1; 00320 if (m_table != NULL) 00321 m_table->PutBoolean(kRunning, true); 00322 } 00323 00330 bool Command::IsRunning() 00331 { 00332 return m_running; 00333 } 00334 00343 void Command::Cancel() 00344 { 00345 if (m_parent != NULL) 00346 wpi_setWPIErrorWithContext(CommandIllegalUse, "Can not cancel a command that is part of a command group"); 00347 00348 _Cancel(); 00349 } 00350 00355 void Command::_Cancel() 00356 { 00357 if (IsRunning()) 00358 m_canceled = true; 00359 } 00360 00365 bool Command::IsCanceled() 00366 { 00367 return m_canceled; 00368 } 00369 00374 bool Command::IsInterruptible() 00375 { 00376 return m_interruptible; 00377 } 00378 00383 void Command::SetInterruptible(bool interruptible) 00384 { 00385 m_interruptible = interruptible; 00386 } 00387 00393 bool Command::DoesRequire(Subsystem *system) 00394 { 00395 return m_requirements.count(system) > 0; 00396 } 00397 00403 CommandGroup *Command::GetGroup() 00404 { 00405 return m_parent; 00406 } 00407 00414 void Command::SetRunWhenDisabled(bool run) 00415 { 00416 m_runWhenDisabled = run; 00417 } 00418 00423 bool Command::WillRunWhenDisabled() 00424 { 00425 return m_runWhenDisabled; 00426 } 00427 00428 std::string Command::GetName() 00429 { 00430 return m_name; 00431 } 00432 00433 std::string Command::GetType() 00434 { 00435 return "Command"; 00436 } 00437 00438 NetworkTable *Command::GetTable() 00439 { 00440 if (m_table == NULL) 00441 { 00442 m_table = new NetworkTable(); 00443 m_table->PutString(kName, GetName()); 00444 m_table->PutBoolean(kRunning, IsRunning()); 00445 m_table->PutBoolean(kIsParented, m_parent != NULL); 00446 m_table->AddChangeListener(kRunning, this); 00447 } 00448 return m_table; 00449 } 00450 00451 void Command::ValueChanged(NetworkTable *table, const char *name, NetworkTables_Types type) 00452 { 00453 if (table->GetBoolean(kRunning)) 00454 Start(); 00455 else 00456 Cancel(); 00457 }
Generated on Thu Jan 12 2012 22:35:18 for WPILibC++ by
1.7.1