diff --git a/wpilibc/shared/include/SmartDashboard/SendableChooser.h b/wpilibc/shared/include/SmartDashboard/SendableChooser.h
index a372098f62..5dbee54aee 100644
--- a/wpilibc/shared/include/SmartDashboard/SendableChooser.h
+++ b/wpilibc/shared/include/SmartDashboard/SendableChooser.h
@@ -7,11 +7,12 @@
#pragma once
-#include
*
+ * @tparam T The type of values to be stored
* @see SmartDashboard
*/
-class SendableChooser : public Sendable {
+template
+class SendableChooser : public SendableChooserBase {
public:
virtual ~SendableChooser() = default;
- void AddObject(const std::string& name, void* object);
- void AddDefault(const std::string& name, void* object);
- void* GetSelected();
+ void AddObject(llvm::StringRef name, const T& object);
+ void AddDefault(llvm::StringRef name, const T& object);
+ T GetSelected();
void InitTable(std::shared_ptr subtable) override;
- std::shared_ptr GetTable() const override;
- std::string GetSmartDashboardType() const override;
private:
- std::string m_defaultChoice;
- std::map m_choices;
- std::shared_ptr m_table;
+ llvm::StringMap m_choices;
};
} // namespace frc
+
+#include "SendableChooser.inc"
diff --git a/wpilibc/shared/src/SmartDashboard/SendableChooser.cpp b/wpilibc/shared/include/SmartDashboard/SendableChooser.inc
similarity index 68%
rename from wpilibc/shared/src/SmartDashboard/SendableChooser.cpp
rename to wpilibc/shared/include/SmartDashboard/SendableChooser.inc
index 177ea126a9..ba9363f1e8 100644
--- a/wpilibc/shared/src/SmartDashboard/SendableChooser.cpp
+++ b/wpilibc/shared/include/SmartDashboard/SendableChooser.inc
@@ -5,13 +5,15 @@
/* the project. */
/*----------------------------------------------------------------------------*/
-#include "SmartDashboard/SendableChooser.h"
+#pragma once
-using namespace frc;
+#include
+#include
+#include
+#include
+#include
-static const std::string kDefault = "default";
-static const std::string kOptions = "options";
-static const std::string kSelected = "selected";
+namespace frc {
/**
* Adds the given object to the list of options.
@@ -22,7 +24,8 @@ static const std::string kSelected = "selected";
* @param name the name of the option
* @param object the option
*/
-void SendableChooser::AddObject(const std::string& name, void* object) {
+template
+void SendableChooser::AddObject(llvm::StringRef name, const T& object) {
m_choices[name] = object;
}
@@ -36,7 +39,8 @@ void SendableChooser::AddObject(const std::string& name, void* object) {
* @param name the name of the option
* @param object the option
*/
-void SendableChooser::AddDefault(const std::string& name, void* object) {
+template
+void SendableChooser::AddDefault(llvm::StringRef name, const T& object) {
m_defaultChoice = name;
AddObject(name, object);
}
@@ -49,29 +53,31 @@ void SendableChooser::AddDefault(const std::string& name, void* object) {
*
* @return the option selected
*/
-void* SendableChooser::GetSelected() {
+template
+T SendableChooser::GetSelected() {
std::string selected = m_table->GetString(kSelected, m_defaultChoice);
- if (selected == "")
+ if (selected == "") {
return nullptr;
- else
+ } else {
return m_choices[selected];
+ }
}
-void SendableChooser::InitTable(std::shared_ptr subtable) {
+template
+void SendableChooser::InitTable(std::shared_ptr subtable) {
std::vector keys;
m_table = subtable;
if (m_table != nullptr) {
- std::map::iterator iter;
- for (iter = m_choices.begin(); iter != m_choices.end(); iter++) {
- keys.push_back(iter->first);
+ for (const auto& choice : m_choices) {
+ keys.push_back(choice.first());
}
+
+ // Unlike std::map, llvm::StringMap elements are not sorted
+ std::sort(keys.begin(), keys.end());
+
m_table->PutValue(kOptions, nt::Value::MakeStringArray(std::move(keys)));
m_table->PutString(kDefault, m_defaultChoice);
}
}
-std::shared_ptr SendableChooser::GetTable() const { return m_table; }
-
-std::string SendableChooser::GetSmartDashboardType() const {
- return "String Chooser";
-}
+} // namespace frc
diff --git a/wpilibc/shared/include/SmartDashboard/SendableChooserBase.h b/wpilibc/shared/include/SmartDashboard/SendableChooserBase.h
new file mode 100644
index 0000000000..04102eec80
--- /dev/null
+++ b/wpilibc/shared/include/SmartDashboard/SendableChooserBase.h
@@ -0,0 +1,40 @@
+/*----------------------------------------------------------------------------*/
+/* Copyright (c) FIRST 2017. All Rights Reserved. */
+/* Open Source Software - may be modified and shared by FRC teams. The code */
+/* must be accompanied by the FIRST BSD license file in the root directory of */
+/* the project. */
+/*----------------------------------------------------------------------------*/
+
+#pragma once
+
+#include
+#include
+
+#include "SmartDashboard/Sendable.h"
+#include "tables/ITable.h"
+
+namespace frc {
+
+/**
+ * This class is a non-template base class for {@link SendableChooser}.
+ *
+ * It contains static, non-templated variables to avoid their duplication in the
+ * template class.
+ */
+class SendableChooserBase : public Sendable {
+ public:
+ virtual ~SendableChooserBase() = default;
+
+ std::shared_ptr GetTable() const override;
+ std::string GetSmartDashboardType() const override;
+
+ protected:
+ static const char* kDefault;
+ static const char* kOptions;
+ static const char* kSelected;
+
+ std::string m_defaultChoice;
+ std::shared_ptr m_table;
+};
+
+} // namespace frc
diff --git a/wpilibc/shared/src/SmartDashboard/SendableChooserBase.cpp b/wpilibc/shared/src/SmartDashboard/SendableChooserBase.cpp
new file mode 100644
index 0000000000..9552e9b14c
--- /dev/null
+++ b/wpilibc/shared/src/SmartDashboard/SendableChooserBase.cpp
@@ -0,0 +1,22 @@
+/*----------------------------------------------------------------------------*/
+/* Copyright (c) FIRST 2017. All Rights Reserved. */
+/* Open Source Software - may be modified and shared by FRC teams. The code */
+/* must be accompanied by the FIRST BSD license file in the root directory of */
+/* the project. */
+/*----------------------------------------------------------------------------*/
+
+#include "SmartDashboard/SendableChooserBase.h"
+
+using namespace frc;
+
+const char* SendableChooserBase::kDefault = "default";
+const char* SendableChooserBase::kOptions = "options";
+const char* SendableChooserBase::kSelected = "selected";
+
+std::shared_ptr SendableChooserBase::GetTable() const {
+ return m_table;
+}
+
+std::string SendableChooserBase::GetSmartDashboardType() const {
+ return "String Chooser";
+}
diff --git a/wpilibj/src/shared/java/edu/wpi/first/wpilibj/smartdashboard/SendableChooser.java b/wpilibj/src/shared/java/edu/wpi/first/wpilibj/smartdashboard/SendableChooser.java
index 62e4f6de42..3c3262518d 100644
--- a/wpilibj/src/shared/java/edu/wpi/first/wpilibj/smartdashboard/SendableChooser.java
+++ b/wpilibj/src/shared/java/edu/wpi/first/wpilibj/smartdashboard/SendableChooser.java
@@ -22,8 +22,10 @@ import edu.wpi.first.wpilibj.tables.ITable;
* SendableChooser} and then put it into the {@link SmartDashboard} to have a list of options appear
* on the laptop. Once autonomous starts, simply ask the {@link SendableChooser} what the selected
* value is.
+ *
+ * @param The type of the values to be stored
*/
-public class SendableChooser implements Sendable {
+public class SendableChooser implements Sendable {
/**
* The key for the default value.
@@ -40,7 +42,7 @@ public class SendableChooser implements Sendable {
/**
* A map linking strings to the objects the represent.
*/
- private final HashMap m_map = new HashMap<>();
+ private final HashMap m_map = new HashMap<>();
private String m_defaultChoice = null;
/**
@@ -56,7 +58,7 @@ public class SendableChooser implements Sendable {
* @param name the name of the option
* @param object the option
*/
- public void addObject(String name, Object object) {
+ public void addObject(String name, V object) {
// if we don't have a default, set the default automatically
if (m_defaultChoice == null) {
addDefault(name, object);
@@ -78,7 +80,7 @@ public class SendableChooser implements Sendable {
* @param name the name of the option
* @param object the option
*/
- public void addDefault(String name, Object object) {
+ public void addDefault(String name, V object) {
if (name == null) {
throw new NullPointerException("Name cannot be null");
}
@@ -95,7 +97,7 @@ public class SendableChooser implements Sendable {
*
* @return the option selected
*/
- public Object getSelected() {
+ public V getSelected() {
String selected = m_table.getString(SELECTED, null);
return m_map.getOrDefault(selected, m_map.get(m_defaultChoice));
}