mirror of
https://github.com/wpilibsuite/allwpilib
synced 2026-06-23 01:21:42 +00:00
Add shims for old NetworkTable interface.
This provides classes for virtual subtables using path delimiters within the global NetworkTable namespace.
This commit is contained in:
192
include/networktables/NetworkTable.h
Normal file
192
include/networktables/NetworkTable.h
Normal file
@@ -0,0 +1,192 @@
|
||||
#ifndef _NETWORKTABLE_H_
|
||||
#define _NETWORKTABLE_H_
|
||||
|
||||
#include <vector>
|
||||
|
||||
#include "tables/ITable.h"
|
||||
|
||||
class NetworkTable : public ITable {
|
||||
private:
|
||||
struct private_init {};
|
||||
|
||||
std::string m_path;
|
||||
std::vector<std::pair<ITableListener*, unsigned int>> m_listeners;
|
||||
|
||||
static std::string s_ip_address;
|
||||
static bool s_client;
|
||||
static bool s_running;
|
||||
|
||||
public:
|
||||
NetworkTable(llvm::StringRef path, const private_init&);
|
||||
virtual ~NetworkTable();
|
||||
|
||||
/**
|
||||
* The path separator for sub-tables and keys
|
||||
*
|
||||
*/
|
||||
static const char PATH_SEPARATOR_CHAR;
|
||||
|
||||
/**
|
||||
* @throws IOException
|
||||
*/
|
||||
static void Initialize();
|
||||
static void Shutdown();
|
||||
|
||||
/**
|
||||
* set that network tables should be a client
|
||||
* This must be called before initalize or GetTable
|
||||
*/
|
||||
static void SetClientMode();
|
||||
|
||||
/**
|
||||
* set that network tables should be a server
|
||||
* This must be called before initalize or GetTable
|
||||
*/
|
||||
static void SetServerMode();
|
||||
|
||||
/**
|
||||
* set the team the robot is configured for (this will set the ip address that
|
||||
* network tables will connect to in client mode)
|
||||
* This must be called before initalize or GetTable
|
||||
* @param team the team number
|
||||
*/
|
||||
static void SetTeam(int team);
|
||||
/**
|
||||
* @param address the adress that network tables will connect to in client
|
||||
* mode
|
||||
*/
|
||||
static void SetIPAddress(llvm::StringRef address);
|
||||
|
||||
/**
|
||||
* Gets the table with the specified key. If the table does not exist, a new
|
||||
*table will be created.<br>
|
||||
* This will automatically initialize network tables if it has not been
|
||||
*already
|
||||
*
|
||||
* @param key
|
||||
* the key name
|
||||
* @return the network table requested
|
||||
*/
|
||||
static std::shared_ptr<NetworkTable> GetTable(llvm::StringRef key);
|
||||
|
||||
void AddTableListener(ITableListener* listener);
|
||||
void AddTableListener(ITableListener* listener, bool immediateNotify);
|
||||
void AddTableListener(llvm::StringRef key, ITableListener* listener,
|
||||
bool immediateNotify);
|
||||
void RemoveTableListener(ITableListener* listener);
|
||||
|
||||
/**
|
||||
* Returns the table at the specified key. If there is no table at the
|
||||
* specified key, it will create a new table
|
||||
*
|
||||
* @param key
|
||||
* the key name
|
||||
* @return the networktable to be returned
|
||||
*/
|
||||
std::shared_ptr<ITable> GetSubTable(llvm::StringRef key);
|
||||
|
||||
/**
|
||||
* Checks the table and tells if it contains the specified key
|
||||
*
|
||||
* @param key
|
||||
* the key to be checked
|
||||
*/
|
||||
bool ContainsKey(llvm::StringRef key);
|
||||
|
||||
bool ContainsSubTable(llvm::StringRef key);
|
||||
|
||||
/**
|
||||
* Maps the specified key to the specified value in this table. The key can
|
||||
* not be null. The value can be retrieved by calling the get method with a
|
||||
* key that is equal to the original key.
|
||||
*
|
||||
* @param key
|
||||
* the key
|
||||
* @param value
|
||||
* the value
|
||||
*/
|
||||
void PutNumber(llvm::StringRef key, double value);
|
||||
|
||||
/**
|
||||
* Returns the key that the name maps to. If the key is null, it will return
|
||||
* the default value
|
||||
*
|
||||
* @param key
|
||||
* the key name
|
||||
* @param defaultValue
|
||||
* the default value if the key is null
|
||||
* @return the key
|
||||
*/
|
||||
double GetNumber(llvm::StringRef key, double defaultValue);
|
||||
|
||||
/**
|
||||
* Maps the specified key to the specified value in this table. The key can
|
||||
* not be null. The value can be retrieved by calling the get method with a
|
||||
* key that is equal to the original key.
|
||||
*
|
||||
* @param key
|
||||
* the key
|
||||
* @param value
|
||||
* the value
|
||||
*/
|
||||
void PutString(llvm::StringRef key, llvm::StringRef value);
|
||||
|
||||
/**
|
||||
* Returns the key that the name maps to. If the key is null, it will return
|
||||
* the default value
|
||||
*
|
||||
* @param key
|
||||
* the key name
|
||||
* @param defaultValue
|
||||
* the default value if the key is null
|
||||
* @return the key
|
||||
*/
|
||||
std::string GetString(llvm::StringRef key, llvm::StringRef defaultValue);
|
||||
|
||||
/**
|
||||
* Maps the specified key to the specified value in this table. The key can
|
||||
* not be null. The value can be retrieved by calling the get method with a
|
||||
* key that is equal to the original key.
|
||||
*
|
||||
* @param key
|
||||
* the key
|
||||
* @param value
|
||||
* the value
|
||||
*/
|
||||
void PutBoolean(llvm::StringRef key, bool value);
|
||||
|
||||
/**
|
||||
* Returns the key that the name maps to. If the key is null, it will return
|
||||
* the default value
|
||||
*
|
||||
* @param key
|
||||
* the key name
|
||||
* @param defaultValue
|
||||
* the default value if the key is null
|
||||
* @return the key
|
||||
*/
|
||||
bool GetBoolean(llvm::StringRef key, bool defaultValue);
|
||||
|
||||
/**
|
||||
* Maps the specified key to the specified value in this table. The key can
|
||||
* not be null. The value can be retrieved by calling the get method with a
|
||||
* key that is equal to the original key.
|
||||
*
|
||||
* @param key the key name
|
||||
* @param value the value to be put
|
||||
*/
|
||||
void PutValue(llvm::StringRef key, std::shared_ptr<nt::Value> value);
|
||||
|
||||
/**
|
||||
* Returns the key that the name maps to.
|
||||
* NOTE: If the value is a double, it will return a Double object,
|
||||
* not a primitive. To get the primitive, use GetDouble
|
||||
*
|
||||
* @param key
|
||||
* the key name
|
||||
* @return the key, or nullptr if the key is not defined
|
||||
*/
|
||||
std::shared_ptr<nt::Value> GetValue(llvm::StringRef key);
|
||||
};
|
||||
|
||||
#endif
|
||||
158
include/tables/ITable.h
Normal file
158
include/tables/ITable.h
Normal file
@@ -0,0 +1,158 @@
|
||||
/*
|
||||
* ITable.h
|
||||
*
|
||||
* Created on: Sep 19, 2012
|
||||
* Author: Mitchell Wills
|
||||
*/
|
||||
|
||||
#ifndef ITABLE_H_
|
||||
#define ITABLE_H_
|
||||
|
||||
#include <memory>
|
||||
|
||||
#include "llvm/StringRef.h"
|
||||
#include "nt_Value.h"
|
||||
|
||||
class ITableListener;
|
||||
|
||||
class ITable {
|
||||
public:
|
||||
/**
|
||||
* Determines whether the given key is in this table.
|
||||
*
|
||||
* @param key the key to search for
|
||||
* @return true if the table as a value assigned to the given key
|
||||
*/
|
||||
virtual bool ContainsKey(llvm::StringRef key) = 0;
|
||||
|
||||
/**
|
||||
* Determines whether there exists a non-empty subtable for this key
|
||||
* in this table.
|
||||
*
|
||||
* @param key the key to search for
|
||||
* @return true if there is a subtable with the key which contains at least
|
||||
* one key/subtable of its own
|
||||
*/
|
||||
virtual bool ContainsSubTable(llvm::StringRef key) = 0;
|
||||
|
||||
/**
|
||||
* Gets the subtable in this table for the given name.
|
||||
*
|
||||
* @param key the name of the table relative to this one
|
||||
* @return a sub table relative to this one
|
||||
*/
|
||||
virtual std::shared_ptr<ITable> GetSubTable(llvm::StringRef key) = 0;
|
||||
|
||||
/**
|
||||
* Gets the value associated with a key as an object
|
||||
*
|
||||
* @param key the key of the value to look up
|
||||
* @return the value associated with the given key
|
||||
* @throws TableKeyNotDefinedException if there is no value associated with
|
||||
* the given key
|
||||
*/
|
||||
virtual std::shared_ptr<nt::Value> GetValue(llvm::StringRef key) = 0;
|
||||
|
||||
/**
|
||||
* Put a value in the table
|
||||
*
|
||||
* @param key the key to be assigned to
|
||||
* @param value the value that will be assigned
|
||||
* @throws IllegalArgumentException when the value is not supported by the
|
||||
* table
|
||||
*/
|
||||
virtual void PutValue(llvm::StringRef key,
|
||||
std::shared_ptr<nt::Value> value) = 0;
|
||||
|
||||
/**
|
||||
* Put a number in the table
|
||||
*
|
||||
* @param key the key to be assigned to
|
||||
* @param value the value that will be assigned
|
||||
*/
|
||||
virtual void PutNumber(llvm::StringRef key, double value) = 0;
|
||||
|
||||
/**
|
||||
* Gets the number associated with the given name.
|
||||
*
|
||||
* @param key the key to look up
|
||||
* @param defaultValue the value to be returned if no value is found
|
||||
* @return the value associated with the given key or the given default value
|
||||
* if there is no value associated with the key
|
||||
*/
|
||||
virtual double GetNumber(llvm::StringRef key, double defaultValue) = 0;
|
||||
|
||||
/**
|
||||
* Put a string in the table
|
||||
*
|
||||
* @param key the key to be assigned to
|
||||
* @param value the value that will be assigned
|
||||
*/
|
||||
virtual void PutString(llvm::StringRef key, llvm::StringRef value) = 0;
|
||||
|
||||
/**
|
||||
* Gets the string associated with the given name.
|
||||
*
|
||||
* @param key the key to look up
|
||||
* @param defaultValue the value to be returned if no value is found
|
||||
* @return the value associated with the given key or the given default value
|
||||
* if there is no value associated with the key
|
||||
*/
|
||||
virtual std::string GetString(llvm::StringRef key,
|
||||
llvm::StringRef defaultValue) = 0;
|
||||
|
||||
/**
|
||||
* Put a boolean in the table
|
||||
*
|
||||
* @param key the key to be assigned to
|
||||
* @param value the value that will be assigned
|
||||
*/
|
||||
virtual void PutBoolean(llvm::StringRef key, bool value) = 0;
|
||||
|
||||
/**
|
||||
* Gets the boolean associated with the given name.
|
||||
*
|
||||
* @param key the key to look up
|
||||
* @param defaultValue the value to be returned if no value is found
|
||||
* @return the value associated with the given key or the given default value
|
||||
* if there is no value associated with the key
|
||||
*/
|
||||
virtual bool GetBoolean(llvm::StringRef key, bool defaultValue) = 0;
|
||||
|
||||
/**
|
||||
* Add a listener for changes to the table
|
||||
*
|
||||
* @param listener the listener to add
|
||||
*/
|
||||
virtual void AddTableListener(ITableListener* listener) = 0;
|
||||
|
||||
/**
|
||||
* Add a listener for changes to the table
|
||||
*
|
||||
* @param listener the listener to add
|
||||
* @param immediateNotify if true then this listener will be notified of all
|
||||
* current entries (marked as new)
|
||||
*/
|
||||
virtual void AddTableListener(ITableListener* listener,
|
||||
bool immediateNotify) = 0;
|
||||
|
||||
/**
|
||||
* Add a listener for changes to a specific key the table
|
||||
*
|
||||
* @param key the key to listen for
|
||||
* @param listener the listener to add
|
||||
* @param immediateNotify if true then this listener will be notified of all
|
||||
* current entries (marked as new)
|
||||
*/
|
||||
virtual void AddTableListener(llvm::StringRef key, ITableListener* listener,
|
||||
bool immediateNotify) = 0;
|
||||
|
||||
/**
|
||||
* Remove a listener from receiving table events
|
||||
*
|
||||
* @param listener the listener to be removed
|
||||
*/
|
||||
virtual void RemoveTableListener(ITableListener* listener) = 0;
|
||||
};
|
||||
|
||||
#endif /* ITABLE_H_ */
|
||||
33
include/tables/ITableListener.h
Normal file
33
include/tables/ITableListener.h
Normal file
@@ -0,0 +1,33 @@
|
||||
/*
|
||||
* ITableListener.h
|
||||
*/
|
||||
|
||||
#ifndef ITABLELISTENER_H_
|
||||
#define ITABLELISTENER_H_
|
||||
|
||||
#include <memory>
|
||||
|
||||
#include "tables/ITable.h"
|
||||
|
||||
/**
|
||||
* A listener that listens to changes in values in a {@link ITable}
|
||||
*/
|
||||
class ITableListener {
|
||||
public:
|
||||
virtual ~ITableListener() = default;
|
||||
/**
|
||||
* Called when a key-value pair is changed in a {@link ITable}
|
||||
* WARNING: If a new key-value is put in this method value changed will
|
||||
* immediatly be called which could lead to recursive code
|
||||
* @param source the table the key-value pair exists in
|
||||
* @param key the key associated with the value that changed
|
||||
* @param value the new value
|
||||
* @param isNew true if the key did not previously exist in the table,
|
||||
* otherwise it is false
|
||||
*/
|
||||
virtual void ValueChanged(ITable* source,
|
||||
const llvm::StringRef key,
|
||||
std::shared_ptr<nt::Value> value, bool isNew) = 0;
|
||||
};
|
||||
|
||||
#endif /* ITABLELISTENER_H_ */
|
||||
187
src/networktables/NetworkTable.cpp
Normal file
187
src/networktables/NetworkTable.cpp
Normal file
@@ -0,0 +1,187 @@
|
||||
#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
|
||||
nt::StartServer("", "", NT_DEFAULT_PORT);
|
||||
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(),
|
||||
[=](const auto& x) { return x.first == listener; });
|
||||
|
||||
for (auto i = matches_begin; i != m_listeners.end(); ++i)
|
||||
nt::RemoveEntryListener(i->second);
|
||||
m_listeners.erase(matches_begin, m_listeners.end());
|
||||
}
|
||||
|
||||
std::shared_ptr<ITable> NetworkTable::GetSubTable(StringRef key) {
|
||||
llvm::SmallString<128> path(m_path);
|
||||
path += PATH_SEPARATOR_CHAR;
|
||||
path += key;
|
||||
return std::make_shared<NetworkTable>(path, private_init());
|
||||
}
|
||||
|
||||
bool NetworkTable::ContainsKey(StringRef key) {
|
||||
llvm::SmallString<128> path(m_path);
|
||||
path += PATH_SEPARATOR_CHAR;
|
||||
path += key;
|
||||
return !nt::GetEntryValue(path);
|
||||
}
|
||||
|
||||
bool NetworkTable::ContainsSubTable(StringRef key) {
|
||||
llvm::SmallString<128> path(m_path);
|
||||
path += PATH_SEPARATOR_CHAR;
|
||||
path += key;
|
||||
path += PATH_SEPARATOR_CHAR;
|
||||
return !nt::GetEntryInfo(path, 0).empty();
|
||||
}
|
||||
|
||||
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));
|
||||
}
|
||||
|
||||
double NetworkTable::GetNumber(StringRef key, double defaultValue) {
|
||||
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));
|
||||
}
|
||||
|
||||
std::string NetworkTable::GetString(StringRef key, StringRef defaultValue) {
|
||||
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));
|
||||
}
|
||||
|
||||
bool NetworkTable::GetBoolean(StringRef key, bool defaultValue) {
|
||||
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);
|
||||
}
|
||||
|
||||
std::shared_ptr<nt::Value> NetworkTable::GetValue(StringRef key) {
|
||||
llvm::SmallString<128> path(m_path);
|
||||
path += PATH_SEPARATOR_CHAR;
|
||||
path += key;
|
||||
return nt::GetEntryValue(path);
|
||||
}
|
||||
Reference in New Issue
Block a user