mirror of
https://github.com/wpilibsuite/allwpilib
synced 2026-06-26 01:51:41 +00:00
[ntcore] Revamp listeners (#4511)
- In both C++ and Java, add listener functions to Instance class (same as NT3 provided) - Add WaitForListenerQueue functions (same as NT3 provided) - Move Java non-poller implementation to Instance (previously only handled single instance) - Change C++ listeners to take non-const references for subscribers etc to help avoid footguns from use of temporary objects (also add doc comment) - Fix Preferences making .type persistent
This commit is contained in:
@@ -28,7 +28,7 @@ class ConnectionListener final {
|
||||
*
|
||||
* @param inst Instance
|
||||
* @param immediateNotify if notification should be immediately created for
|
||||
* existing connections
|
||||
* existing connections
|
||||
* @param listener Listener function
|
||||
*/
|
||||
ConnectionListener(
|
||||
@@ -50,6 +50,18 @@ class ConnectionListener final {
|
||||
*/
|
||||
NT_ConnectionListener GetHandle() const { return m_handle; }
|
||||
|
||||
/**
|
||||
* Wait for the connection listener queue to be empty. This is primarily
|
||||
* useful for deterministic testing. This blocks until either the connection
|
||||
* listener queue is empty (e.g. there are no more events that need to be
|
||||
* passed along to callbacks or poll queues) or the timeout expires.
|
||||
*
|
||||
* @param timeout timeout, in seconds. Set to 0 for non-blocking behavior, or
|
||||
* a negative value to block indefinitely
|
||||
* @return False if timed out, otherwise true.
|
||||
*/
|
||||
bool WaitForQueue(double timeout);
|
||||
|
||||
private:
|
||||
NT_ConnectionListener m_handle{0};
|
||||
};
|
||||
|
||||
@@ -17,7 +17,7 @@ inline ConnectionListener::ConnectionListener(
|
||||
NetworkTableInstance inst, bool immediateNotify,
|
||||
std::function<void(const ConnectionNotification&)> listener)
|
||||
: m_handle{
|
||||
AddConnectionListener(inst.GetHandle(), listener, immediateNotify)} {}
|
||||
AddConnectionListener(inst.GetHandle(), immediateNotify, listener)} {}
|
||||
|
||||
inline ConnectionListener::ConnectionListener(ConnectionListener&& rhs)
|
||||
: m_handle(rhs.m_handle) {
|
||||
@@ -36,6 +36,14 @@ inline ConnectionListener::~ConnectionListener() {
|
||||
}
|
||||
}
|
||||
|
||||
inline bool ConnectionListener::WaitForQueue(double timeout) {
|
||||
if (m_handle != 0) {
|
||||
return nt::WaitForConnectionListenerQueue(m_handle, timeout);
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
inline ConnectionListenerPoller::ConnectionListenerPoller(
|
||||
NetworkTableInstance inst)
|
||||
: m_handle(nt::CreateConnectionListenerPoller(inst.GetHandle())) {}
|
||||
|
||||
@@ -27,9 +27,11 @@ class FloatArrayTopic;
|
||||
class FloatTopic;
|
||||
class IntegerArrayTopic;
|
||||
class IntegerTopic;
|
||||
class MultiSubscriber;
|
||||
class RawTopic;
|
||||
class StringArrayTopic;
|
||||
class StringTopic;
|
||||
class Subscriber;
|
||||
class Topic;
|
||||
|
||||
/**
|
||||
@@ -359,15 +361,17 @@ class NetworkTableInstance final {
|
||||
*/
|
||||
|
||||
/**
|
||||
* Add a connection listener.
|
||||
* Add a connection listener. The callback function is called asynchronously
|
||||
* on a separate thread, so it's important to use synchronization or atomics
|
||||
* when accessing any shared state from the callback function.
|
||||
*
|
||||
* @param callback listener to add
|
||||
* @param immediate_notify notify listener of all existing connections
|
||||
* @param callback listener to add
|
||||
* @return Listener handle
|
||||
*/
|
||||
NT_ConnectionListener AddConnectionListener(
|
||||
std::function<void(const ConnectionNotification& event)> callback,
|
||||
bool immediate_notify) const;
|
||||
bool immediate_notify,
|
||||
std::function<void(const ConnectionNotification& event)> callback) const;
|
||||
|
||||
/**
|
||||
* Remove a connection listener.
|
||||
@@ -376,6 +380,190 @@ class NetworkTableInstance final {
|
||||
*/
|
||||
static void RemoveConnectionListener(NT_ConnectionListener conn_listener);
|
||||
|
||||
/**
|
||||
* Wait for the connection listener queue to be empty. This is primarily
|
||||
* useful for deterministic testing. This blocks until either the connection
|
||||
* listener queue is empty (e.g. there are no more events that need to be
|
||||
* passed along to callbacks or poll queues) or the timeout expires.
|
||||
*
|
||||
* @param timeout timeout, in seconds. Set to 0 for non-blocking behavior, or
|
||||
* a negative value to block indefinitely
|
||||
* @return False if timed out, otherwise true.
|
||||
*/
|
||||
bool WaitForConnectionListenerQueue(double timeout);
|
||||
|
||||
/** @} */
|
||||
|
||||
/**
|
||||
* @{
|
||||
* @name Topic Listener Functions
|
||||
*/
|
||||
|
||||
/**
|
||||
* Add a topic listener for changes on a particular topic. The callback
|
||||
* function is called asynchronously on a separate thread, so it's important
|
||||
* to use synchronization or atomics when accessing any shared state from the
|
||||
* callback function.
|
||||
*
|
||||
* @param topic Topic
|
||||
* @param eventMask Bitmask of TopicListenerFlags values
|
||||
* @param listener Listener function
|
||||
* @return Listener handle
|
||||
*/
|
||||
NT_TopicListener AddTopicListener(
|
||||
Topic topic, unsigned int eventMask,
|
||||
std::function<void(const TopicNotification&)> listener);
|
||||
|
||||
/**
|
||||
* Add a topic listener for topic changes on a subscriber. The callback
|
||||
* function is called asynchronously on a separate thread, so it's important
|
||||
* to use synchronization or atomics when accessing any shared state from the
|
||||
* callback function. This does NOT keep the subscriber active.
|
||||
*
|
||||
* @param subscriber Subscriber
|
||||
* @param eventMask Bitmask of TopicListenerFlags values
|
||||
* @param listener Listener function
|
||||
* @return Listener handle
|
||||
*/
|
||||
NT_TopicListener AddTopicListener(
|
||||
Subscriber& subscriber, unsigned int eventMask,
|
||||
std::function<void(const TopicNotification&)> listener);
|
||||
|
||||
/**
|
||||
* Add a topic listener for topic changes on a subscriber. The callback
|
||||
* function is called asynchronously on a separate thread, so it's important
|
||||
* to use synchronization or atomics when accessing any shared state from the
|
||||
* callback function. This does NOT keep the subscriber active.
|
||||
*
|
||||
* @param subscriber Subscriber
|
||||
* @param eventMask Bitmask of TopicListenerFlags values
|
||||
* @param listener Listener function
|
||||
* @return Listener handle
|
||||
*/
|
||||
NT_TopicListener AddTopicListener(
|
||||
MultiSubscriber& subscriber, int eventMask,
|
||||
std::function<void(const TopicNotification&)> listener);
|
||||
|
||||
/**
|
||||
* Add a topic listener for topic changes on an entry. The callback function
|
||||
* is called asynchronously on a separate thread, so it's important to use
|
||||
* synchronization or atomics when accessing any shared state from the
|
||||
* callback function.
|
||||
*
|
||||
* @param entry Entry
|
||||
* @param eventMask Bitmask of TopicListenerFlags values
|
||||
* @param listener Listener function
|
||||
* @return Listener handle
|
||||
*/
|
||||
NT_TopicListener AddTopicListener(
|
||||
NetworkTableEntry& entry, int eventMask,
|
||||
std::function<void(const TopicNotification&)> listener);
|
||||
|
||||
/**
|
||||
* Add a topic listener for changes to topics with names that start with any
|
||||
* of the given prefixes. The callback function is called asynchronously on a
|
||||
* separate thread, so it's important to use synchronization or atomics when
|
||||
* accessing any shared state from the callback function.
|
||||
*
|
||||
* @param prefixes Topic name string prefixes
|
||||
* @param eventMask Bitmask of TopicListenerFlags values
|
||||
* @param listener Listener function
|
||||
* @return Listener handle
|
||||
*/
|
||||
NT_TopicListener AddTopicListener(
|
||||
std::span<const std::string_view> prefixes, int eventMask,
|
||||
std::function<void(const TopicNotification&)> listener);
|
||||
|
||||
/**
|
||||
* Remove a topic listener.
|
||||
*
|
||||
* @param listener Listener handle to remove
|
||||
*/
|
||||
static void RemoveTopicListener(NT_TopicListener listener);
|
||||
|
||||
/**
|
||||
* Wait for the topic listener queue to be empty. This is primarily useful for
|
||||
* deterministic testing. This blocks until either the topic listener queue is
|
||||
* empty (e.g. there are no more events that need to be passed along to
|
||||
* callbacks or poll queues) or the timeout expires.
|
||||
*
|
||||
* @param timeout timeout, in seconds. Set to 0 for non-blocking behavior, or
|
||||
* a negative value to block indefinitely
|
||||
* @return False if timed out, otherwise true.
|
||||
*/
|
||||
bool WaitForTopicListenerQueue(double timeout);
|
||||
|
||||
/** @} */
|
||||
|
||||
/**
|
||||
* @{
|
||||
* @name Value Listener Functions
|
||||
*/
|
||||
|
||||
/**
|
||||
* Add a value listener for value changes on a subscriber. The callback
|
||||
* function is called asynchronously on a separate thread, so it's important
|
||||
* to use synchronization or atomics when accessing any shared state from the
|
||||
* callback function. This does NOT keep the subscriber active.
|
||||
*
|
||||
* @param subscriber Subscriber
|
||||
* @param eventMask Bitmask of ValueListenerFlags values
|
||||
* @param listener Listener function
|
||||
* @return Listener handle
|
||||
*/
|
||||
NT_ValueListener AddValueListener(
|
||||
Subscriber& subscriber, unsigned int eventMask,
|
||||
std::function<void(const ValueNotification&)> listener);
|
||||
|
||||
/**
|
||||
* Add a value listener for value changes on a subscriber. The callback
|
||||
* function is called asynchronously on a separate thread, so it's important
|
||||
* to use synchronization or atomics when accessing any shared state from the
|
||||
* callback function. This does NOT keep the subscriber active.
|
||||
*
|
||||
* @param subscriber Subscriber
|
||||
* @param eventMask Bitmask of ValueListenerFlags values
|
||||
* @param listener Listener function
|
||||
* @return Listener handle
|
||||
*/
|
||||
NT_ValueListener AddValueListener(
|
||||
MultiSubscriber& subscriber, unsigned int eventMask,
|
||||
std::function<void(const ValueNotification&)> listener);
|
||||
|
||||
/**
|
||||
* Add a value listener for value changes on an entry. The callback function
|
||||
* is called asynchronously on a separate thread, so it's important to use
|
||||
* synchronization or atomics when accessing any shared state from the
|
||||
* callback function.
|
||||
*
|
||||
* @param entry Entry
|
||||
* @param eventMask Bitmask of ValueListenerFlags values
|
||||
* @param listener Listener function
|
||||
* @return Listener handle
|
||||
*/
|
||||
NT_ValueListener AddValueListener(
|
||||
NetworkTableEntry& entry, int eventMask,
|
||||
std::function<void(const ValueNotification&)> listener);
|
||||
|
||||
/**
|
||||
* Remove a value listener.
|
||||
*
|
||||
* @param listener Listener handle to remove
|
||||
*/
|
||||
static void RemoveValueListener(NT_ValueListener listener);
|
||||
|
||||
/**
|
||||
* Wait for the value listener queue to be empty. This is primarily useful for
|
||||
* deterministic testing. This blocks until either the value listener queue is
|
||||
* empty (e.g. there are no more events that need to be passed along to
|
||||
* callbacks or poll queues) or the timeout expires.
|
||||
*
|
||||
* @param timeout timeout, in seconds. Set to 0 for non-blocking behavior, or
|
||||
* a negative value to block indefinitely
|
||||
* @return False if timed out, otherwise true.
|
||||
*/
|
||||
bool WaitForValueListenerQueue(double timeout);
|
||||
|
||||
/** @} */
|
||||
|
||||
/**
|
||||
|
||||
@@ -82,11 +82,83 @@ inline NetworkTableEntry NetworkTableInstance::GetEntry(std::string_view name) {
|
||||
return NetworkTableEntry{::nt::GetEntry(m_handle, name)};
|
||||
}
|
||||
|
||||
inline NT_ConnectionListener NetworkTableInstance::AddConnectionListener(
|
||||
bool immediate_notify,
|
||||
std::function<void(const ConnectionNotification& event)> callback) const {
|
||||
return ::nt::AddConnectionListener(m_handle, immediate_notify,
|
||||
std::move(callback));
|
||||
}
|
||||
|
||||
inline bool NetworkTableInstance::WaitForConnectionListenerQueue(
|
||||
double timeout) {
|
||||
return ::nt::WaitForConnectionListenerQueue(m_handle, timeout);
|
||||
}
|
||||
|
||||
inline void NetworkTableInstance::RemoveConnectionListener(
|
||||
NT_ConnectionListener conn_listener) {
|
||||
::nt::RemoveConnectionListener(conn_listener);
|
||||
}
|
||||
|
||||
inline NT_TopicListener NetworkTableInstance::AddTopicListener(
|
||||
Topic topic, unsigned int eventMask,
|
||||
std::function<void(const TopicNotification&)> listener) {
|
||||
return ::nt::AddTopicListener(topic.GetHandle(), eventMask,
|
||||
std::move(listener));
|
||||
}
|
||||
|
||||
inline NT_TopicListener NetworkTableInstance::AddTopicListener(
|
||||
Subscriber& subscriber, unsigned int eventMask,
|
||||
std::function<void(const TopicNotification&)> listener) {
|
||||
return ::nt::AddTopicListener(subscriber.GetHandle(), eventMask,
|
||||
std::move(listener));
|
||||
}
|
||||
|
||||
inline NT_TopicListener NetworkTableInstance::AddTopicListener(
|
||||
NetworkTableEntry& entry, int eventMask,
|
||||
std::function<void(const TopicNotification&)> listener) {
|
||||
return ::nt::AddTopicListener(entry.GetHandle(), eventMask,
|
||||
std::move(listener));
|
||||
}
|
||||
|
||||
inline NT_TopicListener NetworkTableInstance::AddTopicListener(
|
||||
std::span<const std::string_view> prefixes, int eventMask,
|
||||
std::function<void(const TopicNotification&)> listener) {
|
||||
return ::nt::AddTopicListener(m_handle, prefixes, eventMask,
|
||||
std::move(listener));
|
||||
}
|
||||
|
||||
inline void NetworkTableInstance::RemoveTopicListener(
|
||||
NT_TopicListener listener) {
|
||||
return ::nt::RemoveTopicListener(listener);
|
||||
}
|
||||
|
||||
inline bool NetworkTableInstance::WaitForTopicListenerQueue(double timeout) {
|
||||
return ::nt::WaitForTopicListenerQueue(m_handle, timeout);
|
||||
}
|
||||
|
||||
inline NT_ValueListener NetworkTableInstance::AddValueListener(
|
||||
Subscriber& subscriber, unsigned int eventMask,
|
||||
std::function<void(const ValueNotification&)> listener) {
|
||||
return ::nt::AddValueListener(subscriber.GetHandle(), eventMask,
|
||||
std::move(listener));
|
||||
}
|
||||
|
||||
inline NT_ValueListener NetworkTableInstance::AddValueListener(
|
||||
NetworkTableEntry& entry, int eventMask,
|
||||
std::function<void(const ValueNotification&)> listener) {
|
||||
return ::nt::AddValueListener(entry.GetHandle(), eventMask,
|
||||
std::move(listener));
|
||||
}
|
||||
|
||||
inline void NetworkTableInstance::RemoveValueListener(
|
||||
NT_ValueListener listener) {
|
||||
::nt::RemoveValueListener(listener);
|
||||
}
|
||||
|
||||
inline bool NetworkTableInstance::WaitForValueListenerQueue(double timeout) {
|
||||
return ::nt::WaitForValueListenerQueue(m_handle, timeout);
|
||||
}
|
||||
|
||||
inline unsigned int NetworkTableInstance::GetNetworkMode() const {
|
||||
return ::nt::GetNetworkMode(m_handle);
|
||||
}
|
||||
|
||||
@@ -98,23 +98,25 @@ class TopicListener final {
|
||||
std::function<void(const TopicNotification&)> listener);
|
||||
|
||||
/**
|
||||
* Create a listener for topic changes on a subscriber.
|
||||
* Create a listener for topic changes on a subscriber. This does NOT keep the
|
||||
* subscriber active.
|
||||
*
|
||||
* @param subscriber Subscriber
|
||||
* @param mask Bitmask of TopicListenerFlags values
|
||||
* @param listener Listener function
|
||||
*/
|
||||
TopicListener(const Subscriber& subscriber, unsigned int mask,
|
||||
TopicListener(Subscriber& subscriber, unsigned int mask,
|
||||
std::function<void(const TopicNotification&)> listener);
|
||||
|
||||
/**
|
||||
* Create a listener for topic changes on a subscriber.
|
||||
* Create a listener for topic changes on a subscriber. This does NOT keep the
|
||||
* subscriber active.
|
||||
*
|
||||
* @param subscriber Subscriber
|
||||
* @param mask Bitmask of TopicListenerFlags values
|
||||
* @param listener Listener function
|
||||
*/
|
||||
TopicListener(const MultiSubscriber& subscriber, unsigned int mask,
|
||||
TopicListener(MultiSubscriber& subscriber, unsigned int mask,
|
||||
std::function<void(const TopicNotification&)> listener);
|
||||
|
||||
/**
|
||||
@@ -124,7 +126,7 @@ class TopicListener final {
|
||||
* @param mask Bitmask of TopicListenerFlags values
|
||||
* @param listener Listener function
|
||||
*/
|
||||
TopicListener(const NetworkTableEntry& entry, unsigned int mask,
|
||||
TopicListener(NetworkTableEntry& entry, unsigned int mask,
|
||||
std::function<void(const TopicNotification&)> listener);
|
||||
|
||||
TopicListener(const TopicListener&) = delete;
|
||||
@@ -142,6 +144,18 @@ class TopicListener final {
|
||||
*/
|
||||
NT_TopicListener GetHandle() const { return m_handle; }
|
||||
|
||||
/**
|
||||
* Wait for the topic listener queue to be empty. This is primarily useful for
|
||||
* deterministic testing. This blocks until either the topic listener queue is
|
||||
* empty (e.g. there are no more events that need to be passed along to
|
||||
* callbacks or poll queues) or the timeout expires.
|
||||
*
|
||||
* @param timeout timeout, in seconds. Set to 0 for non-blocking behavior, or
|
||||
* a negative value to block indefinitely
|
||||
* @return False if timed out, otherwise true.
|
||||
*/
|
||||
bool WaitForQueue(double timeout);
|
||||
|
||||
private:
|
||||
NT_TopicListener m_handle{0};
|
||||
};
|
||||
@@ -198,22 +212,24 @@ class TopicListenerPoller final {
|
||||
NT_TopicListener Add(Topic topic, unsigned int mask);
|
||||
|
||||
/**
|
||||
* Start listening to topic changes on a subscriber.
|
||||
* Start listening to topic changes on a subscriber. This does NOT keep the
|
||||
* subscriber active.
|
||||
*
|
||||
* @param subscriber Subscriber
|
||||
* @param mask Bitmask of TopicListenerFlags values
|
||||
* @return Listener handle
|
||||
*/
|
||||
NT_TopicListener Add(const Subscriber& subscriber, unsigned int mask);
|
||||
NT_TopicListener Add(Subscriber& subscriber, unsigned int mask);
|
||||
|
||||
/**
|
||||
* Start listening to topic changes on a subscriber.
|
||||
* Start listening to topic changes on a subscriber. This does NOT keep the
|
||||
* subscriber active.
|
||||
*
|
||||
* @param subscriber Subscriber
|
||||
* @param mask Bitmask of TopicListenerFlags values
|
||||
* @return Listener handle
|
||||
*/
|
||||
NT_TopicListener Add(const MultiSubscriber& subscriber, unsigned int mask);
|
||||
NT_TopicListener Add(MultiSubscriber& subscriber, unsigned int mask);
|
||||
|
||||
/**
|
||||
* Start listening to topic changes on an entry.
|
||||
@@ -222,7 +238,7 @@ class TopicListenerPoller final {
|
||||
* @param mask Bitmask of TopicListenerFlags values
|
||||
* @return Listener handle
|
||||
*/
|
||||
NT_TopicListener Add(const NetworkTableEntry& entry, unsigned int mask);
|
||||
NT_TopicListener Add(NetworkTableEntry& entry, unsigned int mask);
|
||||
|
||||
/**
|
||||
* Remove a listener.
|
||||
|
||||
@@ -29,17 +29,17 @@ inline TopicListener::TopicListener(
|
||||
: m_handle{AddTopicListener(topic.GetHandle(), mask, listener)} {}
|
||||
|
||||
inline TopicListener::TopicListener(
|
||||
const Subscriber& subscriber, unsigned int mask,
|
||||
Subscriber& subscriber, unsigned int mask,
|
||||
std::function<void(const TopicNotification&)> listener)
|
||||
: m_handle{AddTopicListener(subscriber.GetHandle(), mask, listener)} {}
|
||||
|
||||
inline TopicListener::TopicListener(
|
||||
const MultiSubscriber& subscriber, unsigned int mask,
|
||||
MultiSubscriber& subscriber, unsigned int mask,
|
||||
std::function<void(const TopicNotification&)> listener)
|
||||
: m_handle{AddTopicListener(subscriber.GetHandle(), mask, listener)} {}
|
||||
|
||||
inline TopicListener::TopicListener(
|
||||
const NetworkTableEntry& entry, unsigned int mask,
|
||||
NetworkTableEntry& entry, unsigned int mask,
|
||||
std::function<void(const TopicNotification&)> listener)
|
||||
: m_handle{AddTopicListener(entry.GetHandle(), mask, listener)} {}
|
||||
|
||||
@@ -59,6 +59,14 @@ inline TopicListener::~TopicListener() {
|
||||
}
|
||||
}
|
||||
|
||||
inline bool TopicListener::WaitForQueue(double timeout) {
|
||||
if (m_handle != 0) {
|
||||
return nt::WaitForTopicListenerQueue(m_handle, timeout);
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
inline TopicListenerPoller::TopicListenerPoller(NetworkTableInstance inst)
|
||||
: m_handle(nt::CreateTopicListenerPoller(inst.GetHandle())) {}
|
||||
|
||||
@@ -89,17 +97,17 @@ inline NT_TopicListener TopicListenerPoller::Add(Topic topic,
|
||||
return nt::AddPolledTopicListener(m_handle, topic.GetHandle(), mask);
|
||||
}
|
||||
|
||||
inline NT_TopicListener TopicListenerPoller::Add(const Subscriber& subscriber,
|
||||
inline NT_TopicListener TopicListenerPoller::Add(Subscriber& subscriber,
|
||||
unsigned int mask) {
|
||||
return nt::AddPolledTopicListener(m_handle, subscriber.GetHandle(), mask);
|
||||
}
|
||||
|
||||
inline NT_TopicListener TopicListenerPoller::Add(
|
||||
const MultiSubscriber& subscriber, unsigned int mask) {
|
||||
inline NT_TopicListener TopicListenerPoller::Add(MultiSubscriber& subscriber,
|
||||
unsigned int mask) {
|
||||
return nt::AddPolledTopicListener(m_handle, subscriber.GetHandle(), mask);
|
||||
}
|
||||
|
||||
inline NT_TopicListener TopicListenerPoller::Add(const NetworkTableEntry& entry,
|
||||
inline NT_TopicListener TopicListenerPoller::Add(NetworkTableEntry& entry,
|
||||
unsigned int mask) {
|
||||
return nt::AddPolledTopicListener(m_handle, entry.GetHandle(), mask);
|
||||
}
|
||||
|
||||
@@ -57,23 +57,25 @@ class ValueListener final {
|
||||
ValueListener() = default;
|
||||
|
||||
/**
|
||||
* Create a listener for value changes on a subscriber.
|
||||
* Create a listener for value changes on a subscriber. This does NOT keep the
|
||||
* subscriber active.
|
||||
*
|
||||
* @param subscriber Subscriber
|
||||
* @param mask Bitmask of ValueListenerFlags values
|
||||
* @param listener Listener function
|
||||
*/
|
||||
ValueListener(const Subscriber& subscriber, unsigned int mask,
|
||||
ValueListener(Subscriber& subscriber, unsigned int mask,
|
||||
std::function<void(const ValueNotification&)> listener);
|
||||
|
||||
/**
|
||||
* Create a listener for value changes on a subscriber.
|
||||
* Create a listener for value changes on a subscriber. This does NOT keep the
|
||||
* subscriber active.
|
||||
*
|
||||
* @param subscriber Subscriber
|
||||
* @param mask Bitmask of ValueListenerFlags values
|
||||
* @param listener Listener function
|
||||
*/
|
||||
ValueListener(const MultiSubscriber& subscriber, unsigned int mask,
|
||||
ValueListener(MultiSubscriber& subscriber, unsigned int mask,
|
||||
std::function<void(const ValueNotification&)> listener);
|
||||
|
||||
/**
|
||||
@@ -83,17 +85,7 @@ class ValueListener final {
|
||||
* @param mask Bitmask of ValueListenerFlags values
|
||||
* @param listener Listener function
|
||||
*/
|
||||
ValueListener(const NetworkTableEntry& entry, unsigned int mask,
|
||||
std::function<void(const ValueNotification&)> listener);
|
||||
|
||||
/**
|
||||
* Create a listener for value changes on a subscriber/entry handle.
|
||||
*
|
||||
* @param subentry Subscriber/entry handle
|
||||
* @param mask Bitmask of ValueListenerFlags values
|
||||
* @param listener Listener function
|
||||
*/
|
||||
ValueListener(NT_Handle subentry, unsigned int mask,
|
||||
ValueListener(NetworkTableEntry& entry, unsigned int mask,
|
||||
std::function<void(const ValueNotification&)> listener);
|
||||
|
||||
ValueListener(const ValueListener&) = delete;
|
||||
@@ -111,6 +103,18 @@ class ValueListener final {
|
||||
*/
|
||||
NT_ValueListener GetHandle() const { return m_handle; }
|
||||
|
||||
/**
|
||||
* Wait for the value listener queue to be empty. This is primarily useful for
|
||||
* deterministic testing. This blocks until either the value listener queue is
|
||||
* empty (e.g. there are no more events that need to be passed along to
|
||||
* callbacks or poll queues) or the timeout expires.
|
||||
*
|
||||
* @param timeout timeout, in seconds. Set to 0 for non-blocking behavior, or
|
||||
* a negative value to block indefinitely
|
||||
* @return False if timed out, otherwise true.
|
||||
*/
|
||||
bool WaitForQueue(double timeout);
|
||||
|
||||
private:
|
||||
NT_ValueListener m_handle{0};
|
||||
};
|
||||
@@ -147,22 +151,24 @@ class ValueListenerPoller final {
|
||||
NT_ValueListenerPoller GetHandle() const { return m_handle; }
|
||||
|
||||
/**
|
||||
* Start listening to value changes on a subscriber.
|
||||
* Start listening to value changes on a subscriber. This does NOT keep the
|
||||
* subscriber active.
|
||||
*
|
||||
* @param subscriber Subscriber
|
||||
* @param mask Bitmask of ValueListenerFlags values
|
||||
* @return Listener handle
|
||||
*/
|
||||
NT_ValueListener Add(const Subscriber& subscriber, unsigned int mask);
|
||||
NT_ValueListener Add(Subscriber& subscriber, unsigned int mask);
|
||||
|
||||
/**
|
||||
* Start listening to value changes on a subscriber.
|
||||
* Start listening to value changes on a subscriber. This does NOT keep the
|
||||
* subscriber active.
|
||||
*
|
||||
* @param subscriber Subscriber
|
||||
* @param mask Bitmask of ValueListenerFlags values
|
||||
* @return Listener handle
|
||||
*/
|
||||
NT_ValueListener Add(const MultiSubscriber& subscriber, unsigned int mask);
|
||||
NT_ValueListener Add(MultiSubscriber& subscriber, unsigned int mask);
|
||||
|
||||
/**
|
||||
* Start listening to value changes on an entry.
|
||||
@@ -171,16 +177,7 @@ class ValueListenerPoller final {
|
||||
* @param mask Bitmask of ValueListenerFlags values
|
||||
* @return Listener handle
|
||||
*/
|
||||
NT_ValueListener Add(const NetworkTableEntry& entry, unsigned int mask);
|
||||
|
||||
/**
|
||||
* Start listening to value changes on a subscriber/entry handle.
|
||||
*
|
||||
* @param subentry Subscriber/entry handle
|
||||
* @param mask Bitmask of ValueListenerFlags values
|
||||
* @return Listener handle
|
||||
*/
|
||||
NT_ValueListener Add(NT_Handle subentry, unsigned int mask);
|
||||
NT_ValueListener Add(NetworkTableEntry& entry, unsigned int mask);
|
||||
|
||||
/**
|
||||
* Remove a listener.
|
||||
|
||||
@@ -17,25 +17,20 @@
|
||||
namespace nt {
|
||||
|
||||
inline ValueListener::ValueListener(
|
||||
const Subscriber& subscriber, unsigned int mask,
|
||||
Subscriber& subscriber, unsigned int mask,
|
||||
std::function<void(const ValueNotification&)> listener)
|
||||
: m_handle{AddValueListener(subscriber.GetHandle(), mask, listener)} {}
|
||||
|
||||
inline ValueListener::ValueListener(
|
||||
const MultiSubscriber& subscriber, unsigned int mask,
|
||||
MultiSubscriber& subscriber, unsigned int mask,
|
||||
std::function<void(const ValueNotification&)> listener)
|
||||
: m_handle{AddValueListener(subscriber.GetHandle(), mask, listener)} {}
|
||||
|
||||
inline ValueListener::ValueListener(
|
||||
const NetworkTableEntry& entry, unsigned int mask,
|
||||
NetworkTableEntry& entry, unsigned int mask,
|
||||
std::function<void(const ValueNotification&)> listener)
|
||||
: m_handle{AddValueListener(entry.GetHandle(), mask, listener)} {}
|
||||
|
||||
inline ValueListener::ValueListener(
|
||||
NT_Handle subentry, unsigned int mask,
|
||||
std::function<void(const ValueNotification&)> listener)
|
||||
: m_handle{AddValueListener(subentry, mask, listener)} {}
|
||||
|
||||
inline ValueListener::ValueListener(ValueListener&& rhs)
|
||||
: m_handle(rhs.m_handle) {
|
||||
rhs.m_handle = 0;
|
||||
@@ -52,6 +47,14 @@ inline ValueListener::~ValueListener() {
|
||||
}
|
||||
}
|
||||
|
||||
inline bool ValueListener::WaitForQueue(double timeout) {
|
||||
if (m_handle != 0) {
|
||||
return nt::WaitForValueListenerQueue(m_handle, timeout);
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
inline ValueListenerPoller::ValueListenerPoller(NetworkTableInstance inst)
|
||||
: m_handle(nt::CreateValueListenerPoller(inst.GetHandle())) {}
|
||||
|
||||
@@ -72,24 +75,19 @@ inline ValueListenerPoller::~ValueListenerPoller() {
|
||||
}
|
||||
}
|
||||
|
||||
inline NT_ValueListener ValueListenerPoller::Add(const Subscriber& subscriber,
|
||||
inline NT_ValueListener ValueListenerPoller::Add(Subscriber& subscriber,
|
||||
unsigned int mask) {
|
||||
return Add(subscriber.GetHandle(), mask);
|
||||
return nt::AddPolledValueListener(m_handle, subscriber.GetHandle(), mask);
|
||||
}
|
||||
|
||||
inline NT_ValueListener ValueListenerPoller::Add(
|
||||
const MultiSubscriber& subscriber, unsigned int mask) {
|
||||
return Add(subscriber.GetHandle(), mask);
|
||||
inline NT_ValueListener ValueListenerPoller::Add(MultiSubscriber& subscriber,
|
||||
unsigned int mask) {
|
||||
return nt::AddPolledValueListener(m_handle, subscriber.GetHandle(), mask);
|
||||
}
|
||||
|
||||
inline NT_ValueListener ValueListenerPoller::Add(const NetworkTableEntry& entry,
|
||||
inline NT_ValueListener ValueListenerPoller::Add(NetworkTableEntry& entry,
|
||||
unsigned int mask) {
|
||||
return Add(entry.GetHandle(), mask);
|
||||
}
|
||||
|
||||
inline NT_ValueListener ValueListenerPoller::Add(NT_Handle subentry,
|
||||
unsigned int mask) {
|
||||
return nt::AddPolledValueListener(m_handle, subentry, mask);
|
||||
return nt::AddPolledValueListener(m_handle, entry.GetHandle(), mask);
|
||||
}
|
||||
|
||||
inline void ValueListenerPoller::Remove(NT_ValueListener listener) {
|
||||
|
||||
@@ -862,6 +862,19 @@ NT_TopicListener NT_AddTopicListenerSingle(NT_Topic topic, unsigned int mask,
|
||||
void* data,
|
||||
NT_TopicListenerCallback callback);
|
||||
|
||||
/**
|
||||
* Wait for the topic listener queue to be empty. This is primarily useful
|
||||
* for deterministic testing. This blocks until either the topic listener
|
||||
* queue is empty (e.g. there are no more events that need to be passed along to
|
||||
* callbacks or poll queues) or the timeout expires.
|
||||
*
|
||||
* @param handle handle
|
||||
* @param timeout timeout, in seconds. Set to 0 for non-blocking behavior, or a
|
||||
* negative value to block indefinitely
|
||||
* @return False if timed out, otherwise true.
|
||||
*/
|
||||
NT_Bool NT_WaitForTopicListenerQueue(NT_Handle handle, double timeout);
|
||||
|
||||
/**
|
||||
* Creates a topic listener poller.
|
||||
*
|
||||
@@ -971,6 +984,19 @@ NT_ValueListener NT_AddValueListener(NT_Handle subentry, unsigned int mask,
|
||||
void* data,
|
||||
NT_ValueListenerCallback callback);
|
||||
|
||||
/**
|
||||
* Wait for the value listener queue to be empty. This is primarily useful
|
||||
* for deterministic testing. This blocks until either the value listener
|
||||
* queue is empty (e.g. there are no more events that need to be passed along to
|
||||
* callbacks or poll queues) or the timeout expires.
|
||||
*
|
||||
* @param handle handle
|
||||
* @param timeout timeout, in seconds. Set to 0 for non-blocking behavior, or a
|
||||
* negative value to block indefinitely
|
||||
* @return False if timed out, otherwise true.
|
||||
*/
|
||||
NT_Bool NT_WaitForValueListenerQueue(NT_Handle handle, double timeout);
|
||||
|
||||
/**
|
||||
* Create a value listener poller.
|
||||
*
|
||||
@@ -1050,8 +1076,21 @@ typedef void (*NT_ConnectionListenerCallback)(
|
||||
* @return Listener handle
|
||||
*/
|
||||
NT_ConnectionListener NT_AddConnectionListener(
|
||||
NT_Inst inst, void* data, NT_ConnectionListenerCallback callback,
|
||||
NT_Bool immediate_notify);
|
||||
NT_Inst inst, NT_Bool immediate_notify, void* data,
|
||||
NT_ConnectionListenerCallback callback);
|
||||
|
||||
/**
|
||||
* Wait for the connection listener queue to be empty. This is primarily useful
|
||||
* for deterministic testing. This blocks until either the connection listener
|
||||
* queue is empty (e.g. there are no more events that need to be passed along to
|
||||
* callbacks or poll queues) or the timeout expires.
|
||||
*
|
||||
* @param handle handle
|
||||
* @param timeout timeout, in seconds. Set to 0 for non-blocking behavior, or a
|
||||
* negative value to block indefinitely
|
||||
* @return False if timed out, otherwise true.
|
||||
*/
|
||||
NT_Bool NT_WaitForConnectionListenerQueue(NT_Handle handle, double timeout);
|
||||
|
||||
/**
|
||||
* Create a connection listener poller.
|
||||
|
||||
@@ -799,6 +799,19 @@ NT_TopicListener AddTopicListener(
|
||||
NT_Handle handle, unsigned int mask,
|
||||
std::function<void(const TopicNotification&)> callback);
|
||||
|
||||
/**
|
||||
* Wait for the topic listener queue to be empty. This is primarily useful
|
||||
* for deterministic testing. This blocks until either the topic listener
|
||||
* queue is empty (e.g. there are no more events that need to be passed along to
|
||||
* callbacks or poll queues) or the timeout expires.
|
||||
*
|
||||
* @param handle handle
|
||||
* @param timeout timeout, in seconds. Set to 0 for non-blocking behavior, or a
|
||||
* negative value to block indefinitely
|
||||
* @return False if timed out, otherwise true.
|
||||
*/
|
||||
bool WaitForTopicListenerQueue(NT_Handle handle, double timeout);
|
||||
|
||||
/**
|
||||
* Creates a topic listener poller.
|
||||
*
|
||||
@@ -880,6 +893,19 @@ NT_ValueListener AddValueListener(
|
||||
NT_Handle subentry, unsigned int mask,
|
||||
std::function<void(const ValueNotification&)> callback);
|
||||
|
||||
/**
|
||||
* Wait for the value listener queue to be empty. This is primarily useful
|
||||
* for deterministic testing. This blocks until either the value listener
|
||||
* queue is empty (e.g. there are no more events that need to be passed along to
|
||||
* callbacks or poll queues) or the timeout expires.
|
||||
*
|
||||
* @param handle handle
|
||||
* @param timeout timeout, in seconds. Set to 0 for non-blocking behavior, or a
|
||||
* negative value to block indefinitely
|
||||
* @return False if timed out, otherwise true.
|
||||
*/
|
||||
bool WaitForValueListenerQueue(NT_Handle handle, double timeout);
|
||||
|
||||
/**
|
||||
* Create a value listener poller.
|
||||
*
|
||||
@@ -945,9 +971,21 @@ void RemoveValueListener(NT_ValueListener listener);
|
||||
* @return Listener handle
|
||||
*/
|
||||
NT_ConnectionListener AddConnectionListener(
|
||||
NT_Inst inst,
|
||||
std::function<void(const ConnectionNotification& event)> callback,
|
||||
bool immediate_notify);
|
||||
NT_Inst inst, bool immediate_notify,
|
||||
std::function<void(const ConnectionNotification& event)> callback);
|
||||
|
||||
/**
|
||||
* Wait for the connection listener queue to be empty. This is primarily useful
|
||||
* for deterministic testing. This blocks until either the connection listener
|
||||
* queue is empty (e.g. there are no more events that need to be passed along to
|
||||
* callbacks or poll queues) or the timeout expires.
|
||||
*
|
||||
* @param handle handle
|
||||
* @param timeout timeout, in seconds. Set to 0 for non-blocking behavior, or a
|
||||
* negative value to block indefinitely
|
||||
* @return False if timed out, otherwise true.
|
||||
*/
|
||||
bool WaitForConnectionListenerQueue(NT_Handle handle, double timeout);
|
||||
|
||||
/**
|
||||
* Create a connection listener poller.
|
||||
|
||||
Reference in New Issue
Block a user