mirror of
https://github.com/wpilibsuite/allwpilib
synced 2026-07-04 03:11:43 +00:00
Adds SetDefault methods to NetworkTables (#54)
There was no way to atomically check for a key in the table, and then setting if it if non existant. Back before persistent this was not a problem, however now it is, as its possible for values to be added before team's robot programs start. This makes the old method of calling Put*** methods in RobotInit invalid. This adds SetDefault methods, which do this atomically.
This commit is contained in:
committed by
Peter Johnson
parent
6615a34e99
commit
58092c5190
@@ -464,6 +464,48 @@ std::shared_ptr<Value> Storage::GetEntryValue(StringRef name) const {
|
||||
return i == m_entries.end() ? nullptr : i->getValue()->value;
|
||||
}
|
||||
|
||||
bool Storage::SetDefaultEntryValue(StringRef name,
|
||||
std::shared_ptr<Value> value) {
|
||||
if (!value) return false; // can't compare to a null value
|
||||
if (name.empty()) return false; // can't compare empty name
|
||||
std::unique_lock<std::mutex> lock(m_mutex);
|
||||
auto& new_entry = m_entries[name];
|
||||
if (new_entry) { // entry already exists
|
||||
auto old_value = new_entry->value;
|
||||
// if types match return true
|
||||
if (old_value && old_value->type() == value->type()) return true;
|
||||
else return false; // entry exists but doesn't match type
|
||||
}
|
||||
|
||||
// if we've gotten here, entry does not exist, and we can write it.
|
||||
new_entry.reset(new Entry(name));
|
||||
Entry* entry = new_entry.get();
|
||||
// don't need to compare old value as we know it will assign
|
||||
entry->value = value;
|
||||
|
||||
// if we're the server, assign an id if it doesn't have one
|
||||
if (m_server && entry->id == 0xffff) {
|
||||
unsigned int id = m_idmap.size();
|
||||
entry->id = id;
|
||||
m_idmap.push_back(entry);
|
||||
}
|
||||
|
||||
// notify (for local listeners)
|
||||
if (m_notifier.local_notifiers()) {
|
||||
// always a new entry if we got this far
|
||||
m_notifier.NotifyEntry(name, value, NT_NOTIFY_NEW | NT_NOTIFY_LOCAL);
|
||||
}
|
||||
|
||||
// generate message
|
||||
if (!m_queue_outgoing) return true;
|
||||
auto queue_outgoing = m_queue_outgoing;
|
||||
auto msg = Message::EntryAssign(name, entry->id, entry->seq_num.value(),
|
||||
value, entry->flags);
|
||||
lock.unlock();
|
||||
queue_outgoing(msg, nullptr, nullptr);
|
||||
return true;
|
||||
}
|
||||
|
||||
bool Storage::SetEntryValue(StringRef name, std::shared_ptr<Value> value) {
|
||||
if (name.empty()) return true;
|
||||
if (!value) return true;
|
||||
|
||||
@@ -67,6 +67,7 @@ class Storage {
|
||||
// User functions. These are the actual implementations of the corresponding
|
||||
// user API functions in ntcore_cpp.
|
||||
std::shared_ptr<Value> GetEntryValue(StringRef name) const;
|
||||
bool SetDefaultEntryValue(StringRef name, std::shared_ptr<Value> value);
|
||||
bool SetEntryValue(StringRef name, std::shared_ptr<Value> value);
|
||||
void SetEntryTypeValue(StringRef name, std::shared_ptr<Value> value);
|
||||
void SetEntryFlags(StringRef name, unsigned int flags);
|
||||
|
||||
@@ -305,6 +305,13 @@ bool NetworkTable::PutNumber(StringRef key, double value) {
|
||||
return nt::SetEntryValue(path, nt::Value::MakeDouble(value));
|
||||
}
|
||||
|
||||
bool NetworkTable::SetDefaultNumber(StringRef key, double defaultValue) {
|
||||
llvm::SmallString<128> path(m_path);
|
||||
path += PATH_SEPARATOR_CHAR;
|
||||
path += key;
|
||||
return nt::SetDefaultEntryValue(path, nt::Value::MakeDouble(defaultValue));
|
||||
}
|
||||
|
||||
double NetworkTable::GetNumber(StringRef key) const {
|
||||
llvm::SmallString<128> path(m_path);
|
||||
path += PATH_SEPARATOR_CHAR;
|
||||
@@ -332,6 +339,13 @@ bool NetworkTable::PutString(StringRef key, StringRef value) {
|
||||
return nt::SetEntryValue(path, nt::Value::MakeString(value));
|
||||
}
|
||||
|
||||
bool NetworkTable::SetDefaultString(StringRef key, StringRef defaultValue) {
|
||||
llvm::SmallString<128> path(m_path);
|
||||
path += PATH_SEPARATOR_CHAR;
|
||||
path += key;
|
||||
return nt::SetDefaultEntryValue(path, nt::Value::MakeString(defaultValue));
|
||||
}
|
||||
|
||||
std::string NetworkTable::GetString(StringRef key) const {
|
||||
llvm::SmallString<128> path(m_path);
|
||||
path += PATH_SEPARATOR_CHAR;
|
||||
@@ -360,6 +374,13 @@ bool NetworkTable::PutBoolean(StringRef key, bool value) {
|
||||
return nt::SetEntryValue(path, nt::Value::MakeBoolean(value));
|
||||
}
|
||||
|
||||
bool NetworkTable::SetDefaultBoolean(StringRef key, bool defaultValue) {
|
||||
llvm::SmallString<128> path(m_path);
|
||||
path += PATH_SEPARATOR_CHAR;
|
||||
path += key;
|
||||
return nt::SetDefaultEntryValue(path, nt::Value::MakeBoolean(defaultValue));
|
||||
}
|
||||
|
||||
bool NetworkTable::GetBoolean(StringRef key) const {
|
||||
llvm::SmallString<128> path(m_path);
|
||||
path += PATH_SEPARATOR_CHAR;
|
||||
@@ -388,6 +409,14 @@ bool NetworkTable::PutBooleanArray(llvm::StringRef key,
|
||||
return nt::SetEntryValue(path, nt::Value::MakeBooleanArray(value));
|
||||
}
|
||||
|
||||
bool NetworkTable::SetDefaultBooleanArray(StringRef key,
|
||||
llvm::ArrayRef<int> defaultValue) {
|
||||
llvm::SmallString<128> path(m_path);
|
||||
path += PATH_SEPARATOR_CHAR;
|
||||
path += key;
|
||||
return nt::SetDefaultEntryValue(path, nt::Value::MakeBooleanArray(defaultValue));
|
||||
}
|
||||
|
||||
std::vector<int> NetworkTable::GetBooleanArray(
|
||||
llvm::StringRef key, llvm::ArrayRef<int> defaultValue) const {
|
||||
llvm::SmallString<128> path(m_path);
|
||||
@@ -407,6 +436,14 @@ bool NetworkTable::PutNumberArray(llvm::StringRef key,
|
||||
return nt::SetEntryValue(path, nt::Value::MakeDoubleArray(value));
|
||||
}
|
||||
|
||||
bool NetworkTable::SetDefaultNumberArray(StringRef key,
|
||||
llvm::ArrayRef<double> defaultValue) {
|
||||
llvm::SmallString<128> path(m_path);
|
||||
path += PATH_SEPARATOR_CHAR;
|
||||
path += key;
|
||||
return nt::SetDefaultEntryValue(path, nt::Value::MakeDoubleArray(defaultValue));
|
||||
}
|
||||
|
||||
std::vector<double> NetworkTable::GetNumberArray(
|
||||
llvm::StringRef key, llvm::ArrayRef<double> defaultValue) const {
|
||||
llvm::SmallString<128> path(m_path);
|
||||
@@ -426,6 +463,14 @@ bool NetworkTable::PutStringArray(llvm::StringRef key,
|
||||
return nt::SetEntryValue(path, nt::Value::MakeStringArray(value));
|
||||
}
|
||||
|
||||
bool NetworkTable::SetDefaultStringArray(StringRef key,
|
||||
llvm::ArrayRef<std::string> defaultValue) {
|
||||
llvm::SmallString<128> path(m_path);
|
||||
path += PATH_SEPARATOR_CHAR;
|
||||
path += key;
|
||||
return nt::SetDefaultEntryValue(path, nt::Value::MakeStringArray(defaultValue));
|
||||
}
|
||||
|
||||
std::vector<std::string> NetworkTable::GetStringArray(
|
||||
llvm::StringRef key, llvm::ArrayRef<std::string> defaultValue) const {
|
||||
llvm::SmallString<128> path(m_path);
|
||||
@@ -444,6 +489,14 @@ bool NetworkTable::PutRaw(llvm::StringRef key, llvm::StringRef value) {
|
||||
return nt::SetEntryValue(path, nt::Value::MakeRaw(value));
|
||||
}
|
||||
|
||||
bool NetworkTable::SetDefaultRaw(StringRef key,
|
||||
StringRef defaultValue) {
|
||||
llvm::SmallString<128> path(m_path);
|
||||
path += PATH_SEPARATOR_CHAR;
|
||||
path += key;
|
||||
return nt::SetDefaultEntryValue(path, nt::Value::MakeRaw(defaultValue));
|
||||
}
|
||||
|
||||
std::string NetworkTable::GetRaw(llvm::StringRef key,
|
||||
llvm::StringRef defaultValue) const {
|
||||
llvm::SmallString<128> path(m_path);
|
||||
@@ -462,6 +515,14 @@ bool NetworkTable::PutValue(StringRef key, std::shared_ptr<nt::Value> value) {
|
||||
return nt::SetEntryValue(path, value);
|
||||
}
|
||||
|
||||
bool NetworkTable::SetDefaultValue(StringRef key,
|
||||
std::shared_ptr<nt::Value> defaultValue) {
|
||||
llvm::SmallString<128> path(m_path);
|
||||
path += PATH_SEPARATOR_CHAR;
|
||||
path += key;
|
||||
return nt::SetDefaultEntryValue(path, defaultValue);
|
||||
}
|
||||
|
||||
std::shared_ptr<nt::Value> NetworkTable::GetValue(StringRef key) const {
|
||||
llvm::SmallString<128> path(m_path);
|
||||
path += PATH_SEPARATOR_CHAR;
|
||||
|
||||
@@ -124,6 +124,12 @@ void NT_GetEntryValue(const char *name, size_t name_len,
|
||||
ConvertToC(*v, value);
|
||||
}
|
||||
|
||||
int NT_SetDefaultEntryValue(const char* name, size_t name_len,
|
||||
const struct NT_Value *set_value) {
|
||||
return nt::SetDefaultEntryValue(StringRef(name, name_len),
|
||||
ConvertFromC(*set_value));
|
||||
}
|
||||
|
||||
int NT_SetEntryValue(const char *name, size_t name_len,
|
||||
const struct NT_Value *value) {
|
||||
return nt::SetEntryValue(StringRef(name, name_len), ConvertFromC(*value));
|
||||
@@ -701,6 +707,57 @@ NT_String *NT_GetValueStringArray(const struct NT_Value *value,
|
||||
return arr;
|
||||
}
|
||||
|
||||
int NT_SetDefaultEntryBoolean(const char *name, size_t name_len,
|
||||
int default_boolean) {
|
||||
return nt::SetDefaultEntryValue(StringRef(name, name_len),
|
||||
Value::MakeBoolean(default_boolean != 0));
|
||||
}
|
||||
|
||||
int NT_SetDefaultEntryDouble(const char *name, size_t name_len,
|
||||
double default_double) {
|
||||
return nt::SetDefaultEntryValue(StringRef(name, name_len),
|
||||
Value::MakeDouble(default_double));
|
||||
}
|
||||
|
||||
int NT_SetDefaultEntryString(const char *name, size_t name_len,
|
||||
const char *default_value, size_t default_len) {
|
||||
return nt::SetDefaultEntryValue(StringRef(name, name_len),
|
||||
Value::MakeString(StringRef(default_value,
|
||||
default_len)));
|
||||
}
|
||||
|
||||
int NT_SetDefaultEntryRaw(const char *name, size_t name_len,
|
||||
const char *default_value, size_t default_len) {
|
||||
return nt::SetDefaultEntryValue(StringRef(name, name_len),
|
||||
Value::MakeString(StringRef(default_value,
|
||||
default_len)));
|
||||
}
|
||||
|
||||
int NT_SetDefaultEntryBooleanArray(const char *name, size_t name_len,
|
||||
const int *default_value,
|
||||
size_t default_size) {
|
||||
return nt::SetDefaultEntryValue(StringRef(name, name_len),
|
||||
Value::MakeBooleanArray(llvm::makeArrayRef(default_value, default_size)));
|
||||
}
|
||||
|
||||
int NT_SetDefaultEntryDoubleArray(const char *name, size_t name_len, const double *default_value,
|
||||
size_t default_size) {
|
||||
return nt::SetDefaultEntryValue(StringRef(name, name_len),
|
||||
Value::MakeDoubleArray(llvm::makeArrayRef(default_value, default_size)));
|
||||
}
|
||||
|
||||
int NT_SetDefaultEntryStringArray(const char *name, size_t name_len,
|
||||
const struct NT_String* default_value,
|
||||
size_t default_size) {
|
||||
std::vector<std::string> vec;
|
||||
vec.reserve(default_size);
|
||||
for (size_t i = 0; i < default_size; ++i)
|
||||
vec.push_back(ConvertFromC(default_value[i]));
|
||||
|
||||
return nt::SetDefaultEntryValue(StringRef(name, name_len),
|
||||
Value::MakeStringArray(std::move(vec)));
|
||||
}
|
||||
|
||||
int NT_GetEntryBoolean(const char *name, size_t name_len,
|
||||
unsigned long long *last_change, int *v_boolean) {
|
||||
auto v = nt::GetEntryValue(StringRef(name, name_len));
|
||||
|
||||
@@ -29,6 +29,10 @@ std::shared_ptr<Value> GetEntryValue(StringRef name) {
|
||||
return Storage::GetInstance().GetEntryValue(name);
|
||||
}
|
||||
|
||||
bool SetDefaultEntryValue(StringRef name, std::shared_ptr<Value> value) {
|
||||
return Storage::GetInstance().SetDefaultEntryValue(name, value);
|
||||
}
|
||||
|
||||
bool SetEntryValue(StringRef name, std::shared_ptr<Value> value) {
|
||||
return Storage::GetInstance().SetEntryValue(name, value);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user