diff --git a/glass/src/libnt/native/cpp/NetworkTables.cpp b/glass/src/libnt/native/cpp/NetworkTables.cpp index 90bc306aaf..a21e3dd341 100644 --- a/glass/src/libnt/native/cpp/NetworkTables.cpp +++ b/glass/src/libnt/native/cpp/NetworkTables.cpp @@ -600,138 +600,42 @@ NetworkTablesModel::Entry* NetworkTablesModel::AddEntry(NT_Topic topic) { return entry.get(); } +NetworkTablesModel::Client::Subscriber::Subscriber( + nt::meta::ClientSubscriber&& oth) + : ClientSubscriber{std::move(oth)}, + topicsStr{StringArrayToString(topics)} {} + void NetworkTablesModel::Client::UpdatePublishers( std::span data) { - mpack_reader_t r; - mpack_reader_init_data(&r, data); - uint32_t numPub = mpack_expect_array_max(&r, 1000); - std::vector newPublishers; - newPublishers.reserve(numPub); - for (uint32_t i = 0; i < numPub; ++i) { - ClientPublisher pub; - uint32_t numMapElem = mpack_expect_map(&r); - for (uint32_t j = 0; j < numMapElem; ++j) { - std::string key; - mpack_expect_str(&r, &key); - if (key == "uid") { - pub.uid = mpack_expect_i64(&r); - } else if (key == "topic") { - mpack_expect_str(&r, &pub.topic); - } else { - mpack_discard(&r); - } - } - mpack_done_map(&r); - newPublishers.emplace_back(std::move(pub)); - } - mpack_done_array(&r); - if (mpack_reader_destroy(&r) == mpack_ok) { - publishers = std::move(newPublishers); + if (auto pubs = nt::meta::DecodeClientPublishers(data)) { + publishers = std::move(*pubs); } else { fmt::print(stderr, "Failed to update publishers\n"); } } -static void DecodeSubscriberOptions( - mpack_reader_t& r, NetworkTablesModel::SubscriberOptions* options) { - *options = NetworkTablesModel::SubscriberOptions{}; - uint32_t numMapElem = mpack_expect_map(&r); - for (uint32_t j = 0; j < numMapElem; ++j) { - std::string key; - mpack_expect_str(&r, &key); - if (key == "topicsonly") { - options->topicsOnly = mpack_expect_bool(&r); - } else if (key == "all") { - options->sendAll = mpack_expect_bool(&r); - } else if (key == "periodic") { - options->periodic = mpack_expect_float(&r); - } else if (key == "prefix") { - options->prefixMatch = mpack_expect_bool(&r); - } else { - // TODO: Save other options - mpack_discard(&r); - } - } - mpack_done_map(&r); -} - void NetworkTablesModel::Client::UpdateSubscribers( std::span data) { - mpack_reader_t r; - mpack_reader_init_data(&r, data); - uint32_t numSub = mpack_expect_array_max(&r, 1000); - std::vector newSubscribers; - newSubscribers.reserve(numSub); - for (uint32_t i = 0; i < numSub; ++i) { - ClientSubscriber sub; - uint32_t numMapElem = mpack_expect_map(&r); - for (uint32_t j = 0; j < numMapElem; ++j) { - std::string key; - mpack_expect_str(&r, &key); - if (key == "uid") { - sub.uid = mpack_expect_i64(&r); - } else if (key == "topics") { - uint32_t numPrefix = mpack_expect_array_max(&r, 100); - sub.topics.reserve(numPrefix); - for (uint32_t k = 0; k < numPrefix; ++k) { - std::string val; - if (mpack_expect_str(&r, &val) == mpack_ok) { - sub.topics.emplace_back(std::move(val)); - } - } - sub.topicsStr = StringArrayToString(sub.topics); - mpack_done_array(&r); - } else if (key == "options") { - DecodeSubscriberOptions(r, &sub.options); - } else { - mpack_discard(&r); - } + if (auto subs = nt::meta::DecodeClientSubscribers(data)) { + subscribers.clear(); + subscribers.reserve(subs->size()); + for (auto&& sub : *subs) { + subscribers.emplace_back(std::move(sub)); } - mpack_done_map(&r); - newSubscribers.emplace_back(std::move(sub)); - } - mpack_done_array(&r); - if (mpack_reader_destroy(&r) == mpack_ok) { - subscribers = std::move(newSubscribers); } else { fmt::print(stderr, "Failed to update subscribers\n"); } } void NetworkTablesModel::UpdateClients(std::span data) { - mpack_reader_t r; - mpack_reader_init_data(&r, data); - uint32_t numClients = mpack_expect_array_max(&r, 100); - std::vector clientsArr; - clientsArr.reserve(numClients); - for (uint32_t i = 0; i < numClients; ++i) { - Client client; - uint32_t numMapElem = mpack_expect_map(&r); - for (uint32_t j = 0; j < numMapElem; ++j) { - std::string key; - mpack_expect_str(&r, &key); - if (key == "id") { - mpack_expect_str(&r, &client.id); - } else if (key == "conn") { - mpack_expect_str(&r, &client.conn); - } else if (key == "ver") { - uint16_t val = mpack_expect_u16(&r); - client.version = fmt::format("{}.{}", val >> 8, val & 0xff); - } else { - mpack_discard(&r); - } - } - mpack_done_map(&r); - clientsArr.emplace_back(std::move(client)); - } - mpack_done_array(&r); - if (mpack_reader_destroy(&r) != mpack_ok) { + auto clientsArr = nt::meta::DecodeClients(data); + if (!clientsArr) { return; } // we need to create a new map so deletions are reflected std::map> newClients; - for (auto&& client : clientsArr) { + for (auto&& client : *clientsArr) { auto& newClient = newClients[client.id]; newClient = std::move(client); auto it = m_clients.find(newClient.id); @@ -1499,8 +1403,8 @@ void glass::DisplayNetworkTablesInfo(NetworkTablesModel* model) { if (CollapsingHeader(client.second.id.c_str())) { PushID(client.second.id.c_str()); ImGui::Indent(); - ImGui::Text("%s (version %s)", client.second.conn.c_str(), - client.second.version.c_str()); + ImGui::Text("%s (version %u.%u)", client.second.conn.c_str(), + client.second.version >> 8, client.second.version & 0xff); DisplayClient(client.second); ImGui::Unindent(); PopID(); diff --git a/glass/src/libnt/native/include/glass/networktables/NetworkTables.h b/glass/src/libnt/native/include/glass/networktables/NetworkTables.h index 35444f65c1..a9a1b9bf3d 100644 --- a/glass/src/libnt/native/include/glass/networktables/NetworkTables.h +++ b/glass/src/libnt/native/include/glass/networktables/NetworkTables.h @@ -28,25 +28,6 @@ class DataSource; class NetworkTablesModel : public Model { public: - struct SubscriberOptions { - float periodic = 0.1f; - bool topicsOnly = false; - bool sendAll = false; - bool prefixMatch = false; - // std::string otherStr; - }; - - struct TopicPublisher { - std::string client; - uint64_t pubuid; - }; - - struct TopicSubscriber { - std::string client; - uint64_t subuid; - SubscriberOptions options; - }; - struct EntryValueTreeNode; struct ValueSource { @@ -103,8 +84,8 @@ class NetworkTablesModel : public Model { /** Publisher (created when the value changes). */ NT_Publisher publisher{0}; - std::vector publishers; - std::vector subscribers; + std::vector publishers; + std::vector subscribers; }; struct TreeNode { @@ -126,24 +107,18 @@ class NetworkTablesModel : public Model { std::vector children; }; - struct ClientPublisher { - int64_t uid = -1; - std::string topic; - }; + struct Client : public nt::meta::Client { + Client() = default; + /*implicit*/ Client(nt::meta::Client&& oth) // NOLINT + : nt::meta::Client{std::move(oth)} {} - struct ClientSubscriber { - int64_t uid = -1; - std::vector topics; - std::string topicsStr; - SubscriberOptions options; - }; + struct Subscriber : public nt::meta::ClientSubscriber { + /*implicit*/ Subscriber(nt::meta::ClientSubscriber&& oth); // NOLINT + std::string topicsStr; + }; - struct Client { - std::string id; - std::string conn; - std::string version; - std::vector publishers; - std::vector subscribers; + std::vector publishers; + std::vector subscribers; void UpdatePublishers(std::span data); void UpdateSubscribers(std::span data); diff --git a/ntcore/src/main/native/cpp/ntcore_meta.cpp b/ntcore/src/main/native/cpp/ntcore_meta.cpp new file mode 100644 index 0000000000..05cb4b7b3d --- /dev/null +++ b/ntcore/src/main/native/cpp/ntcore_meta.cpp @@ -0,0 +1,210 @@ +// Copyright (c) FIRST and other WPILib contributors. +// Open Source Software; you can modify and/or share it under the terms of +// the WPILib BSD license file in the root directory of this project. + +#include +#include +#include + +#include "ntcore_cpp.h" + +using namespace mpack; + +using namespace nt::meta; + +static SubscriberOptions DecodeSubscriberOptions(mpack_reader_t& r) { + SubscriberOptions options; + uint32_t numMapElem = mpack_expect_map(&r); + for (uint32_t j = 0; j < numMapElem; ++j) { + std::string key; + mpack_expect_str(&r, &key); + if (key == "topicsonly") { + options.topicsOnly = mpack_expect_bool(&r); + } else if (key == "all") { + options.sendAll = mpack_expect_bool(&r); + } else if (key == "periodic") { + options.periodic = mpack_expect_float(&r); + } else if (key == "prefix") { + options.prefixMatch = mpack_expect_bool(&r); + } else { + // TODO: Save other options + mpack_discard(&r); + } + } + mpack_done_map(&r); + return options; +} + +std::optional> nt::meta::DecodeClientPublishers( + std::span data) { + mpack_reader_t r; + mpack_reader_init_data(&r, data); + uint32_t numPub = mpack_expect_array_max(&r, 1000); + std::vector publishers; + publishers.reserve(numPub); + for (uint32_t i = 0; i < numPub; ++i) { + ClientPublisher pub; + uint32_t numMapElem = mpack_expect_map(&r); + for (uint32_t j = 0; j < numMapElem; ++j) { + std::string key; + mpack_expect_str(&r, &key); + if (key == "uid") { + pub.uid = mpack_expect_i64(&r); + } else if (key == "topic") { + mpack_expect_str(&r, &pub.topic); + } else { + mpack_discard(&r); + } + } + mpack_done_map(&r); + publishers.emplace_back(std::move(pub)); + } + mpack_done_array(&r); + if (mpack_reader_destroy(&r) == mpack_ok) { + return {std::move(publishers)}; + } else { + return {}; + } +} + +std::optional> nt::meta::DecodeClientSubscribers( + std::span data) { + mpack_reader_t r; + mpack_reader_init_data(&r, data); + uint32_t numSub = mpack_expect_array_max(&r, 1000); + std::vector subscribers; + subscribers.reserve(numSub); + for (uint32_t i = 0; i < numSub; ++i) { + ClientSubscriber sub; + uint32_t numMapElem = mpack_expect_map(&r); + for (uint32_t j = 0; j < numMapElem; ++j) { + std::string key; + mpack_expect_str(&r, &key); + if (key == "uid") { + sub.uid = mpack_expect_i64(&r); + } else if (key == "topics") { + uint32_t numPrefix = mpack_expect_array_max(&r, 100); + sub.topics.reserve(numPrefix); + for (uint32_t k = 0; k < numPrefix; ++k) { + std::string val; + if (mpack_expect_str(&r, &val) == mpack_ok) { + sub.topics.emplace_back(std::move(val)); + } + } + mpack_done_array(&r); + } else if (key == "options") { + sub.options = DecodeSubscriberOptions(r); + } else { + mpack_discard(&r); + } + } + mpack_done_map(&r); + subscribers.emplace_back(std::move(sub)); + } + mpack_done_array(&r); + if (mpack_reader_destroy(&r) == mpack_ok) { + return {std::move(subscribers)}; + } else { + return {}; + } +} + +std::optional> nt::meta::DecodeTopicPublishers( + std::span data) { + mpack_reader_t r; + mpack_reader_init_data(&r, data); + uint32_t numPub = mpack_expect_array_max(&r, 1000); + std::vector publishers; + publishers.reserve(numPub); + for (uint32_t i = 0; i < numPub; ++i) { + TopicPublisher pub; + uint32_t numMapElem = mpack_expect_map(&r); + for (uint32_t j = 0; j < numMapElem; ++j) { + std::string key; + mpack_expect_str(&r, &key); + if (key == "pubuid") { + pub.pubuid = mpack_expect_i64(&r); + } else if (key == "client") { + mpack_expect_str(&r, &pub.client); + } else { + mpack_discard(&r); + } + } + mpack_done_map(&r); + publishers.emplace_back(std::move(pub)); + } + mpack_done_array(&r); + if (mpack_reader_destroy(&r) == mpack_ok) { + return {std::move(publishers)}; + } else { + return {}; + } +} + +std::optional> nt::meta::DecodeTopicSubscribers( + std::span data) { + mpack_reader_t r; + mpack_reader_init_data(&r, data); + uint32_t numSub = mpack_expect_array_max(&r, 1000); + std::vector subscribers; + subscribers.reserve(numSub); + for (uint32_t i = 0; i < numSub; ++i) { + TopicSubscriber sub; + uint32_t numMapElem = mpack_expect_map(&r); + for (uint32_t j = 0; j < numMapElem; ++j) { + std::string key; + mpack_expect_str(&r, &key); + if (key == "subuid") { + sub.subuid = mpack_expect_i64(&r); + } else if (key == "client") { + mpack_expect_str(&r, &sub.client); + } else if (key == "options") { + sub.options = DecodeSubscriberOptions(r); + } else { + mpack_discard(&r); + } + } + mpack_done_map(&r); + subscribers.emplace_back(std::move(sub)); + } + mpack_done_array(&r); + if (mpack_reader_destroy(&r) == mpack_ok) { + return {std::move(subscribers)}; + } else { + return {}; + } +} + +std::optional> nt::meta::DecodeClients( + std::span data) { + mpack_reader_t r; + mpack_reader_init_data(&r, data); + uint32_t numClients = mpack_expect_array_max(&r, 100); + std::vector clients; + clients.reserve(numClients); + for (uint32_t i = 0; i < numClients; ++i) { + Client client; + uint32_t numMapElem = mpack_expect_map(&r); + for (uint32_t j = 0; j < numMapElem; ++j) { + std::string key; + mpack_expect_str(&r, &key); + if (key == "id") { + mpack_expect_str(&r, &client.id); + } else if (key == "conn") { + mpack_expect_str(&r, &client.conn); + } else if (key == "ver") { + client.version = mpack_expect_u16(&r); + } else { + mpack_discard(&r); + } + } + mpack_done_map(&r); + clients.emplace_back(std::move(client)); + } + mpack_done_array(&r); + if (mpack_reader_destroy(&r) == mpack_ok) { + return {std::move(clients)}; + } else { + return {}; + } +} diff --git a/ntcore/src/main/native/cpp/ntcore_meta_c.cpp b/ntcore/src/main/native/cpp/ntcore_meta_c.cpp new file mode 100644 index 0000000000..889254e1b7 --- /dev/null +++ b/ntcore/src/main/native/cpp/ntcore_meta_c.cpp @@ -0,0 +1,138 @@ +// Copyright (c) FIRST and other WPILib contributors. +// Open Source Software; you can modify and/or share it under the terms of +// the WPILib BSD license file in the root directory of this project. + +#include +#include + +#include "Value_internal.h" +#include "ntcore_cpp.h" + +using namespace nt; +using namespace nt::meta; + +static void ConvertToC(const SubscriberOptions& in, + NT_Meta_SubscriberOptions* out) { + out->periodic = in.periodic; + out->topicsOnly = in.topicsOnly; + out->sendAll = in.sendAll; + out->prefixMatch = in.prefixMatch; +} + +static void ConvertToC(const TopicPublisher& in, NT_Meta_TopicPublisher* out) { + ConvertToC(in.client, &out->client); + out->pubuid = in.pubuid; +} + +static void ConvertToC(const TopicSubscriber& in, + NT_Meta_TopicSubscriber* out) { + ConvertToC(in.client, &out->client); + out->subuid = in.subuid; + ConvertToC(in.options, &out->options); +} + +static void ConvertToC(const ClientPublisher& in, + NT_Meta_ClientPublisher* out) { + out->uid = in.uid; + ConvertToC(in.topic, &out->topic); +} + +static void ConvertToC(const ClientSubscriber& in, + NT_Meta_ClientSubscriber* out) { + out->uid = in.uid; + out->topics = ConvertToC(in.topics, &out->topicsCount); + ConvertToC(in.options, &out->options); +} + +static void ConvertToC(const Client& in, NT_Meta_Client* out) { + ConvertToC(in.id, &out->id); + ConvertToC(in.conn, &out->conn); + out->version = in.version; +} + +template +static O* ConvertToC(const std::optional>& in, size_t* out_len) { + if (in) { + if (O* rv = ConvertToC(*in, out_len)) { + return rv; + } else { + return static_cast(wpi::safe_malloc(0)); // return non-NULL + } + } else { + *out_len = 0; + return nullptr; + } +} + +extern "C" { + +struct NT_Meta_TopicPublisher* NT_Meta_DecodeTopicPublishers( + const uint8_t* data, size_t size, size_t* count) { + return ConvertToC(DecodeTopicPublishers({data, size}), + count); +} + +struct NT_Meta_TopicSubscriber* NT_Meta_DecodeTopicSubscribers( + const uint8_t* data, size_t size, size_t* count) { + return ConvertToC( + DecodeTopicSubscribers({data, size}), count); +} + +struct NT_Meta_ClientPublisher* NT_Meta_DecodeClientPublishers( + const uint8_t* data, size_t size, size_t* count) { + return ConvertToC( + DecodeClientPublishers({data, size}), count); +} + +struct NT_Meta_ClientSubscriber* NT_Meta_DecodeClientSubscribers( + const uint8_t* data, size_t size, size_t* count) { + return ConvertToC( + DecodeClientSubscribers({data, size}), count); +} + +struct NT_Meta_Client* NT_Meta_DecodeClients(const uint8_t* data, size_t size, + size_t* count) { + return ConvertToC(DecodeClients({data, size}), count); +} + +void NT_Meta_FreeTopicPublishers(struct NT_Meta_TopicPublisher* arr, + size_t count) { + for (size_t i = 0; i < count; ++i) { + std::free(arr[i].client.str); + } + std::free(arr); +} + +void NT_Meta_FreeTopicSubscribers(struct NT_Meta_TopicSubscriber* arr, + size_t count) { + for (size_t i = 0; i < count; ++i) { + std::free(arr[i].client.str); + } + std::free(arr); +} + +void NT_Meta_FreeClientPublishers(struct NT_Meta_ClientPublisher* arr, + size_t count) { + for (size_t i = 0; i < count; ++i) { + std::free(arr[i].topic.str); + } + std::free(arr); +} + +void NT_Meta_FreeClientSubscribers(struct NT_Meta_ClientSubscriber* arr, + size_t count) { + for (size_t i = 0; i < count; ++i) { + NT_FreeStringArray(arr[i].topics, arr[i].topicsCount); + } + std::free(arr); +} + +void NT_Meta_FreeClients(struct NT_Meta_Client* arr, size_t count) { + for (size_t i = 0; i < count; ++i) { + std::free(arr[i].id.str); + std::free(arr[i].conn.str); + } + std::free(arr); +} + +} // extern "C" diff --git a/ntcore/src/main/native/include/ntcore_c.h b/ntcore/src/main/native/include/ntcore_c.h index 74f9666163..e9e9f81d5d 100644 --- a/ntcore/src/main/native/include/ntcore_c.h +++ b/ntcore/src/main/native/include/ntcore_c.h @@ -1702,6 +1702,170 @@ struct NT_String* NT_GetValueStringArray(const struct NT_Value* value, /** @} */ /** @} */ +/** + * @defgroup ntcore_c_meta_api ntcore C meta-topic API + * + * Meta-topic decoders for C. + * + * @{ + */ + +/** + * Subscriber options. Different from PubSubOptions in this reflects only + * options that are sent over the network. + */ +struct NT_Meta_SubscriberOptions { + double periodic; + NT_Bool topicsOnly; + NT_Bool sendAll; + NT_Bool prefixMatch; +}; + +/** + * Topic publisher (as published via `$pub$`). + */ +struct NT_Meta_TopicPublisher { + struct NT_String client; + uint64_t pubuid; +}; + +/** + * Topic subscriber (as published via `$sub$`). + */ +struct NT_Meta_TopicSubscriber { + struct NT_String client; + uint64_t subuid; + struct NT_Meta_SubscriberOptions options; +}; + +/** + * Client publisher (as published via `$clientpub$` or `$serverpub`). + */ +struct NT_Meta_ClientPublisher { + int64_t uid; + struct NT_String topic; +}; + +/** + * Client subscriber (as published via `$clientsub$` or `$serversub`). + */ +struct NT_Meta_ClientSubscriber { + int64_t uid; + size_t topicsCount; + struct NT_String* topics; + struct NT_Meta_SubscriberOptions options; +}; + +/** + * Client (as published via `$clients`). + */ +struct NT_Meta_Client { + struct NT_String id; + struct NT_String conn; + uint16_t version; +}; + +/** + * Decodes `$pub$` meta-topic data. + * + * @param data data contents + * @param size size of data contents + * @param count number of elements in returned array (output) + * @return Array of TopicPublishers, or NULL on decoding error. + */ +struct NT_Meta_TopicPublisher* NT_Meta_DecodeTopicPublishers( + const uint8_t* data, size_t size, size_t* count); + +/** + * Decodes `$sub$` meta-topic data. + * + * @param data data contents + * @param size size of data contents + * @param count number of elements in returned array (output) + * @return Array of TopicSubscribers, or NULL on decoding error. + */ +struct NT_Meta_TopicSubscriber* NT_Meta_DecodeTopicSubscribers( + const uint8_t* data, size_t size, size_t* count); + +/** + * Decodes `$clientpub$` meta-topic data. + * + * @param data data contents + * @param size size of data contents + * @param count number of elements in returned array (output) + * @return Array of ClientPublishers, or NULL on decoding error. + */ +struct NT_Meta_ClientPublisher* NT_Meta_DecodeClientPublishers( + const uint8_t* data, size_t size, size_t* count); + +/** + * Decodes `$clientsub$` meta-topic data. + * + * @param data data contents + * @param size size of data contents + * @param count number of elements in returned array (output) + * @return Array of ClientSubscribers, or NULL on decoding error. + */ +struct NT_Meta_ClientSubscriber* NT_Meta_DecodeClientSubscribers( + const uint8_t* data, size_t size, size_t* count); + +/** + * Decodes `$clients` meta-topic data. + * + * @param data data contents + * @param size size of data contents + * @param count number of elements in returned array (output) + * @return Array of Clients, or NULL on decoding error. + */ +struct NT_Meta_Client* NT_Meta_DecodeClients(const uint8_t* data, size_t size, + size_t* count); + +/** + * Frees an array of NT_Meta_TopicPublisher. + * + * @param arr pointer to the array to free + * @param count size of the array to free + */ +void NT_Meta_FreeTopicPublishers(struct NT_Meta_TopicPublisher* arr, + size_t count); + +/** + * Frees an array of NT_Meta_TopicSubscriber. + * + * @param arr pointer to the array to free + * @param count size of the array to free + */ +void NT_Meta_FreeTopicSubscribers(struct NT_Meta_TopicSubscriber* arr, + size_t count); + +/** + * Frees an array of NT_Meta_ClientPublisher. + * + * @param arr pointer to the array to free + * @param count size of the array to free + */ +void NT_Meta_FreeClientPublishers(struct NT_Meta_ClientPublisher* arr, + size_t count); + +/** + * Frees an array of NT_Meta_ClientSubscriber. + * + * @param arr pointer to the array to free + * @param count size of the array to free + */ +void NT_Meta_FreeClientSubscribers(struct NT_Meta_ClientSubscriber* arr, + size_t count); + +/** + * Frees an array of NT_Meta_Client. + * + * @param arr pointer to the array to free + * @param count size of the array to free + */ +void NT_Meta_FreeClients(struct NT_Meta_Client* arr, size_t count); + +/** @} */ + #ifdef __cplusplus } // extern "C" #endif diff --git a/ntcore/src/main/native/include/ntcore_cpp.h b/ntcore/src/main/native/include/ntcore_cpp.h index 40cfe5c2ac..cbb541bbd2 100644 --- a/ntcore/src/main/native/include/ntcore_cpp.h +++ b/ntcore/src/main/native/include/ntcore_cpp.h @@ -1294,4 +1294,119 @@ NT_Listener AddPolledLogger(NT_ListenerPoller poller, unsigned int min_level, /** @} */ /** @} */ +/** + * NetworkTables meta-topic decoding functions. + */ +namespace meta { + +/** + * @defgroup ntcore_cpp_meta_api ntcore C++ meta-topic API + * + * Meta-topic decoders for C++. + * + * @{ + */ + +/** + * Subscriber options. Different from PubSubOptions in this reflects only + * options that are sent over the network. + */ +struct SubscriberOptions { + double periodic = 0.1; + bool topicsOnly = false; + bool sendAll = false; + bool prefixMatch = false; + // std::string otherStr; +}; + +/** + * Topic publisher (as published via `$pub$`). + */ +struct TopicPublisher { + std::string client; + uint64_t pubuid = 0; +}; + +/** + * Topic subscriber (as published via `$sub$`). + */ +struct TopicSubscriber { + std::string client; + uint64_t subuid = 0; + SubscriberOptions options; +}; + +/** + * Client publisher (as published via `$clientpub$` or `$serverpub`). + */ +struct ClientPublisher { + int64_t uid = -1; + std::string topic; +}; + +/** + * Client subscriber (as published via `$clientsub$` or `$serversub`). + */ +struct ClientSubscriber { + int64_t uid = -1; + std::vector topics; + SubscriberOptions options; +}; + +/** + * Client (as published via `$clients`). + */ +struct Client { + std::string id; + std::string conn; + uint16_t version = 0; +}; + +/** + * Decodes `$pub$` meta-topic data. + * + * @param data data contents + * @return Vector of TopicPublishers, or empty optional on decoding error. + */ +std::optional> DecodeTopicPublishers( + std::span data); + +/** + * Decodes `$sub$` meta-topic data. + * + * @param data data contents + * @return Vector of TopicSubscribers, or empty optional on decoding error. + */ +std::optional> DecodeTopicSubscribers( + std::span data); + +/** + * Decodes `$clientpub$` meta-topic data. + * + * @param data data contents + * @return Vector of ClientPublishers, or empty optional on decoding error. + */ +std::optional> DecodeClientPublishers( + std::span data); + +/** + * Decodes `$clientsub$` meta-topic data. + * + * @param data data contents + * @return Vector of ClientSubscribers, or empty optional on decoding error. + */ +std::optional> DecodeClientSubscribers( + std::span data); + +/** + * Decodes `$clients` meta-topic data. + * + * @param data data contents + * @return Vector of Clients, or empty optional on decoding error. + */ +std::optional> DecodeClients(std::span data); + +/** @} */ + +} // namespace meta } // namespace nt diff --git a/ntcoreffi/src/main/native/symbols.txt b/ntcoreffi/src/main/native/symbols.txt index ddcf1143ef..4f6ebeb974 100644 --- a/ntcoreffi/src/main/native/symbols.txt +++ b/ntcoreffi/src/main/native/symbols.txt @@ -131,6 +131,16 @@ NT_GetValueType NT_InitString NT_InitValue NT_IsConnected +NT_Meta_DecodeClientPublishers +NT_Meta_DecodeClientSubscribers +NT_Meta_DecodeClients +NT_Meta_DecodeTopicPublishers +NT_Meta_DecodeTopicSubscribers +NT_Meta_FreeClientPublishers +NT_Meta_FreeClientSubscribers +NT_Meta_FreeClients +NT_Meta_FreeTopicPublishers +NT_Meta_FreeTopicSubscribers NT_Now NT_Publish NT_PublishEx