mirror of
https://github.com/wpilibsuite/allwpilib
synced 2026-06-25 01:41:43 +00:00
[wpilib] SendableChooser: Add onChange listener (#5458)
This commit is contained in:
@@ -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;
|
||||
};
|
||||
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
};
|
||||
|
||||
|
||||
Reference in New Issue
Block a user