WPILibC++ 2025.3.1
Loading...
Searching...
No Matches
SendableChooser.h
Go to the documentation of this file.
1// Copyright (c) FIRST and other WPILib contributors.
2// Open Source Software; you can modify and/or share it under the terms of
3// the WPILib BSD license file in the root directory of this project.
4
5#pragma once
6
7#include <algorithm>
8#include <concepts>
9#include <functional>
10#include <memory>
11#include <string>
12#include <string_view>
13#include <utility>
14#include <vector>
15
16#include <wpi/StringMap.h>
18
20
21namespace frc {
22
23/**
24 * The SendableChooser class is a useful tool for presenting a selection of
25 * options to the SmartDashboard.
26 *
27 * For instance, you may wish to be able to select between multiple autonomous
28 * modes. You can do this by putting every possible Command you want to run as
29 * an autonomous into a SendableChooser and then put it into the SmartDashboard
30 * to have a list of options appear on the laptop. Once autonomous starts,
31 * simply ask the SendableChooser what the selected value is.
32 *
33 * @tparam T The type of values to be stored
34 * @see SmartDashboard
35 */
36template <class T>
37 requires std::copy_constructible<T> && std::default_initializable<T>
39 wpi::StringMap<T> m_choices;
40 std::function<void(T)> m_listener;
41 template <class U>
42 static U _unwrap_smart_ptr(const U& value) {
43 return value;
44 }
45
46 template <class U>
47 static std::weak_ptr<U> _unwrap_smart_ptr(const std::shared_ptr<U>& value) {
48 return value;
49 }
50
51 public:
52 using CopyType = decltype(_unwrap_smart_ptr(m_choices.find("")->second));
53
54 SendableChooser() = default;
55 ~SendableChooser() override = default;
58
59 /**
60 * Adds the given object to the list of options.
61 *
62 * On the SmartDashboard on the desktop, the object will appear as the given
63 * name.
64 *
65 * @param name the name of the option
66 * @param object the option
67 */
68 void AddOption(std::string_view name, T object) {
69 m_choices[name] = std::move(object);
70 }
71
72 /**
73 * Add the given object to the list of options and marks it as the default.
74 *
75 * Functionally, this is very close to AddOption() except that it will use
76 * this as the default option if none other is explicitly selected.
77 *
78 * @param name the name of the option
79 * @param object the option
80 */
81 void SetDefaultOption(std::string_view name, T object) {
83 AddOption(name, std::move(object));
84 }
85
86 /**
87 * Returns a copy of the selected option (a std::weak_ptr<U> if T =
88 * std::shared_ptr<U>).
89 *
90 * If there is none selected, it will return the default. If there is none
91 * selected and no default, then it will return a value-initialized instance.
92 * For integer types, this is 0. For container types like std::string, this is
93 * an empty string.
94 *
95 * @return The option selected
96 */
98 std::string selected = m_defaultChoice;
99 {
100 std::scoped_lock lock(m_mutex);
101 if (m_haveSelected) {
102 selected = m_selected;
103 }
104 }
105 if (selected.empty()) {
106 return CopyType{};
107 } else {
108 auto it = m_choices.find(selected);
109 if (it == m_choices.end()) {
110 return CopyType{};
111 }
112 return _unwrap_smart_ptr(it->second);
113 }
114 }
115
116 /**
117 * Bind a listener that's called when the selected value changes.
118 * Only one listener can be bound. Calling this function will replace the
119 * previous listener.
120 * @param listener The function to call that accepts the new value
121 */
122 void OnChange(std::function<void(T)> listener) {
123 std::scoped_lock lock(m_mutex);
124 m_listener = listener;
125 }
126
127 void InitSendable(wpi::SendableBuilder& builder) override {
128 builder.SetSmartDashboardType("String Chooser");
131 kOptions,
132 [=, this] {
133 std::vector<std::string> keys;
134 for (const auto& choice : m_choices) {
135 keys.emplace_back(choice.first);
136 }
137 return keys;
138 },
139 nullptr);
141 kDefault,
142 [=, this](wpi::SmallVectorImpl<char>&) -> std::string_view {
143 return m_defaultChoice;
144 },
145 nullptr);
147 kActive,
148 [=, this](wpi::SmallVectorImpl<char>& buf) -> std::string_view {
149 std::scoped_lock lock(m_mutex);
150 if (m_haveSelected) {
151 buf.assign(m_selected.begin(), m_selected.end());
152 return {buf.data(), buf.size()};
153 } else {
154 return m_defaultChoice;
155 }
156 },
157 nullptr);
158 builder.AddStringProperty(kSelected, nullptr,
159 [=, this](std::string_view val) {
160 T choice{};
161 std::function<void(T)> listener;
162 {
163 std::scoped_lock lock(m_mutex);
164 m_haveSelected = true;
165 m_selected = val;
166 if (m_previousVal != val && m_listener) {
167 choice = m_choices[val];
168 listener = m_listener;
169 }
170 m_previousVal = val;
171 }
172 if (listener) {
173 listener(choice);
174 }
175 });
176 }
177};
178
179} // namespace frc
This class is a non-template base class for SendableChooser.
Definition SendableChooserBase.h:23
static constexpr const char * kActive
Definition SendableChooserBase.h:35
std::string m_defaultChoice
Definition SendableChooserBase.h:38
static constexpr const char * kInstance
Definition SendableChooserBase.h:36
wpi::mutex m_mutex
Definition SendableChooserBase.h:41
static constexpr const char * kOptions
Definition SendableChooserBase.h:33
static constexpr const char * kSelected
Definition SendableChooserBase.h:34
std::string m_selected
Definition SendableChooserBase.h:39
bool m_haveSelected
Definition SendableChooserBase.h:40
int m_instance
Definition SendableChooserBase.h:42
static constexpr const char * kDefault
Definition SendableChooserBase.h:32
std::string m_previousVal
Definition SendableChooserBase.h:43
The SendableChooser class is a useful tool for presenting a selection of options to the SmartDashboar...
Definition SendableChooser.h:38
SendableChooser & operator=(SendableChooser &&rhs)=default
void SetDefaultOption(std::string_view name, T object)
Add the given object to the list of options and marks it as the default.
Definition SendableChooser.h:81
SendableChooser(SendableChooser &&rhs)=default
decltype(_unwrap_smart_ptr(m_choices.find("") ->second)) CopyType
Definition SendableChooser.h:52
void InitSendable(wpi::SendableBuilder &builder) override
Initializes this Sendable object.
Definition SendableChooser.h:127
void OnChange(std::function< void(T)> listener)
Bind a listener that's called when the selected value changes.
Definition SendableChooser.h:122
~SendableChooser() override=default
void AddOption(std::string_view name, T object)
Adds the given object to the list of options.
Definition SendableChooser.h:68
CopyType GetSelected() const
Returns a copy of the selected option (a std::weak_ptr<U> if T = std::shared_ptr<U>).
Definition SendableChooser.h:97
SendableChooser()=default
Helper class for building Sendable dashboard representations.
Definition SendableBuilder.h:21
virtual void AddStringArrayProperty(std::string_view key, std::function< std::vector< std::string >()> getter, std::function< void(std::span< const std::string >)> setter)=0
Add a string array property.
virtual void SetSmartDashboardType(std::string_view type)=0
Set the string representation of the named data type that will be used by the smart dashboard for thi...
virtual void AddSmallStringProperty(std::string_view key, std::function< std::string_view(wpi::SmallVectorImpl< char > &buf)> getter, std::function< void(std::string_view)> setter)=0
Add a string property (SmallString form).
virtual void PublishConstInteger(std::string_view key, int64_t value)=0
Add a constant integer property.
virtual void AddStringProperty(std::string_view key, std::function< std::string()> getter, std::function< void(std::string_view)> setter)=0
Add a string property.
This class consists of common code factored out of the SmallVector class to reduce code duplication b...
Definition sha1.h:30
void assign(size_type NumElts, ValueParamT Elt)
Definition SmallVector.h:720
size_t size() const
Definition SmallVector.h:99
pointer data()
Return a pointer to the vector's buffer, even if empty().
Definition SmallVector.h:302
StringMap is a sorted associative container that contains key-value pairs with unique string keys.
Definition StringMap.h:26
iterator find(std::string_view key)
Finds an element with key equal to key.
Definition StringMap.h:655
Definition CAN.h:11