[wpilib] SendableChooser: Add onChange listener (#5458)

This commit is contained in:
Gold856
2023-07-18 19:33:45 -04:00
committed by GitHub
parent 6f7cdd460e
commit 0b91ca6d5a
6 changed files with 98 additions and 6 deletions

View File

@@ -31,7 +31,7 @@ template <class T>
requires std::copy_constructible<T> && std::default_initializable<T>
class SendableChooser : public SendableChooserBase {
wpi::StringMap<T> m_choices;
std::function<void(T)> m_listener;
template <class U>
static U _unwrap_smart_ptr(const U& value);
@@ -82,6 +82,14 @@ class SendableChooser : public SendableChooserBase {
*/
auto GetSelected() -> decltype(_unwrap_smart_ptr(m_choices[""]));
/**
* Bind a listener that's called when the selected value changes.
* Only one listener can be bound. Calling this function will replace the
* previous listener.
* @param listener The function to call that accepts the new value
*/
void OnChange(std::function<void(T)>);
void InitSendable(nt::NTSendableBuilder& builder) override;
};

View File

@@ -48,6 +48,13 @@ auto SendableChooser<T>::GetSelected()
}
}
template <class T>
requires std::copy_constructible<T> && std::default_initializable<T>
void SendableChooser<T>::OnChange(std::function<void(T)> listener) {
std::scoped_lock lock(m_mutex);
m_listener = listener;
}
template <class T>
requires std::copy_constructible<T> && std::default_initializable<T>
void SendableChooser<T>::InitSendable(nt::NTSendableBuilder& builder) {
@@ -95,11 +102,23 @@ void SendableChooser<T>::InitSendable(nt::NTSendableBuilder& builder) {
nullptr);
builder.AddStringProperty(kSelected, nullptr,
[=, this](std::string_view val) {
std::scoped_lock lock(m_mutex);
m_haveSelected = true;
m_selected = val;
for (auto& pub : m_activePubs) {
pub.Set(val);
T choice{};
std::function<void(T)> listener;
{
std::scoped_lock lock(m_mutex);
m_haveSelected = true;
m_selected = val;
for (auto& pub : m_activePubs) {
pub.Set(val);
}
if (m_previousVal != val && m_listener) {
choice = m_choices[val];
listener = m_listener;
}
m_previousVal = val;
}
if (listener) {
listener(choice);
}
});
}

View File

@@ -45,6 +45,7 @@ class SendableChooserBase : public nt::NTSendable,
wpi::SmallVector<nt::StringPublisher, 2> m_activePubs;
wpi::mutex m_mutex;
int m_instance;
std::string m_previousVal;
static std::atomic_int s_instances;
};