[ntcore] NetworkTables 4 (#3217)

This commit is contained in:
Peter Johnson
2022-10-08 10:01:31 -07:00
committed by GitHub
parent 90cfa00115
commit 77301b126c
380 changed files with 34573 additions and 22095 deletions

View File

@@ -4,6 +4,7 @@
#include "frc/smartdashboard/Field2d.h"
#include <networktables/DoubleArrayTopic.h>
#include <networktables/NTSendableBuilder.h>
#include <wpi/sendable/SendableRegistry.h>
@@ -57,7 +58,7 @@ FieldObject2d* Field2d::GetObject(std::string_view name) {
std::make_unique<FieldObject2d>(name, FieldObject2d::private_init{}));
auto obj = m_objects.back().get();
if (m_table) {
obj->m_entry = m_table->GetEntry(obj->m_name);
obj->m_entry = m_table->GetDoubleArrayTopic(obj->m_name).GetEntry({});
}
return obj;
}
@@ -74,7 +75,7 @@ void Field2d::InitSendable(nt::NTSendableBuilder& builder) {
m_table = builder.GetTable();
for (auto&& obj : m_objects) {
std::scoped_lock lock2(obj->m_mutex);
obj->m_entry = m_table->GetEntry(obj->m_name);
obj->m_entry = m_table->GetDoubleArrayTopic(obj->m_name).GetEntry({});
obj->UpdateEntry(true);
}
}

View File

@@ -6,9 +6,6 @@
#include <vector>
#include <wpi/Endian.h>
#include <wpi/MathExtras.h>
#include "frc/trajectory/Trajectory.h"
using namespace frc;
@@ -83,41 +80,17 @@ void FieldObject2d::UpdateEntry(bool setDefault) {
if (!m_entry) {
return;
}
if (m_poses.size() < (255 / 3)) {
wpi::SmallVector<double, 9> arr;
for (auto&& pose : m_poses) {
auto& translation = pose.Translation();
arr.push_back(translation.X().value());
arr.push_back(translation.Y().value());
arr.push_back(pose.Rotation().Degrees().value());
}
if (setDefault) {
m_entry.SetDefaultDoubleArray(arr);
} else {
m_entry.ForceSetDoubleArray(arr);
}
wpi::SmallVector<double, 9> arr;
for (auto&& pose : m_poses) {
auto& translation = pose.Translation();
arr.push_back(translation.X().value());
arr.push_back(translation.Y().value());
arr.push_back(pose.Rotation().Degrees().value());
}
if (setDefault) {
m_entry.SetDefault(arr);
} else {
// send as raw array of doubles if too big for NT array
std::vector<char> arr;
arr.resize(m_poses.size() * 3 * 8);
char* p = arr.data();
for (auto&& pose : m_poses) {
auto& translation = pose.Translation();
wpi::support::endian::write64be(
p, wpi::DoubleToBits(translation.X().value()));
p += 8;
wpi::support::endian::write64be(
p, wpi::DoubleToBits(translation.Y().value()));
p += 8;
wpi::support::endian::write64be(
p, wpi::DoubleToBits(pose.Rotation().Degrees().value()));
p += 8;
}
if (setDefault) {
m_entry.SetDefaultRaw({arr.data(), arr.size()});
} else {
m_entry.ForceSetRaw({arr.data(), arr.size()});
}
m_entry.Set(arr);
}
}
@@ -125,46 +98,15 @@ void FieldObject2d::UpdateFromEntry() const {
if (!m_entry) {
return;
}
auto val = m_entry.GetValue();
if (!val) {
auto arr = m_entry.Get();
auto size = arr.size();
if ((size % 3) != 0) {
return;
}
if (val->IsDoubleArray()) {
auto arr = val->GetDoubleArray();
auto size = arr.size();
if ((size % 3) != 0) {
return;
}
m_poses.resize(size / 3);
for (size_t i = 0; i < size / 3; ++i) {
m_poses[i] =
Pose2d{units::meter_t{arr[i * 3 + 0]}, units::meter_t{arr[i * 3 + 1]},
units::degree_t{arr[i * 3 + 2]}};
}
} else if (val->IsRaw()) {
// treat it simply as an array of doubles
std::string_view data = val->GetRaw();
// must be triples of doubles
auto size = data.size();
if ((size % (3 * 8)) != 0) {
return;
}
m_poses.resize(size / (3 * 8));
const char* p = data.data();
for (size_t i = 0; i < size / (3 * 8); ++i) {
double x = wpi::BitsToDouble(
wpi::support::endian::readNext<uint64_t, wpi::support::big,
wpi::support::unaligned>(p));
double y = wpi::BitsToDouble(
wpi::support::endian::readNext<uint64_t, wpi::support::big,
wpi::support::unaligned>(p));
double rot = wpi::BitsToDouble(
wpi::support::endian::readNext<uint64_t, wpi::support::big,
wpi::support::unaligned>(p));
m_poses[i] =
Pose2d{units::meter_t{x}, units::meter_t{y}, units::degree_t{rot}};
}
m_poses.resize(size / 3);
for (size_t i = 0; i < size / 3; ++i) {
m_poses[i] =
Pose2d{units::meter_t{arr[i * 3 + 0]}, units::meter_t{arr[i * 3 + 1]},
units::degree_t{arr[i * 3 + 2]}};
}
}

View File

@@ -5,13 +5,14 @@
#include "frc/smartdashboard/Mechanism2d.h"
#include <cstdio>
#include <string_view>
#include <networktables/NTSendableBuilder.h>
using namespace frc;
static constexpr char kBackgroundColor[] = "backgroundColor";
static constexpr char kDims[] = "dims";
static constexpr std::string_view kBackgroundColor = "backgroundColor";
static constexpr std::string_view kDims = "dims";
Mechanism2d::Mechanism2d(double width, double height,
const Color8Bit& backgroundColor)
@@ -35,8 +36,8 @@ MechanismRoot2d* Mechanism2d::GetRoot(std::string_view name, double x,
void Mechanism2d::SetBackgroundColor(const Color8Bit& color) {
m_color = color.HexString();
if (m_table) {
m_table->GetEntry(kBackgroundColor).SetString(m_color);
if (m_colorPub) {
m_colorPub.Set(m_color);
}
}
@@ -45,8 +46,10 @@ void Mechanism2d::InitSendable(nt::NTSendableBuilder& builder) {
std::scoped_lock lock(m_mutex);
m_table = builder.GetTable();
m_table->GetEntry(kDims).SetDoubleArray({m_width, m_height});
m_table->GetEntry(kBackgroundColor).SetString(m_color);
m_dimsPub = m_table->GetDoubleArrayTopic(kDims).Publish();
m_dimsPub.Set({{m_width, m_height}});
m_colorPub = m_table->GetStringTopic(kBackgroundColor).Publish();
m_colorPub.Set(m_color);
for (const auto& entry : m_roots) {
const auto& root = entry.getValue().get();
root->Update(m_table->GetSubTable(entry.getKey()));

View File

@@ -21,38 +21,48 @@ MechanismLigament2d::MechanismLigament2d(std::string_view name, double length,
void MechanismLigament2d::UpdateEntries(
std::shared_ptr<nt::NetworkTable> table) {
table->GetEntry(".type").SetString("line");
m_typePub = table->GetStringTopic(".type").Publish();
m_typePub.Set("line");
m_colorEntry = table->GetEntry("color");
m_angleEntry = table->GetEntry("angle");
m_weightEntry = table->GetEntry("weight");
m_lengthEntry = table->GetEntry("length");
Flush();
m_colorEntry = table->GetStringTopic("color").GetEntry("");
m_colorEntry.Set(m_color);
m_angleEntry = table->GetDoubleTopic("angle").GetEntry(0.0);
m_angleEntry.Set(m_angle);
m_weightEntry = table->GetDoubleTopic("weight").GetEntry(0.0);
m_weightEntry.Set(m_weight);
m_lengthEntry = table->GetDoubleTopic("length").GetEntry(0.0);
m_lengthEntry.Set(m_length);
}
void MechanismLigament2d::SetColor(const Color8Bit& color) {
std::scoped_lock lock(m_mutex);
std::snprintf(m_color, sizeof(m_color), "#%02X%02X%02X", color.red,
color.green, color.blue);
Flush();
if (m_colorEntry) {
m_colorEntry.Set(m_color);
}
}
void MechanismLigament2d::SetAngle(units::degree_t angle) {
std::scoped_lock lock(m_mutex);
m_angle = angle.value();
Flush();
if (m_angleEntry) {
m_angleEntry.Set(m_angle);
}
}
void MechanismLigament2d::SetLineWeight(double lineWidth) {
std::scoped_lock lock(m_mutex);
m_weight = lineWidth;
Flush();
if (m_weightEntry) {
m_weightEntry.Set(m_weight);
}
}
Color8Bit MechanismLigament2d::GetColor() {
std::scoped_lock lock(m_mutex);
if (m_colorEntry) {
auto color = m_colorEntry.GetString("");
auto color = m_colorEntry.Get();
std::strncpy(m_color, color.c_str(), sizeof(m_color));
m_color[sizeof(m_color) - 1] = '\0';
}
@@ -64,7 +74,7 @@ Color8Bit MechanismLigament2d::GetColor() {
double MechanismLigament2d::GetAngle() {
std::scoped_lock lock(m_mutex);
if (m_angleEntry) {
m_angle = m_angleEntry.GetDouble(0.0);
m_angle = m_angleEntry.Get();
}
return m_angle;
}
@@ -72,7 +82,7 @@ double MechanismLigament2d::GetAngle() {
double MechanismLigament2d::GetLength() {
std::scoped_lock lock(m_mutex);
if (m_lengthEntry) {
m_length = m_lengthEntry.GetDouble(0.0);
m_length = m_lengthEntry.Get();
}
return m_length;
}
@@ -80,7 +90,7 @@ double MechanismLigament2d::GetLength() {
double MechanismLigament2d::GetLineWeight() {
std::scoped_lock lock(m_mutex);
if (m_weightEntry) {
m_weight = m_weightEntry.GetDouble(0.0);
m_weight = m_weightEntry.Get();
}
return m_weight;
}
@@ -88,16 +98,7 @@ double MechanismLigament2d::GetLineWeight() {
void MechanismLigament2d::SetLength(double length) {
std::scoped_lock lock(m_mutex);
m_length = length;
Flush();
}
#define SAFE_WRITE(data, Type) \
if (m_##data##Entry) { \
m_##data##Entry.Set##Type(m_##data); \
if (m_lengthEntry) {
m_lengthEntry.Set(length);
}
void MechanismLigament2d::Flush() {
SAFE_WRITE(color, String)
SAFE_WRITE(angle, Double)
SAFE_WRITE(length, Double)
SAFE_WRITE(weight, Double)
}

View File

@@ -20,16 +20,16 @@ void MechanismRoot2d::SetPosition(double x, double y) {
}
void MechanismRoot2d::UpdateEntries(std::shared_ptr<nt::NetworkTable> table) {
m_xEntry = table->GetEntry("x");
m_yEntry = table->GetEntry("y");
m_xPub = table->GetDoubleTopic("x").Publish();
m_yPub = table->GetDoubleTopic("y").Publish();
Flush();
}
inline void MechanismRoot2d::Flush() {
if (m_xEntry) {
m_xEntry.SetDouble(m_x);
if (m_xPub) {
m_xPub.Set(m_x);
}
if (m_yEntry) {
m_yEntry.SetDouble(m_y);
if (m_yPub) {
m_yPub.Set(m_y);
}
}

View File

@@ -4,16 +4,37 @@
#include "frc/smartdashboard/SendableBuilderImpl.h"
#include <networktables/BooleanArrayTopic.h>
#include <networktables/BooleanTopic.h>
#include <networktables/DoubleArrayTopic.h>
#include <networktables/DoubleTopic.h>
#include <networktables/FloatArrayTopic.h>
#include <networktables/FloatTopic.h>
#include <networktables/IntegerArrayTopic.h>
#include <networktables/IntegerTopic.h>
#include <networktables/RawTopic.h>
#include <networktables/StringArrayTopic.h>
#include <ntcore_cpp.h>
#include <wpi/SmallString.h>
#include <wpi/SmallVector.h>
#include "frc/smartdashboard/SmartDashboard.h"
using namespace frc;
template <typename Topic>
void SendableBuilderImpl::PropertyImpl<Topic>::Update(bool controllable,
int64_t time) {
if (controllable && sub && updateLocal) {
updateLocal(sub);
} else if (pub && updateNetwork) {
updateNetwork(pub, time);
}
}
void SendableBuilderImpl::SetTable(std::shared_ptr<nt::NetworkTable> table) {
m_table = table;
m_controllableEntry = table->GetEntry(".controllable");
m_controllablePublisher = table->GetBooleanTopic(".controllable").Publish();
m_controllablePublisher.SetDefault(false);
}
std::shared_ptr<nt::NetworkTable> SendableBuilderImpl::GetTable() {
@@ -31,9 +52,7 @@ bool SendableBuilderImpl::IsActuator() const {
void SendableBuilderImpl::Update() {
uint64_t time = nt::Now();
for (auto& property : m_properties) {
if (property.update) {
property.update(property.entry, time);
}
property->Update(m_controllable, time);
}
for (auto& updateTable : m_updateTables) {
updateTable();
@@ -41,20 +60,16 @@ void SendableBuilderImpl::Update() {
}
void SendableBuilderImpl::StartListeners() {
for (auto& property : m_properties) {
property.StartListener();
}
if (m_controllableEntry) {
m_controllableEntry.SetBoolean(true);
m_controllable = true;
if (m_controllablePublisher) {
m_controllablePublisher.Set(true);
}
}
void SendableBuilderImpl::StopListeners() {
for (auto& property : m_properties) {
property.StopListener();
}
if (m_controllableEntry) {
m_controllableEntry.SetBoolean(false);
m_controllable = false;
if (m_controllablePublisher) {
m_controllablePublisher.Set(false);
}
}
@@ -77,11 +92,17 @@ void SendableBuilderImpl::ClearProperties() {
}
void SendableBuilderImpl::SetSmartDashboardType(std::string_view type) {
m_table->GetEntry(".type").SetString(type);
if (!m_typePublisher) {
m_typePublisher = m_table->GetStringTopic(".type").Publish();
}
m_typePublisher.Set(type);
}
void SendableBuilderImpl::SetActuator(bool value) {
m_table->GetEntry(".actuator").SetBoolean(value);
if (!m_actuatorPublisher) {
m_actuatorPublisher = m_table->GetBooleanTopic(".actuator").Publish();
}
m_actuatorPublisher.Set(value);
m_actuator = value;
}
@@ -89,272 +110,183 @@ void SendableBuilderImpl::SetSafeState(std::function<void()> func) {
m_safeState = func;
}
void SendableBuilderImpl::SetUpdateTable(std::function<void()> func) {
void SendableBuilderImpl::SetUpdateTable(wpi::unique_function<void()> func) {
m_updateTables.emplace_back(std::move(func));
}
nt::NetworkTableEntry SendableBuilderImpl::GetEntry(std::string_view key) {
return m_table->GetEntry(key);
nt::Topic SendableBuilderImpl::GetTopic(std::string_view key) {
return m_table->GetTopic(key);
}
template <typename Topic, typename Getter, typename Setter>
void SendableBuilderImpl::AddPropertyImpl(Topic topic, Getter getter,
Setter setter) {
auto prop = std::make_unique<PropertyImpl<Topic>>();
if (getter) {
prop->pub = topic.Publish();
prop->updateNetwork = [=](auto& pub, int64_t time) {
pub.Set(getter(), time);
};
}
if (setter) {
prop->sub = topic.Subscribe({});
prop->updateLocal = [=](auto& sub) {
for (auto&& val : sub.ReadQueue()) {
setter(val.value);
}
};
}
m_properties.emplace_back(std::move(prop));
}
void SendableBuilderImpl::AddBooleanProperty(std::string_view key,
std::function<bool()> getter,
std::function<void(bool)> setter) {
m_properties.emplace_back(*m_table, key);
if (getter) {
m_properties.back().update = [=](nt::NetworkTableEntry entry,
uint64_t time) {
entry.SetValue(nt::Value::MakeBoolean(getter(), time));
};
}
if (setter) {
m_properties.back().createListener =
[=](nt::NetworkTableEntry entry) -> NT_EntryListener {
return entry.AddListener(
[=](const nt::EntryNotification& event) {
if (!event.value->IsBoolean()) {
return;
}
SmartDashboard::PostListenerTask(
[=] { setter(event.value->GetBoolean()); });
},
NT_NOTIFY_IMMEDIATE | NT_NOTIFY_NEW | NT_NOTIFY_UPDATE);
};
}
AddPropertyImpl(m_table->GetBooleanTopic(key), std::move(getter),
std::move(setter));
}
void SendableBuilderImpl::AddIntegerProperty(
std::string_view key, std::function<int64_t()> getter,
std::function<void(int64_t)> setter) {
AddPropertyImpl(m_table->GetIntegerTopic(key), std::move(getter),
std::move(setter));
}
void SendableBuilderImpl::AddFloatProperty(std::string_view key,
std::function<float()> getter,
std::function<void(float)> setter) {
AddPropertyImpl(m_table->GetFloatTopic(key), std::move(getter),
std::move(setter));
}
void SendableBuilderImpl::AddDoubleProperty(
std::string_view key, std::function<double()> getter,
std::function<void(double)> setter) {
m_properties.emplace_back(*m_table, key);
if (getter) {
m_properties.back().update = [=](nt::NetworkTableEntry entry,
uint64_t time) {
entry.SetValue(nt::Value::MakeDouble(getter(), time));
};
}
if (setter) {
m_properties.back().createListener =
[=](nt::NetworkTableEntry entry) -> NT_EntryListener {
return entry.AddListener(
[=](const nt::EntryNotification& event) {
if (!event.value->IsDouble()) {
return;
}
SmartDashboard::PostListenerTask(
[=] { setter(event.value->GetDouble()); });
},
NT_NOTIFY_IMMEDIATE | NT_NOTIFY_NEW | NT_NOTIFY_UPDATE);
};
}
AddPropertyImpl(m_table->GetDoubleTopic(key), std::move(getter),
std::move(setter));
}
void SendableBuilderImpl::AddStringProperty(
std::string_view key, std::function<std::string()> getter,
std::function<void(std::string_view)> setter) {
m_properties.emplace_back(*m_table, key);
if (getter) {
m_properties.back().update = [=](nt::NetworkTableEntry entry,
uint64_t time) {
entry.SetValue(nt::Value::MakeString(getter(), time));
};
}
if (setter) {
m_properties.back().createListener =
[=](nt::NetworkTableEntry entry) -> NT_EntryListener {
return entry.AddListener(
[=](const nt::EntryNotification& event) {
if (!event.value->IsString()) {
return;
}
SmartDashboard::PostListenerTask(
[=] { setter(event.value->GetString()); });
},
NT_NOTIFY_IMMEDIATE | NT_NOTIFY_NEW | NT_NOTIFY_UPDATE);
};
}
AddPropertyImpl(m_table->GetStringTopic(key), std::move(getter),
std::move(setter));
}
void SendableBuilderImpl::AddBooleanArrayProperty(
std::string_view key, std::function<std::vector<int>()> getter,
std::function<void(wpi::span<const int>)> setter) {
m_properties.emplace_back(*m_table, key);
if (getter) {
m_properties.back().update = [=](nt::NetworkTableEntry entry,
uint64_t time) {
entry.SetValue(nt::Value::MakeBooleanArray(getter(), time));
};
}
if (setter) {
m_properties.back().createListener =
[=](nt::NetworkTableEntry entry) -> NT_EntryListener {
return entry.AddListener(
[=](const nt::EntryNotification& event) {
if (!event.value->IsBooleanArray()) {
return;
}
SmartDashboard::PostListenerTask(
[=] { setter(event.value->GetBooleanArray()); });
},
NT_NOTIFY_IMMEDIATE | NT_NOTIFY_NEW | NT_NOTIFY_UPDATE);
};
}
AddPropertyImpl(m_table->GetBooleanArrayTopic(key), std::move(getter),
std::move(setter));
}
void SendableBuilderImpl::AddIntegerArrayProperty(
std::string_view key, std::function<std::vector<int64_t>()> getter,
std::function<void(wpi::span<const int64_t>)> setter) {
AddPropertyImpl(m_table->GetIntegerArrayTopic(key), std::move(getter),
std::move(setter));
}
void SendableBuilderImpl::AddFloatArrayProperty(
std::string_view key, std::function<std::vector<float>()> getter,
std::function<void(wpi::span<const float>)> setter) {
AddPropertyImpl(m_table->GetFloatArrayTopic(key), std::move(getter),
std::move(setter));
}
void SendableBuilderImpl::AddDoubleArrayProperty(
std::string_view key, std::function<std::vector<double>()> getter,
std::function<void(wpi::span<const double>)> setter) {
m_properties.emplace_back(*m_table, key);
if (getter) {
m_properties.back().update = [=](nt::NetworkTableEntry entry,
uint64_t time) {
entry.SetValue(nt::Value::MakeDoubleArray(getter(), time));
};
}
if (setter) {
m_properties.back().createListener =
[=](nt::NetworkTableEntry entry) -> NT_EntryListener {
return entry.AddListener(
[=](const nt::EntryNotification& event) {
if (!event.value->IsDoubleArray()) {
return;
}
SmartDashboard::PostListenerTask(
[=] { setter(event.value->GetDoubleArray()); });
},
NT_NOTIFY_IMMEDIATE | NT_NOTIFY_NEW | NT_NOTIFY_UPDATE);
};
}
AddPropertyImpl(m_table->GetDoubleArrayTopic(key), std::move(getter),
std::move(setter));
}
void SendableBuilderImpl::AddStringArrayProperty(
std::string_view key, std::function<std::vector<std::string>()> getter,
std::function<void(wpi::span<const std::string>)> setter) {
m_properties.emplace_back(*m_table, key);
if (getter) {
m_properties.back().update = [=](nt::NetworkTableEntry entry,
uint64_t time) {
entry.SetValue(nt::Value::MakeStringArray(getter(), time));
};
}
if (setter) {
m_properties.back().createListener =
[=](nt::NetworkTableEntry entry) -> NT_EntryListener {
return entry.AddListener(
[=](const nt::EntryNotification& event) {
if (!event.value->IsStringArray()) {
return;
}
SmartDashboard::PostListenerTask(
[=] { setter(event.value->GetStringArray()); });
},
NT_NOTIFY_IMMEDIATE | NT_NOTIFY_NEW | NT_NOTIFY_UPDATE);
};
}
AddPropertyImpl(m_table->GetStringArrayTopic(key), std::move(getter),
std::move(setter));
}
void SendableBuilderImpl::AddRawProperty(
std::string_view key, std::function<std::string()> getter,
std::function<void(std::string_view)> setter) {
m_properties.emplace_back(*m_table, key);
std::string_view key, std::string_view typeString,
std::function<std::vector<uint8_t>()> getter,
std::function<void(wpi::span<const uint8_t>)> setter) {
auto topic = m_table->GetRawTopic(key);
auto prop = std::make_unique<PropertyImpl<nt::RawTopic>>();
if (getter) {
m_properties.back().update = [=](nt::NetworkTableEntry entry,
uint64_t time) {
entry.SetValue(nt::Value::MakeRaw(getter(), time));
prop->pub = topic.Publish(typeString);
prop->updateNetwork = [=](auto& pub, int64_t time) {
pub.Set(getter(), time);
};
}
if (setter) {
m_properties.back().createListener =
[=](nt::NetworkTableEntry entry) -> NT_EntryListener {
return entry.AddListener(
[=](const nt::EntryNotification& event) {
if (!event.value->IsRaw()) {
return;
}
SmartDashboard::PostListenerTask(
[=] { setter(event.value->GetRaw()); });
},
NT_NOTIFY_IMMEDIATE | NT_NOTIFY_NEW | NT_NOTIFY_UPDATE);
prop->sub = topic.Subscribe(typeString, {});
prop->updateLocal = [=](auto& sub) {
for (auto&& val : sub.ReadQueue()) {
setter(val.value);
}
};
}
m_properties.emplace_back(std::move(prop));
}
void SendableBuilderImpl::AddValueProperty(
std::string_view key, std::function<std::shared_ptr<nt::Value>()> getter,
std::function<void(std::shared_ptr<nt::Value>)> setter) {
m_properties.emplace_back(*m_table, key);
template <typename T, size_t Size, typename Topic, typename Getter,
typename Setter>
void SendableBuilderImpl::AddSmallPropertyImpl(Topic topic, Getter getter,
Setter setter) {
auto prop = std::make_unique<PropertyImpl<Topic>>();
if (getter) {
m_properties.back().update = [=](nt::NetworkTableEntry entry,
uint64_t time) {
entry.SetValue(getter());
prop->pub = topic.Publish();
prop->updateNetwork = [=](auto& pub, int64_t time) {
wpi::SmallVector<T, Size> buf;
pub.Set(getter(buf), time);
};
}
if (setter) {
m_properties.back().createListener =
[=](nt::NetworkTableEntry entry) -> NT_EntryListener {
return entry.AddListener(
[=](const nt::EntryNotification& event) {
SmartDashboard::PostListenerTask([=] { setter(event.value); });
},
NT_NOTIFY_IMMEDIATE | NT_NOTIFY_NEW | NT_NOTIFY_UPDATE);
prop->sub = topic.Subscribe({});
prop->updateLocal = [=](auto& sub) {
for (auto&& val : sub.ReadQueue()) {
setter(val.value);
}
};
}
m_properties.emplace_back(std::move(prop));
}
void SendableBuilderImpl::AddSmallStringProperty(
std::string_view key,
std::function<std::string_view(wpi::SmallVectorImpl<char>& buf)> getter,
std::function<void(std::string_view)> setter) {
m_properties.emplace_back(*m_table, key);
if (getter) {
m_properties.back().update = [=](nt::NetworkTableEntry entry,
uint64_t time) {
wpi::SmallString<128> buf;
entry.SetValue(nt::Value::MakeString(getter(buf), time));
};
}
if (setter) {
m_properties.back().createListener =
[=](nt::NetworkTableEntry entry) -> NT_EntryListener {
return entry.AddListener(
[=](const nt::EntryNotification& event) {
if (!event.value->IsString()) {
return;
}
SmartDashboard::PostListenerTask(
[=] { setter(event.value->GetString()); });
},
NT_NOTIFY_IMMEDIATE | NT_NOTIFY_NEW | NT_NOTIFY_UPDATE);
};
}
AddSmallPropertyImpl<char, 128>(m_table->GetStringTopic(key),
std::move(getter), std::move(setter));
}
void SendableBuilderImpl::AddSmallBooleanArrayProperty(
std::string_view key,
std::function<wpi::span<const int>(wpi::SmallVectorImpl<int>& buf)> getter,
std::function<void(wpi::span<const int>)> setter) {
m_properties.emplace_back(*m_table, key);
if (getter) {
m_properties.back().update = [=](nt::NetworkTableEntry entry,
uint64_t time) {
wpi::SmallVector<int, 16> buf;
entry.SetValue(nt::Value::MakeBooleanArray(getter(buf), time));
};
}
if (setter) {
m_properties.back().createListener =
[=](nt::NetworkTableEntry entry) -> NT_EntryListener {
return entry.AddListener(
[=](const nt::EntryNotification& event) {
if (!event.value->IsBooleanArray()) {
return;
}
SmartDashboard::PostListenerTask(
[=] { setter(event.value->GetBooleanArray()); });
},
NT_NOTIFY_IMMEDIATE | NT_NOTIFY_NEW | NT_NOTIFY_UPDATE);
};
}
AddSmallPropertyImpl<int, 16>(m_table->GetBooleanArrayTopic(key),
std::move(getter), std::move(setter));
}
void SendableBuilderImpl::AddSmallIntegerArrayProperty(
std::string_view key,
std::function<wpi::span<const int64_t>(wpi::SmallVectorImpl<int64_t>& buf)>
getter,
std::function<void(wpi::span<const int64_t>)> setter) {
AddSmallPropertyImpl<int64_t, 16>(m_table->GetIntegerArrayTopic(key),
std::move(getter), std::move(setter));
}
void SendableBuilderImpl::AddSmallFloatArrayProperty(
std::string_view key,
std::function<wpi::span<const float>(wpi::SmallVectorImpl<float>& buf)>
getter,
std::function<void(wpi::span<const float>)> setter) {
AddSmallPropertyImpl<float, 16>(m_table->GetFloatArrayTopic(key),
std::move(getter), std::move(setter));
}
void SendableBuilderImpl::AddSmallDoubleArrayProperty(
@@ -362,28 +294,8 @@ void SendableBuilderImpl::AddSmallDoubleArrayProperty(
std::function<wpi::span<const double>(wpi::SmallVectorImpl<double>& buf)>
getter,
std::function<void(wpi::span<const double>)> setter) {
m_properties.emplace_back(*m_table, key);
if (getter) {
m_properties.back().update = [=](nt::NetworkTableEntry entry,
uint64_t time) {
wpi::SmallVector<double, 16> buf;
entry.SetValue(nt::Value::MakeDoubleArray(getter(buf), time));
};
}
if (setter) {
m_properties.back().createListener =
[=](nt::NetworkTableEntry entry) -> NT_EntryListener {
return entry.AddListener(
[=](const nt::EntryNotification& event) {
if (!event.value->IsDoubleArray()) {
return;
}
SmartDashboard::PostListenerTask(
[=] { setter(event.value->GetDoubleArray()); });
},
NT_NOTIFY_IMMEDIATE | NT_NOTIFY_NEW | NT_NOTIFY_UPDATE);
};
}
AddSmallPropertyImpl<double, 16>(m_table->GetDoubleArrayTopic(key),
std::move(getter), std::move(setter));
}
void SendableBuilderImpl::AddSmallStringArrayProperty(
@@ -392,54 +304,31 @@ void SendableBuilderImpl::AddSmallStringArrayProperty(
wpi::span<const std::string>(wpi::SmallVectorImpl<std::string>& buf)>
getter,
std::function<void(wpi::span<const std::string>)> setter) {
m_properties.emplace_back(*m_table, key);
if (getter) {
m_properties.back().update = [=](nt::NetworkTableEntry entry,
uint64_t time) {
wpi::SmallVector<std::string, 16> buf;
entry.SetValue(nt::Value::MakeStringArray(getter(buf), time));
};
}
if (setter) {
m_properties.back().createListener =
[=](nt::NetworkTableEntry entry) -> NT_EntryListener {
return entry.AddListener(
[=](const nt::EntryNotification& event) {
if (!event.value->IsStringArray()) {
return;
}
SmartDashboard::PostListenerTask(
[=] { setter(event.value->GetStringArray()); });
},
NT_NOTIFY_IMMEDIATE | NT_NOTIFY_NEW | NT_NOTIFY_UPDATE);
};
}
AddSmallPropertyImpl<std::string, 16>(m_table->GetStringArrayTopic(key),
std::move(getter), std::move(setter));
}
void SendableBuilderImpl::AddSmallRawProperty(
std::string_view key,
std::function<std::string_view(wpi::SmallVectorImpl<char>& buf)> getter,
std::function<void(std::string_view)> setter) {
m_properties.emplace_back(*m_table, key);
std::string_view key, std::string_view typeString,
std::function<wpi::span<uint8_t>(wpi::SmallVectorImpl<uint8_t>& buf)>
getter,
std::function<void(wpi::span<const uint8_t>)> setter) {
auto topic = m_table->GetRawTopic(key);
auto prop = std::make_unique<PropertyImpl<nt::RawTopic>>();
if (getter) {
m_properties.back().update = [=](nt::NetworkTableEntry entry,
uint64_t time) {
wpi::SmallVector<char, 128> buf;
entry.SetValue(nt::Value::MakeRaw(getter(buf), time));
prop->pub = topic.Publish(typeString);
prop->updateNetwork = [=](auto& pub, int64_t time) {
wpi::SmallVector<uint8_t, 128> buf;
pub.Set(getter(buf), time);
};
}
if (setter) {
m_properties.back().createListener =
[=](nt::NetworkTableEntry entry) -> NT_EntryListener {
return entry.AddListener(
[=](const nt::EntryNotification& event) {
if (!event.value->IsRaw()) {
return;
}
SmartDashboard::PostListenerTask(
[=] { setter(event.value->GetRaw()); });
},
NT_NOTIFY_IMMEDIATE | NT_NOTIFY_NEW | NT_NOTIFY_UPDATE);
prop->sub = topic.Subscribe(typeString, {});
prop->updateLocal = [=](auto& sub) {
for (auto&& val : sub.ReadQueue()) {
setter(val.value);
}
};
}
m_properties.emplace_back(std::move(prop));
}

View File

@@ -19,7 +19,8 @@ SendableChooserBase::SendableChooserBase(SendableChooserBase&& oth)
m_defaultChoice(std::move(oth.m_defaultChoice)),
m_selected(std::move(oth.m_selected)),
m_haveSelected(std::move(oth.m_haveSelected)),
m_activeEntries(std::move(oth.m_activeEntries)),
m_instancePubs(std::move(oth.m_instancePubs)),
m_activePubs(std::move(oth.m_activePubs)),
m_instance(std::move(oth.m_instance)) {}
SendableChooserBase& SendableChooserBase::operator=(SendableChooserBase&& oth) {
@@ -28,7 +29,8 @@ SendableChooserBase& SendableChooserBase::operator=(SendableChooserBase&& oth) {
m_defaultChoice = std::move(oth.m_defaultChoice);
m_selected = std::move(oth.m_selected);
m_haveSelected = std::move(oth.m_haveSelected);
m_activeEntries = std::move(oth.m_activeEntries);
m_instancePubs = std::move(oth.m_instancePubs);
m_activePubs = std::move(oth.m_activePubs);
m_instance = std::move(oth.m_instance);
return *this;
}

View File

@@ -70,22 +70,6 @@ bool SmartDashboard::IsPersistent(std::string_view key) {
return GetInstance().table->GetEntry(key).IsPersistent();
}
void SmartDashboard::SetFlags(std::string_view key, unsigned int flags) {
GetInstance().table->GetEntry(key).SetFlags(flags);
}
void SmartDashboard::ClearFlags(std::string_view key, unsigned int flags) {
GetInstance().table->GetEntry(key).ClearFlags(flags);
}
unsigned int SmartDashboard::GetFlags(std::string_view key) {
return GetInstance().table->GetEntry(key).GetFlags();
}
void SmartDashboard::Delete(std::string_view key) {
GetInstance().table->Delete(key);
}
nt::NetworkTableEntry SmartDashboard::GetEntry(std::string_view key) {
return GetInstance().table->GetEntry(key);
}
@@ -218,31 +202,32 @@ std::vector<std::string> SmartDashboard::GetStringArray(
return GetInstance().table->GetEntry(key).GetStringArray(defaultValue);
}
bool SmartDashboard::PutRaw(std::string_view key, std::string_view value) {
bool SmartDashboard::PutRaw(std::string_view key,
wpi::span<const uint8_t> value) {
return GetInstance().table->GetEntry(key).SetRaw(value);
}
bool SmartDashboard::SetDefaultRaw(std::string_view key,
std::string_view defaultValue) {
wpi::span<const uint8_t> defaultValue) {
return GetInstance().table->GetEntry(key).SetDefaultRaw(defaultValue);
}
std::string SmartDashboard::GetRaw(std::string_view key,
std::string_view defaultValue) {
std::vector<uint8_t> SmartDashboard::GetRaw(
std::string_view key, wpi::span<const uint8_t> defaultValue) {
return GetInstance().table->GetEntry(key).GetRaw(defaultValue);
}
bool SmartDashboard::PutValue(std::string_view keyName,
std::shared_ptr<nt::Value> value) {
const nt::Value& value) {
return GetInstance().table->GetEntry(keyName).SetValue(value);
}
bool SmartDashboard::SetDefaultValue(std::string_view key,
std::shared_ptr<nt::Value> defaultValue) {
const nt::Value& defaultValue) {
return GetInstance().table->GetEntry(key).SetDefaultValue(defaultValue);
}
std::shared_ptr<nt::Value> SmartDashboard::GetValue(std::string_view keyName) {
nt::Value SmartDashboard::GetValue(std::string_view keyName) {
return GetInstance().table->GetEntry(keyName).GetValue();
}