2015-07-23 01:23:09 -07:00
|
|
|
#include "networktables/NetworkTable.h"
|
|
|
|
|
|
|
|
|
|
#include <algorithm>
|
|
|
|
|
|
|
|
|
|
#include "llvm/SmallString.h"
|
|
|
|
|
#include "tables/ITableListener.h"
|
|
|
|
|
#include "ntcore.h"
|
|
|
|
|
|
|
|
|
|
using llvm::StringRef;
|
|
|
|
|
|
|
|
|
|
const char NetworkTable::PATH_SEPARATOR_CHAR = '/';
|
|
|
|
|
std::string NetworkTable::s_ip_address;
|
|
|
|
|
bool NetworkTable::s_client = false;
|
|
|
|
|
bool NetworkTable::s_running = false;
|
|
|
|
|
|
|
|
|
|
void NetworkTable::Initialize() {
|
|
|
|
|
if (s_client)
|
|
|
|
|
nt::StartClient(s_ip_address.c_str(), NT_DEFAULT_PORT);
|
|
|
|
|
else
|
2015-07-23 21:47:54 -07:00
|
|
|
nt::StartServer("networktables.ini", "", NT_DEFAULT_PORT);
|
2015-07-23 01:23:09 -07:00
|
|
|
s_running = true;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void NetworkTable::Shutdown() {
|
|
|
|
|
if (s_client)
|
|
|
|
|
nt::StopClient();
|
|
|
|
|
else
|
|
|
|
|
nt::StopServer();
|
|
|
|
|
s_running = false;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void NetworkTable::SetClientMode() { s_client = true; }
|
|
|
|
|
|
|
|
|
|
void NetworkTable::SetServerMode() { s_client = false; }
|
|
|
|
|
|
|
|
|
|
void NetworkTable::SetTeam(int team) {
|
|
|
|
|
char tmp[30];
|
|
|
|
|
sprintf(tmp, "%d.%d.%d.%d\n", 10, team / 100, team % 100, 2);
|
|
|
|
|
SetIPAddress(tmp);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void NetworkTable::SetIPAddress(StringRef address) {
|
|
|
|
|
s_ip_address = address;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
std::shared_ptr<NetworkTable> NetworkTable::GetTable(StringRef key) {
|
|
|
|
|
if (!s_running) Initialize();
|
|
|
|
|
llvm::SmallString<128> path;
|
|
|
|
|
path += PATH_SEPARATOR_CHAR;
|
|
|
|
|
path += key;
|
|
|
|
|
return std::make_shared<NetworkTable>(path, private_init());
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
NetworkTable::NetworkTable(StringRef path, const private_init&)
|
|
|
|
|
: m_path(path) {}
|
|
|
|
|
|
|
|
|
|
NetworkTable::~NetworkTable() {
|
|
|
|
|
for (auto& i : m_listeners)
|
|
|
|
|
nt::RemoveEntryListener(i.second);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void NetworkTable::AddTableListener(ITableListener* listener) {
|
|
|
|
|
AddTableListener(listener, false);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void NetworkTable::AddTableListener(ITableListener* listener,
|
|
|
|
|
bool immediateNotify) {
|
|
|
|
|
llvm::SmallString<128> path(m_path);
|
|
|
|
|
path += PATH_SEPARATOR_CHAR;
|
|
|
|
|
unsigned int id = nt::AddEntryListener(
|
|
|
|
|
path,
|
|
|
|
|
[=](unsigned int uid, StringRef name, std::shared_ptr<nt::Value> value,
|
|
|
|
|
bool is_new) { listener->ValueChanged(this, name, value, is_new); },
|
|
|
|
|
immediateNotify);
|
|
|
|
|
m_listeners.emplace_back(listener, id);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void NetworkTable::AddTableListener(StringRef key,
|
|
|
|
|
ITableListener* listener,
|
|
|
|
|
bool immediateNotify) {
|
|
|
|
|
llvm::SmallString<128> path(m_path);
|
|
|
|
|
path += PATH_SEPARATOR_CHAR;
|
|
|
|
|
path += key;
|
|
|
|
|
unsigned int id = nt::AddEntryListener(
|
|
|
|
|
path,
|
|
|
|
|
[=](unsigned int uid, StringRef name, std::shared_ptr<nt::Value> value,
|
|
|
|
|
bool is_new) { listener->ValueChanged(this, name, value, is_new); },
|
|
|
|
|
immediateNotify);
|
|
|
|
|
m_listeners.emplace_back(listener, id);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void NetworkTable::RemoveTableListener(ITableListener* listener) {
|
|
|
|
|
auto matches_begin =
|
|
|
|
|
std::remove_if(m_listeners.begin(), m_listeners.end(),
|
2015-08-03 01:23:42 -07:00
|
|
|
[=](const Listener& x) { return x.first == listener; });
|
2015-07-23 01:23:09 -07:00
|
|
|
|
|
|
|
|
for (auto i = matches_begin; i != m_listeners.end(); ++i)
|
|
|
|
|
nt::RemoveEntryListener(i->second);
|
|
|
|
|
m_listeners.erase(matches_begin, m_listeners.end());
|
|
|
|
|
}
|
|
|
|
|
|
2015-07-23 21:46:30 -07:00
|
|
|
std::shared_ptr<ITable> NetworkTable::GetSubTable(StringRef key) const {
|
2015-07-23 01:23:09 -07:00
|
|
|
llvm::SmallString<128> path(m_path);
|
|
|
|
|
path += PATH_SEPARATOR_CHAR;
|
|
|
|
|
path += key;
|
|
|
|
|
return std::make_shared<NetworkTable>(path, private_init());
|
|
|
|
|
}
|
|
|
|
|
|
2015-07-23 21:46:30 -07:00
|
|
|
bool NetworkTable::ContainsKey(StringRef key) const {
|
2015-07-23 01:23:09 -07:00
|
|
|
llvm::SmallString<128> path(m_path);
|
|
|
|
|
path += PATH_SEPARATOR_CHAR;
|
|
|
|
|
path += key;
|
|
|
|
|
return !nt::GetEntryValue(path);
|
|
|
|
|
}
|
|
|
|
|
|
2015-07-23 21:46:30 -07:00
|
|
|
bool NetworkTable::ContainsSubTable(StringRef key) const {
|
2015-07-23 01:23:09 -07:00
|
|
|
llvm::SmallString<128> path(m_path);
|
|
|
|
|
path += PATH_SEPARATOR_CHAR;
|
|
|
|
|
path += key;
|
|
|
|
|
path += PATH_SEPARATOR_CHAR;
|
|
|
|
|
return !nt::GetEntryInfo(path, 0).empty();
|
|
|
|
|
}
|
|
|
|
|
|
2015-07-23 21:53:33 -07:00
|
|
|
void NetworkTable::Persist(StringRef key) {
|
|
|
|
|
llvm::SmallString<128> path(m_path);
|
|
|
|
|
path += PATH_SEPARATOR_CHAR;
|
|
|
|
|
path += key;
|
|
|
|
|
nt::SetEntryFlags(path, NT_PERSISTENT);
|
|
|
|
|
}
|
|
|
|
|
|
2015-07-23 01:23:09 -07:00
|
|
|
void NetworkTable::PutNumber(StringRef key, double value) {
|
|
|
|
|
llvm::SmallString<128> path(m_path);
|
|
|
|
|
path += PATH_SEPARATOR_CHAR;
|
|
|
|
|
path += key;
|
|
|
|
|
nt::SetEntryValue(path, nt::Value::MakeDouble(value));
|
|
|
|
|
}
|
|
|
|
|
|
2015-07-23 21:46:30 -07:00
|
|
|
double NetworkTable::GetNumber(StringRef key, double defaultValue) const {
|
2015-07-23 01:23:09 -07:00
|
|
|
llvm::SmallString<128> path(m_path);
|
|
|
|
|
path += PATH_SEPARATOR_CHAR;
|
|
|
|
|
path += key;
|
|
|
|
|
auto value = nt::GetEntryValue(path);
|
|
|
|
|
if (!value || value->type() != NT_DOUBLE)
|
|
|
|
|
return defaultValue;
|
|
|
|
|
return value->GetDouble();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void NetworkTable::PutString(StringRef key, StringRef value) {
|
|
|
|
|
llvm::SmallString<128> path(m_path);
|
|
|
|
|
path += PATH_SEPARATOR_CHAR;
|
|
|
|
|
path += key;
|
|
|
|
|
nt::SetEntryValue(path, nt::Value::MakeString(value));
|
|
|
|
|
}
|
|
|
|
|
|
2015-07-23 21:46:30 -07:00
|
|
|
std::string NetworkTable::GetString(StringRef key,
|
|
|
|
|
StringRef defaultValue) const {
|
2015-07-23 01:23:09 -07:00
|
|
|
llvm::SmallString<128> path(m_path);
|
|
|
|
|
path += PATH_SEPARATOR_CHAR;
|
|
|
|
|
path += key;
|
|
|
|
|
auto value = nt::GetEntryValue(path);
|
|
|
|
|
if (!value || value->type() != NT_STRING)
|
|
|
|
|
return defaultValue;
|
|
|
|
|
return value->GetString();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void NetworkTable::PutBoolean(StringRef key, bool value) {
|
|
|
|
|
llvm::SmallString<128> path(m_path);
|
|
|
|
|
path += PATH_SEPARATOR_CHAR;
|
|
|
|
|
path += key;
|
|
|
|
|
nt::SetEntryValue(path, nt::Value::MakeBoolean(value));
|
|
|
|
|
}
|
|
|
|
|
|
2015-07-23 21:46:30 -07:00
|
|
|
bool NetworkTable::GetBoolean(StringRef key, bool defaultValue) const {
|
2015-07-23 01:23:09 -07:00
|
|
|
llvm::SmallString<128> path(m_path);
|
|
|
|
|
path += PATH_SEPARATOR_CHAR;
|
|
|
|
|
path += key;
|
|
|
|
|
auto value = nt::GetEntryValue(path);
|
|
|
|
|
if (!value || value->type() != NT_BOOLEAN)
|
|
|
|
|
return defaultValue;
|
|
|
|
|
return value->GetBoolean();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void NetworkTable::PutValue(StringRef key, std::shared_ptr<nt::Value> value) {
|
|
|
|
|
llvm::SmallString<128> path(m_path);
|
|
|
|
|
path += PATH_SEPARATOR_CHAR;
|
|
|
|
|
path += key;
|
|
|
|
|
nt::SetEntryValue(path, value);
|
|
|
|
|
}
|
|
|
|
|
|
2015-07-23 21:46:30 -07:00
|
|
|
std::shared_ptr<nt::Value> NetworkTable::GetValue(StringRef key) const {
|
2015-07-23 01:23:09 -07:00
|
|
|
llvm::SmallString<128> path(m_path);
|
|
|
|
|
path += PATH_SEPARATOR_CHAR;
|
|
|
|
|
path += key;
|
|
|
|
|
return nt::GetEntryValue(path);
|
|
|
|
|
}
|