[ntcore] Pass pub/sub options as a unified PubSubOptions struct (#4794)

In Java, PubSubOption is still used for passing options, but this
simplifies C++ use substantially, as it allows aggregate construction.
This commit is contained in:
Peter Johnson
2022-12-12 19:28:15 -08:00
committed by GitHub
parent f66a667321
commit a865f48e96
53 changed files with 695 additions and 623 deletions

View File

@@ -30,7 +30,7 @@ class MultiSubscriber final {
*/
MultiSubscriber(NetworkTableInstance inst,
std::span<const std::string_view> prefixes,
std::span<const PubSubOption> options = {});
const PubSubOptions& options = kDefaultPubSubOptions);
MultiSubscriber(const MultiSubscriber&) = delete;
MultiSubscriber& operator=(const MultiSubscriber&) = delete;

View File

@@ -10,7 +10,7 @@ namespace nt {
inline MultiSubscriber::MultiSubscriber(
NetworkTableInstance inst, std::span<const std::string_view> prefixes,
std::span<const PubSubOption> options)
const PubSubOptions& options)
: m_handle{::nt::SubscribeMultiple(inst.GetHandle(), prefixes, options)} {}
inline MultiSubscriber::MultiSubscriber(MultiSubscriber&& rhs)

View File

@@ -6,7 +6,6 @@
#include <stdint.h>
#include <span>
#include <string>
#include <string_view>
#include <utility>
@@ -171,7 +170,7 @@ class Topic {
* @return subscriber
*/
[[nodiscard]] GenericSubscriber GenericSubscribe(
std::span<const PubSubOption> options = {});
const PubSubOptions& options = kDefaultPubSubOptions);
/**
* Create a new subscriber to the topic.
@@ -188,7 +187,8 @@ class Topic {
* @return subscriber
*/
[[nodiscard]] GenericSubscriber GenericSubscribe(
std::string_view typeString, std::span<const PubSubOption> options = {});
std::string_view typeString,
const PubSubOptions& options = kDefaultPubSubOptions);
/**
* Create a new publisher to the topic.
@@ -207,7 +207,8 @@ class Topic {
* @return publisher
*/
[[nodiscard]] GenericPublisher GenericPublish(
std::string_view typeString, std::span<const PubSubOption> options = {});
std::string_view typeString,
const PubSubOptions& options = kDefaultPubSubOptions);
/**
* Create a new publisher to the topic, with type string and initial
@@ -229,7 +230,7 @@ class Topic {
*/
[[nodiscard]] GenericPublisher GenericPublishEx(
std::string_view typeString, const wpi::json& properties,
std::span<const PubSubOption> options = {});
const PubSubOptions& options = kDefaultPubSubOptions);
/**
* Create a new generic entry for the topic.
@@ -250,7 +251,7 @@ class Topic {
* @return entry
*/
[[nodiscard]] GenericEntry GetGenericEntry(
std::span<const PubSubOption> options = {});
const PubSubOptions& options = kDefaultPubSubOptions);
/**
* Create a new generic entry for the topic.
@@ -272,7 +273,8 @@ class Topic {
* @return entry
*/
[[nodiscard]] GenericEntry GetGenericEntry(
std::string_view typeString, std::span<const PubSubOption> options = {});
std::string_view typeString,
const PubSubOptions& options = kDefaultPubSubOptions);
/**
* Equality operator. Returns true if both instances refer to the same

View File

@@ -11,6 +11,7 @@
#include <vector>
#include "networktables/Topic.h"
#include "ntcore_cpp.h"
namespace wpi {
class json;
@@ -295,7 +296,8 @@ class UnitTopic final : public Topic {
* @return subscriber
*/
[[nodiscard]] SubscriberType Subscribe(
ParamType defaultValue, std::span<const PubSubOption> options = {});
ParamType defaultValue,
const PubSubOptions& options = kDefaultPubSubOptions);
/**
* Create a new subscriber to the topic, with specific type string.
@@ -315,7 +317,7 @@ class UnitTopic final : public Topic {
*/
[[nodiscard]] SubscriberType SubscribeEx(
std::string_view typeString, ParamType defaultValue,
std::span<const PubSubOption> options = {});
const PubSubOptions& options = kDefaultPubSubOptions);
/**
* Create a new publisher to the topic.
@@ -333,7 +335,7 @@ class UnitTopic final : public Topic {
* @return publisher
*/
[[nodiscard]] PublisherType Publish(
std::span<const PubSubOption> options = {});
const PubSubOptions& options = kDefaultPubSubOptions);
/**
* Create a new publisher to the topic, with type string and initial
@@ -355,7 +357,7 @@ class UnitTopic final : public Topic {
*/
[[nodiscard]] PublisherType PublishEx(
std::string_view typeString, const wpi::json& properties,
std::span<const PubSubOption> options = {});
const PubSubOptions& options = kDefaultPubSubOptions);
/**
* Create a new entry for the topic.
@@ -377,8 +379,9 @@ class UnitTopic final : public Topic {
* @param options publish and/or subscribe options
* @return entry
*/
[[nodiscard]] EntryType GetEntry(ParamType defaultValue,
std::span<const PubSubOption> options = {});
[[nodiscard]] EntryType GetEntry(
ParamType defaultValue,
const PubSubOptions& options = kDefaultPubSubOptions);
/**
* Create a new entry for the topic, with specific type string.
@@ -403,7 +406,7 @@ class UnitTopic final : public Topic {
*/
[[nodiscard]] EntryType GetEntryEx(
std::string_view typeString, ParamType defaultValue,
std::span<const PubSubOption> options = {});
const PubSubOptions& options = kDefaultPubSubOptions);
};
} // namespace nt

View File

@@ -93,31 +93,29 @@ inline bool UnitTopic<T>::IsMatchingUnit() const {
}
template <typename T>
inline UnitSubscriber<T> UnitTopic<T>::Subscribe(
T defaultValue, std::span<const PubSubOption> options) {
inline UnitSubscriber<T> UnitTopic<T>::Subscribe(T defaultValue,
const PubSubOptions& options) {
return UnitSubscriber<T>{
::nt::Subscribe(m_handle, NT_DOUBLE, "double", options), defaultValue};
}
template <typename T>
inline UnitSubscriber<T> UnitTopic<T>::SubscribeEx(
std::string_view typeString, T defaultValue,
std::span<const PubSubOption> options) {
std::string_view typeString, T defaultValue, const PubSubOptions& options) {
return UnitSubscriber<T>{
::nt::Subscribe(m_handle, NT_DOUBLE, typeString, options), defaultValue};
}
template <typename T>
inline UnitPublisher<T> UnitTopic<T>::Publish(
std::span<const PubSubOption> options) {
inline UnitPublisher<T> UnitTopic<T>::Publish(const PubSubOptions& options) {
return UnitPublisher<T>{::nt::PublishEx(m_handle, NT_DOUBLE, "double",
{{"unit", T{}.name()}}, options)};
}
template <typename T>
inline UnitPublisher<T> UnitTopic<T>::PublishEx(
std::string_view typeString, const wpi::json& properties,
std::span<const PubSubOption> options) {
inline UnitPublisher<T> UnitTopic<T>::PublishEx(std::string_view typeString,
const wpi::json& properties,
const PubSubOptions& options) {
wpi::json props = properties;
props["unit"] = T{}.name();
return UnitPublisher<T>{
@@ -125,16 +123,16 @@ inline UnitPublisher<T> UnitTopic<T>::PublishEx(
}
template <typename T>
inline UnitEntry<T> UnitTopic<T>::GetEntry(
T defaultValue, std::span<const PubSubOption> options) {
inline UnitEntry<T> UnitTopic<T>::GetEntry(T defaultValue,
const PubSubOptions& options) {
return UnitEntry<T>{::nt::GetEntry(m_handle, NT_DOUBLE, "double", options),
defaultValue};
}
template <typename T>
inline UnitEntry<T> UnitTopic<T>::GetEntryEx(
std::string_view typeString, T defaultValue,
std::span<const PubSubOption> options) {
inline UnitEntry<T> UnitTopic<T>::GetEntryEx(std::string_view typeString,
T defaultValue,
const PubSubOptions& options) {
return UnitEntry<T>{::nt::GetEntry(m_handle, NT_DOUBLE, typeString, options),
defaultValue};
}

View File

@@ -88,18 +88,6 @@ enum NT_NetworkMode {
NT_NET_MODE_LOCAL = 0x10, /* running in local-only mode */
};
/** Pub/sub option types */
enum NT_PubSubOptionType {
NT_PUBSUB_PERIODIC = 1, /* period between transmissions */
NT_PUBSUB_SENDALL, /* all value changes are sent */
NT_PUBSUB_TOPICSONLY, /* only send topic changes, no value changes */
NT_PUBSUB_POLLSTORAGE, /* polling storage for subscription */
NT_PUBSUB_KEEPDUPLICATES, /* preserve duplicate values */
NT_PUBSUB_LOCALREMOTE, /* local, remote, or any value changes */
NT_PUBSUB_EXCLUDEPUB, /* exclude value changes made by given publisher */
NT_PUBSUB_EXCLUDESELF, /* exclude value changes made by entry publisher */
};
/** Event notification flags. */
enum NT_EventFlags {
NT_EVENT_NONE = 0,
@@ -283,18 +271,74 @@ struct NT_Event {
} data;
};
/** NetworkTables publish/subscribe option. */
struct NT_PubSubOption {
/** Option type. */
enum NT_PubSubOptionType type;
/** NetworkTables publish/subscribe options. */
struct NT_PubSubOptions {
/**
* Structure size. Must be set to sizeof(NT_PubSubOptions).
*/
unsigned int structSize;
/**
* Option value. 1 (true) or 0 (false) for immediate and logging options,
* time between updates, in milliseconds, for periodic option. For
* local/remote option, 1=local only, 2=remote only, 0 or 3=both local and
* remote. For exclude publisher, publisher handle.
* Polling storage size for a subscription. Specifies the maximum number of
* updates NetworkTables should store between calls to the subscriber's
* ReadQueue() function. If zero, defaults to 1 if sendAll is false, 20 if
* sendAll is true.
*/
unsigned int value;
unsigned int pollStorage;
/**
* How frequently changes will be sent over the network, in seconds.
* NetworkTables may send more frequently than this (e.g. use a combined
* minimum period for all values) or apply a restricted range to this value.
* The default is 100 ms.
*/
double periodic;
/**
* For subscriptions, if non-zero, value updates for ReadQueue() are not
* queued for this publisher.
*/
NT_Publisher excludePublisher;
/**
* Send all value changes over the network.
*/
NT_Bool sendAll;
/**
* For subscriptions, don't ask for value changes (only topic announcements).
*/
NT_Bool topicsOnly;
/**
* Perform prefix match on subscriber topic names. Is ignored/overridden by
* Subscribe() functions; only present in struct for the purposes of getting
* information about subscriptions.
*/
NT_Bool prefixMatch;
/**
* Preserve duplicate value changes (rather than ignoring them).
*/
NT_Bool keepDuplicates;
/**
* For subscriptions, if remote value updates should not be queued for
* ReadQueue(). See also disableLocal.
*/
NT_Bool disableRemote;
/**
* For subscriptions, if local value updates should not be queued for
* ReadQueue(). See also disableRemote.
*/
NT_Bool disableLocal;
/**
* For entries, don't queue (for ReadQueue) value updates for the entry's
* internal publisher.
*/
NT_Bool excludeSelf;
};
/**
@@ -682,13 +726,11 @@ NT_Bool NT_SetTopicProperties(NT_Topic topic, const char* properties);
* @param type expected type
* @param typeStr expected type string
* @param options subscription options
* @param options_len number of elements in options array
* @return Subscriber handle
*/
NT_Subscriber NT_Subscribe(NT_Topic topic, enum NT_Type type,
const char* typeStr,
const struct NT_PubSubOption* options,
size_t options_len);
const struct NT_PubSubOptions* options);
/**
* Stops subscriber.
@@ -704,12 +746,10 @@ void NT_Unsubscribe(NT_Subscriber sub);
* @param type type
* @param typeStr type string
* @param options publish options
* @param options_len number of elements in options array
* @return Publisher handle
*/
NT_Publisher NT_Publish(NT_Topic topic, enum NT_Type type, const char* typeStr,
const struct NT_PubSubOption* options,
size_t options_len);
const struct NT_PubSubOptions* options);
/**
* Creates a new publisher to a topic.
@@ -719,13 +759,11 @@ NT_Publisher NT_Publish(NT_Topic topic, enum NT_Type type, const char* typeStr,
* @param typeStr type string
* @param properties initial properties (JSON object)
* @param options publish options
* @param options_len number of elements in options array
* @return Publisher handle
*/
NT_Publisher NT_PublishEx(NT_Topic topic, enum NT_Type type,
const char* typeStr, const char* properties,
const struct NT_PubSubOption* options,
size_t options_len);
const struct NT_PubSubOptions* options);
/**
* Stops publisher.
@@ -741,12 +779,10 @@ void NT_Unpublish(NT_Handle pubentry);
* @param type type
* @param typeStr type string
* @param options publish options
* @param options_len number of elements in options array
* @return Entry handle
*/
NT_Entry NT_GetEntryEx(NT_Topic topic, enum NT_Type type, const char* typeStr,
const struct NT_PubSubOption* options,
size_t options_len);
const struct NT_PubSubOptions* options);
/**
* Stops entry subscriber/publisher.
@@ -786,14 +822,12 @@ NT_Topic NT_GetTopicFromHandle(NT_Handle pubsubentry);
* @param prefixes topic name prefixes
* @param prefixes_len number of elements in prefixes array
* @param options subscriber options
* @param options_len number of elements in options array
* @return subscriber handle
*/
NT_MultiSubscriber NT_SubscribeMultiple(NT_Inst inst,
const struct NT_String* prefixes,
size_t prefixes_len,
const struct NT_PubSubOption* options,
size_t options_len);
const struct NT_PubSubOptions* options);
/**
* Unsubscribes a multi-subscriber.

View File

@@ -259,131 +259,86 @@ class Event {
LogMessage* GetLogMessage() { return std::get_if<nt::LogMessage>(&data); }
};
/** NetworkTables publish/subscribe option. */
class PubSubOption {
public:
constexpr PubSubOption(NT_PubSubOptionType type, unsigned int value)
: type{type}, value{value} {}
/** NetworkTables publish/subscribe options. */
struct PubSubOptions {
/**
* Default value of periodic.
*/
static constexpr double kDefaultPeriodic = 0.1;
/**
* How frequently changes will be sent over the network. NetworkTables may
* send more frequently than this (e.g. use a combined minimum period for all
* values) or apply a restricted range to this value. The default if
* unspecified (and the immediate flag is false) is 100 ms. This option and
* the immediate option override each other.
*
* @param time time between updates, in seconds
* @return option
* Structure size. Must be set to sizeof(PubSubOptions).
*/
static constexpr PubSubOption Periodic(double time) {
return PubSubOption{NT_PUBSUB_PERIODIC,
static_cast<unsigned int>(time * 1000)};
}
unsigned int structSize = sizeof(PubSubOptions);
/**
* If enabled, sends all value changes over the network even if only sent
* periodically. This option defaults to disabled.
*
* @param enabled True to enable, false to disable
* @return option
* Polling storage size for a subscription. Specifies the maximum number of
* updates NetworkTables should store between calls to the subscriber's
* ReadQueue() function. If zero, defaults to 1 if sendAll is false, 20 if
* sendAll is true.
*/
static constexpr PubSubOption SendAll(bool enabled) {
return PubSubOption{NT_PUBSUB_SENDALL, enabled ? 1u : 0u};
}
unsigned int pollStorage = 0;
/**
* If enabled, no value changes are sent over the network. This option
* defaults to disabled.
*
* @param enabled True to enable, false to disable
* @return option
* How frequently changes will be sent over the network, in seconds.
* NetworkTables may send more frequently than this (e.g. use a combined
* minimum period for all values) or apply a restricted range to this value.
* The default is 100 ms.
*/
static constexpr PubSubOption TopicsOnly(bool enabled) {
return PubSubOption{NT_PUBSUB_TOPICSONLY, enabled ? 1u : 0u};
}
double periodic = kDefaultPeriodic;
/**
* If enabled, preserves duplicate value changes (rather than ignoring them).
* This option defaults to disabled.
*
* @param enabled True to enable, false to disable
* @return option
* For subscriptions, if non-zero, value updates for ReadQueue() are not
* queued for this publisher.
*/
static constexpr PubSubOption KeepDuplicates(bool enabled) {
return PubSubOption{NT_PUBSUB_KEEPDUPLICATES, enabled ? 1u : 0u};
}
NT_Publisher excludePublisher = 0;
/**
* Polling storage for subscription. Specifies the maximum number of updates
* NetworkTables should store between calls to the subscriber's ReadQueue()
* function. Defaults to 1 if SendAll is false, 20 if SendAll is true.
*
* @param depth number of entries to save for polling.
* @return option
* Send all value changes over the network.
*/
static constexpr PubSubOption PollStorage(unsigned int depth) {
return PubSubOption{NT_PUBSUB_POLLSTORAGE, depth};
}
bool sendAll = false;
/**
* If only local value updates should be queued for ReadQueue(). See also
* RemoteOnly() and AllUpdates(). Default is AllUpdates. Only has an effect on
* subscriptions.
*
* @return option
* For subscriptions, don't ask for value changes (only topic announcements).
*/
static constexpr PubSubOption LocalOnly() {
return PubSubOption{NT_PUBSUB_LOCALREMOTE, 1u};
}
bool topicsOnly = false;
/**
* If only remote value updates should be queued for ReadQueue(). See also
* LocalOnly() and AllUpdates(). Default is AllUpdates. Only has an effect on
* subscriptions.
*
* @return option
* Preserve duplicate value changes (rather than ignoring them).
*/
static constexpr PubSubOption RemoteOnly() {
return PubSubOption{NT_PUBSUB_LOCALREMOTE, 2u};
}
bool keepDuplicates = false;
/**
* If both local and remote value updates should be queued for ReadQueue().
* See also LocalOnly() and RemoteOnly(). Default is AllUpdates. Only has an
* effect on subscriptions.
*
* @return option
* Perform prefix match on subscriber topic names. Is ignored/overridden by
* Subscribe() functions; only present in struct for the purposes of getting
* information about subscriptions.
*/
static constexpr PubSubOption AllUpdates() {
return PubSubOption{NT_PUBSUB_LOCALREMOTE, 0u};
}
bool prefixMatch = false;
/**
* Don't queue value updates for the given publisher. Only has an effect on
* subscriptions. Only one exclusion may be set.
*
* @param publisher publisher handle
* @return option
* For subscriptions, if remote value updates should not be queued for
* ReadQueue(). See also disableLocal.
*/
static constexpr PubSubOption ExcludePublisher(NT_Publisher publisher) {
return PubSubOption{NT_PUBSUB_EXCLUDEPUB, publisher};
}
bool disableRemote = false;
/**
* Don't queue value updates for the internal publisher for an entry. Only has
* an effect on entries.
*
* @param enabled True to enable, false to disable
* @return option
* For subscriptions, if local value updates should not be queued for
* ReadQueue(). See also disableRemote.
*/
static constexpr PubSubOption ExcludeSelf(bool enabled) {
return PubSubOption{NT_PUBSUB_EXCLUDESELF, enabled ? 1u : 0u};
}
bool disableLocal = false;
NT_PubSubOptionType type;
unsigned int value;
/**
* For entries, don't queue (for ReadQueue) value updates for the entry's
* internal publisher.
*/
bool excludeSelf = false;
};
/**
* Default publish/subscribe options.
*/
constexpr PubSubOptions kDefaultPubSubOptions;
/**
* @defgroup ntcore_instance_func Instance Functions
* @{
@@ -750,7 +705,7 @@ bool SetTopicProperties(NT_Topic topic, const wpi::json& update);
* @return Subscriber handle
*/
NT_Subscriber Subscribe(NT_Topic topic, NT_Type type, std::string_view typeStr,
std::span<const PubSubOption> options = {});
const PubSubOptions& options = kDefaultPubSubOptions);
/**
* Stops subscriber.
@@ -769,7 +724,7 @@ void Unsubscribe(NT_Subscriber sub);
* @return Publisher handle
*/
NT_Publisher Publish(NT_Topic topic, NT_Type type, std::string_view typeStr,
std::span<const PubSubOption> options = {});
const PubSubOptions& options = kDefaultPubSubOptions);
/**
* Creates a new publisher to a topic.
@@ -783,7 +738,7 @@ NT_Publisher Publish(NT_Topic topic, NT_Type type, std::string_view typeStr,
*/
NT_Publisher PublishEx(NT_Topic topic, NT_Type type, std::string_view typeStr,
const wpi::json& properties,
std::span<const PubSubOption> options = {});
const PubSubOptions& options = kDefaultPubSubOptions);
/**
* Stops publisher.
@@ -802,7 +757,7 @@ void Unpublish(NT_Handle pubentry);
* @return Entry handle
*/
NT_Entry GetEntry(NT_Topic topic, NT_Type type, std::string_view typeStr,
std::span<const PubSubOption> options = {});
const PubSubOptions& options = kDefaultPubSubOptions);
/**
* Stops entry subscriber/publisher.
@@ -845,7 +800,7 @@ NT_Topic GetTopicFromHandle(NT_Handle pubsubentry);
*/
NT_MultiSubscriber SubscribeMultiple(
NT_Inst inst, std::span<const std::string_view> prefixes,
std::span<const PubSubOption> options = {});
const PubSubOptions& options = kDefaultPubSubOptions);
/**
* Unsubscribes a multi-subscriber.