blob: c0d8c62613e305e72a3084071542b59f617029ed [file] [log] [blame]
jerrymf1579332013-02-07 01:56:28 +00001/*----------------------------------------------------------------------------*/
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/Subsystem.h"
8
9#include "Commands/Command.h"
10#include "Commands/Scheduler.h"
11#include "WPIErrors.h"
12
13/**
14 * Creates a subsystem with the given name
15 * @param name the name of the subsystem
16 */
17Subsystem::Subsystem(const char *name) :
18 m_currentCommand(NULL),
19 m_defaultCommand(NULL),
20 m_initializedDefaultCommand(false)
21{
22 m_name = name;
23 Scheduler::GetInstance()->RegisterSubsystem(this);
24 m_table = NULL;
jerrym42dedc02013-02-25 01:59:14 +000025 m_currentCommandChanged = true;
jerrymf1579332013-02-07 01:56:28 +000026}
27/**
28 * Initialize the default command for this subsystem
29 * This is meant to be the place to call SetDefaultCommand in a subsystem and will be called
30 * on all the subsystems by the CommandBase method before the program starts running by using
31 * the list of all registered Subsystems inside the Scheduler.
32 *
33 * This should be overridden by a Subsystem that has a default Command
34 */
35void Subsystem::InitDefaultCommand() {
36
37}
38
39/**
40 * Sets the default command. If this is not called or is called with null,
41 * then there will be no default command for the subsystem.
42 *
43 * <p><b>WARNING:</b> This should <b>NOT</b> be called in a constructor if the subsystem is a
44 * singleton.</p>
45 *
46 * @param command the default command (or null if there should be none)
47 */
48void Subsystem::SetDefaultCommand(Command *command)
49{
50 if (command == NULL)
51 {
52 m_defaultCommand = NULL;
53 }
54 else
55 {
56 bool found = false;
57 Command::SubsystemSet requirements = command->GetRequirements();
58 Command::SubsystemSet::iterator iter = requirements.begin();
59 for (; iter != requirements.end(); iter++)
60 {
61 if (*iter == this)
62 {
63 found = true;
64 break;
65 }
66 }
67
68 if (!found)
69 {
70 wpi_setWPIErrorWithContext(CommandIllegalUse, "A default command must require the subsystem");
71 return;
72 }
73
74 m_defaultCommand = command;
75 }
76 if (m_table != NULL)
77 {
78 if (m_defaultCommand != NULL)
79 {
80 m_table->PutBoolean("hasDefault", true);
81 m_table->PutString("default", m_defaultCommand->GetName());
82 }
83 else
84 {
85 m_table->PutBoolean("hasDefault", false);
86 }
87 }
88}
89
90/**
91 * Returns the default command (or null if there is none).
92 * @return the default command
93 */
94Command *Subsystem::GetDefaultCommand()
95{
96 if (!m_initializedDefaultCommand) {
97 m_initializedDefaultCommand = true;
98 InitDefaultCommand();
99 }
100 return m_defaultCommand;
101}
102
103/**
104 * Sets the current command
105 * @param command the new current command
106 */
107void Subsystem::SetCurrentCommand(Command *command)
108{
109 m_currentCommand = command;
jerrym42dedc02013-02-25 01:59:14 +0000110 m_currentCommandChanged = true;
jerrymf1579332013-02-07 01:56:28 +0000111}
112
113/**
114 * Returns the command which currently claims this subsystem.
115 * @return the command which currently claims this subsystem
116 */
117Command *Subsystem::GetCurrentCommand()
118{
119 return m_currentCommand;
120}
121
122/**
123 * Call this to alert Subsystem that the current command is actually the command.
124 * Sometimes, the {@link Subsystem} is told that it has no command while the {@link Scheduler}
125 * is going through the loop, only to be soon after given a new one. This will avoid that situation.
126 */
127void Subsystem::ConfirmCommand()
128{
jerrym42dedc02013-02-25 01:59:14 +0000129 if (m_currentCommandChanged) {
130 if (m_table != NULL)
jerrymf1579332013-02-07 01:56:28 +0000131 {
jerrym42dedc02013-02-25 01:59:14 +0000132 if (m_currentCommand != NULL)
133 {
134 m_table->PutBoolean("hasCommand", true);
135 m_table->PutString("command", m_currentCommand->GetName());
136 }
137 else
138 {
139 m_table->PutBoolean("hasCommand", false);
140 }
jerrymf1579332013-02-07 01:56:28 +0000141 }
jerrym42dedc02013-02-25 01:59:14 +0000142 m_currentCommandChanged = false;
jerrymf1579332013-02-07 01:56:28 +0000143 }
144}
145
146
147
148std::string Subsystem::GetName()
149{
150 return m_name;
151}
152
153std::string Subsystem::GetSmartDashboardType()
154{
155 return "Subsystem";
156}
157
158void Subsystem::InitTable(ITable* table)
159{
160 m_table = table;
161 if(m_table!=NULL){
162 if (m_defaultCommand != NULL) {
163 m_table->PutBoolean("hasDefault", true);
164 m_table->PutString("default", m_defaultCommand->GetName());
165 } else {
166 m_table->PutBoolean("hasDefault", false);
167 }
168 if (m_currentCommand != NULL) {
169 m_table->PutBoolean("hasCommand", true);
170 m_table->PutString("command", m_currentCommand->GetName());
171 } else {
172 m_table->PutBoolean("hasCommand", false);
173 }
174 }
175}
176
177ITable* Subsystem::GetTable(){
178 return m_table;
179}