diff --git a/include/networktables/NetworkTable.h b/include/networktables/NetworkTable.h index 73e860a04f..1724b93b2f 100644 --- a/include/networktables/NetworkTable.h +++ b/include/networktables/NetworkTable.h @@ -1,6 +1,7 @@ #ifndef _NETWORKTABLE_H_ #define _NETWORKTABLE_H_ +#include #include #include @@ -54,12 +55,59 @@ class NetworkTable : public ITable { * @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); + /** + * Sets the network identity. + * This is provided in the connection info on the remote end. + * @param name identity + */ + static void SetNetworkIdentity(llvm::StringRef name); + + /** + * Deletes ALL keys in ALL subtables. Use with caution! + */ + static void GlobalDeleteAll(); + + /** + * Flushes all updated values immediately to the network. + * Note: This is rate-limited to protect the network from flooding. + * This is primarily useful for synchronizing network updates with + * user code. + */ + static void Flush(); + + /** + * Set the periodic update rate. + * + * @param interval update interval in seconds (range 0.1 to 1.0) + */ + static void SetUpdateRate(double interval); + + /** + * Saves persistent keys to a file. The server does this automatically. + * + * @param filename file name + * @return Error (or nullptr). + */ + static const char* SavePersistent(llvm::StringRef filename); + + /** + * Loads persistent keys from a file. The server does this automatically. + * + * @param filename file name + * @param warn callback function called for warnings + * @return Error (or nullptr). + */ + static const char* LoadPersistent( + llvm::StringRef filename, + std::function warn); + /** * Gets the table with the specified key. If the table does not exist, a new *table will be created.
@@ -103,7 +151,58 @@ class NetworkTable : public ITable { * * @param key the key to make persistent */ - void Persist(llvm::StringRef key); + void SetPersistent(llvm::StringRef key); + + /** + * Stop making a key's value persistent through program restarts. + * The key cannot be null. + * + * @param key the key name + */ + void ClearPersistent(llvm::StringRef key); + + /** + * Returns whether the value is persistent through program restarts. + * The key cannot be null. + * + * @param key the key name + */ + bool IsPersistent(llvm::StringRef key); + + /** + * Sets flags on the specified key in this table. The key can + * not be null. + * + * @param key the key name + * @param flags the flags to set (bitmask) + */ + void SetFlags(llvm::StringRef key, unsigned int flags); + + /** + * Clears flags on the specified key in this table. The key can + * not be null. + * + * @param key the key name + * @param flags the flags to clear (bitmask) + */ + void ClearFlags(llvm::StringRef key, unsigned int flags); + + /** + * Returns the flags for the specified key. + * + * @param key + * the key name + * @return the flags, or 0 if the key is not defined + */ + unsigned int GetFlags(llvm::StringRef key); + + /** + * Deletes the specified key in this table. The key can + * not be null. + * + * @param key the key name + */ + void Delete(llvm::StringRef key); /** * Maps the specified key to the specified value in this table. The key can @@ -115,7 +214,7 @@ class NetworkTable : public ITable { * @param value * the value */ - void PutNumber(llvm::StringRef key, double value); + bool PutNumber(llvm::StringRef key, double value); /** * Returns the key that the name maps to. If the key is null, it will return @@ -139,7 +238,7 @@ class NetworkTable : public ITable { * @param value * the value */ - void PutString(llvm::StringRef key, llvm::StringRef value); + bool PutString(llvm::StringRef key, llvm::StringRef value); /** * Returns the key that the name maps to. If the key is null, it will return @@ -164,7 +263,7 @@ class NetworkTable : public ITable { * @param value * the value */ - void PutBoolean(llvm::StringRef key, bool value); + bool PutBoolean(llvm::StringRef key, bool value); /** * Returns the key that the name maps to. If the key is null, it will return @@ -186,7 +285,7 @@ class NetworkTable : public ITable { * @param key the key name * @param value the value to be put */ - void PutValue(llvm::StringRef key, std::shared_ptr value); + bool PutValue(llvm::StringRef key, std::shared_ptr value); /** * Returns the key that the name maps to. diff --git a/include/tables/ITable.h b/include/tables/ITable.h index adb2c12b91..8b594348b8 100644 --- a/include/tables/ITable.h +++ b/include/tables/ITable.h @@ -48,7 +48,58 @@ class ITable { * * @param key the key to make persistent */ - virtual void Persist(llvm::StringRef key) = 0; + virtual void SetPersistent(llvm::StringRef key) = 0; + + /** + * Stop making a key's value persistent through program restarts. + * The key cannot be null. + * + * @param key the key name + */ + virtual void ClearPersistent(llvm::StringRef key) = 0; + + /** + * Returns whether the value is persistent through program restarts. + * The key cannot be null. + * + * @param key the key name + */ + virtual bool IsPersistent(llvm::StringRef key) = 0; + + /** + * Sets flags on the specified key in this table. The key can + * not be null. + * + * @param key the key name + * @param flags the flags to set (bitmask) + */ + virtual void SetFlags(llvm::StringRef key, unsigned int flags) = 0; + + /** + * Clears flags on the specified key in this table. The key can + * not be null. + * + * @param key the key name + * @param flags the flags to clear (bitmask) + */ + virtual void ClearFlags(llvm::StringRef key, unsigned int flags) = 0; + + /** + * Returns the flags for the specified key. + * + * @param key + * the key name + * @return the flags, or 0 if the key is not defined + */ + virtual unsigned int GetFlags(llvm::StringRef key) = 0; + + /** + * Deletes the specified key in this table. The key can + * not be null. + * + * @param key the key name + */ + virtual void Delete(llvm::StringRef key) = 0; /** * Gets the value associated with a key as an object @@ -65,10 +116,11 @@ class ITable { * * @param key the key to be assigned to * @param value the value that will be assigned + * @return False if the table key already exists with a different type * @throws IllegalArgumentException when the value is not supported by the * table */ - virtual void PutValue(llvm::StringRef key, + virtual bool PutValue(llvm::StringRef key, std::shared_ptr value) = 0; /** @@ -76,8 +128,9 @@ class ITable { * * @param key the key to be assigned to * @param value the value that will be assigned + * @return False if the table key already exists with a different type */ - virtual void PutNumber(llvm::StringRef key, double value) = 0; + virtual bool PutNumber(llvm::StringRef key, double value) = 0; /** * Gets the number associated with the given name. @@ -94,8 +147,9 @@ class ITable { * * @param key the key to be assigned to * @param value the value that will be assigned + * @return False if the table key already exists with a different type */ - virtual void PutString(llvm::StringRef key, llvm::StringRef value) = 0; + virtual bool PutString(llvm::StringRef key, llvm::StringRef value) = 0; /** * Gets the string associated with the given name. @@ -113,8 +167,9 @@ class ITable { * * @param key the key to be assigned to * @param value the value that will be assigned + * @return False if the table key already exists with a different type */ - virtual void PutBoolean(llvm::StringRef key, bool value) = 0; + virtual bool PutBoolean(llvm::StringRef key, bool value) = 0; /** * Gets the boolean associated with the given name. diff --git a/java/src/edu/wpi/first/wpilibj/networktables/NetworkTable.java b/java/src/edu/wpi/first/wpilibj/networktables/NetworkTable.java index 304a540705..0f45c40c1f 100644 --- a/java/src/edu/wpi/first/wpilibj/networktables/NetworkTable.java +++ b/java/src/edu/wpi/first/wpilibj/networktables/NetworkTable.java @@ -112,6 +112,15 @@ public class NetworkTable implements ITable, IRemote { port = aport; } + /** + * Sets the network identity. + * This is provided in the connection info on the remote end. + * @param name identity + */ + public static void setNetworkIdentity(String name) { + NetworkTablesJNI.setNetworkIdentity(name); + } + public static boolean[] toNative(Boolean[] arr) { boolean[] out = new boolean[arr.length]; for (int i = 0; i < arr.length; i++) @@ -165,6 +174,10 @@ public class NetworkTable implements ITable, IRemote { } public String toString() { return "NetworkTable: " + path; } + public static ConnectionInfo[] connections() { + return NetworkTablesJNI.getConnections(); + } + public boolean isConnected() { ConnectionInfo[] conns = NetworkTablesJNI.getConnections(); return conns.length > 0; @@ -767,15 +780,57 @@ public class NetworkTable implements ITable, IRemote { /** The persistent flag value. */ public static final int PERSISTENT = 1; + /** + * Makes a key's value persistent through program restarts. + * The key cannot be null. + * + * @param key the key name + */ + public void setPersistent(String key) { + setFlags(key, PERSISTENT); + } + + /** + * Stop making a key's value persistent through program restarts. + * The key cannot be null. + * + * @param key the key name + */ + public void clearPersistent(String key) { + clearFlags(key, PERSISTENT); + } + + /** + * Returns whether the value is persistent through program restarts. + * The key cannot be null. + * + * @param key the key name + * @return True if the value is persistent. + */ + public boolean isPersistent(String key) { + return (getFlags(key) & PERSISTENT) != 0; + } + /** * Sets flags on the specified key in this table. The key can * not be null. * * @param key the key name - * @param flags the flags to set + * @param flags the flags to set (bitmask) */ public void setFlags(String key, int flags) { - NetworkTablesJNI.setEntryFlags(path + PATH_SEPARATOR + key, flags); + NetworkTablesJNI.setEntryFlags(path + PATH_SEPARATOR + key, getFlags(key) | flags); + } + + /** + * Clears flags on the specified key in this table. The key can + * not be null. + * + * @param key the key name + * @param flags the flags to clear (bitmask) + */ + public void clearFlags(String key, int flags) { + NetworkTablesJNI.setEntryFlags(path + PATH_SEPARATOR + key, getFlags(key) & ~flags); } /** @@ -789,6 +844,63 @@ public class NetworkTable implements ITable, IRemote { return NetworkTablesJNI.getEntryFlags(path + PATH_SEPARATOR + key); } + /** + * Deletes the specified key in this table. The key can + * not be null. + * + * @param key the key name + */ + public void delete(String key) { + NetworkTablesJNI.deleteEntry(path + PATH_SEPARATOR + key); + } + + /** + * Deletes ALL keys in ALL subtables. Use with caution! + */ + public static void globalDeleteAll() { + NetworkTablesJNI.deleteAllEntries(); + } + + /** + * Flushes all updated values immediately to the network. + * Note: This is rate-limited to protect the network from flooding. + * This is primarily useful for synchronizing network updates with + * user code. + */ + public static void flush() { + NetworkTablesJNI.flush(); + } + + /** + * Set the periodic update rate. + * + * @param interval update interval in seconds (range 0.1 to 1.0) + */ + public static void setUpdateRate(double interval) { + NetworkTablesJNI.setUpdateRate(interval); + } + + /** + * Saves persistent keys to a file. The server does this automatically. + * + * @param filename file name + * @throws PersistentException if error saving file + */ + public static void savePersistent(String filename) throws PersistentException { + NetworkTablesJNI.savePersistent(filename); + } + + /** + * Loads persistent keys from a file. The server does this automatically. + * + * @param filename file name + * @return List of warnings (errors result in an exception instead) + * @throws PersistentException if error reading file + */ + public static String[] loadPersistent(String filename) throws PersistentException { + return NetworkTablesJNI.loadPersistent(filename); + } + /* * Deprecated Methods */ diff --git a/java/src/edu/wpi/first/wpilibj/tables/ITable.java b/java/src/edu/wpi/first/wpilibj/tables/ITable.java index e4dc52d3be..b5c62e3867 100644 --- a/java/src/edu/wpi/first/wpilibj/tables/ITable.java +++ b/java/src/edu/wpi/first/wpilibj/tables/ITable.java @@ -30,6 +30,66 @@ public interface ITable { */ public ITable getSubTable(String key); + /** + * Makes a key's value persistent through program restarts. + * The key cannot be null. + * + * @param key the key name + */ + public void setPersistent(String key); + + /** + * Stop making a key's value persistent through program restarts. + * The key cannot be null. + * + * @param key the key name + */ + public void clearPersistent(String key); + + /** + * Returns whether the value is persistent through program restarts. + * The key cannot be null. + * + * @param key the key name + * @return True if the value is persistent. + */ + public boolean isPersistent(String key); + + /** + * Sets flags on the specified key in this table. The key can + * not be null. + * + * @param key the key name + * @param flags the flags to set (bitmask) + */ + public void setFlags(String key, int flags); + + /** + * Clears flags on the specified key in this table. The key can + * not be null. + * + * @param key the key name + * @param flags the flags to clear (bitmask) + */ + public void clearFlags(String key, int flags); + + /** + * Returns the flags for the specified key. + * + * @param key + * the key name + * @return the flags, or 0 if the key is not defined + */ + public int getFlags(String key); + + /** + * Deletes the specified key in this table. The key can + * not be null. + * + * @param key the key name + */ + public void delete(String key); + /** * Gets the value associated with a key as an object * @param key the key of the value to look up diff --git a/src/networktables/NetworkTable.cpp b/src/networktables/NetworkTable.cpp index b033000df3..51cb94981e 100644 --- a/src/networktables/NetworkTable.cpp +++ b/src/networktables/NetworkTable.cpp @@ -14,6 +14,7 @@ bool NetworkTable::s_client = false; bool NetworkTable::s_running = false; void NetworkTable::Initialize() { + if (s_running) Shutdown(); if (s_client) nt::StartClient(s_ip_address.c_str(), NT_DEFAULT_PORT); else @@ -22,6 +23,7 @@ void NetworkTable::Initialize() { } void NetworkTable::Shutdown() { + if (!s_running) return; if (s_client) nt::StopClient(); else @@ -43,8 +45,28 @@ void NetworkTable::SetTeam(int team) { SetIPAddress(tmp); } -void NetworkTable::SetIPAddress(StringRef address) { - s_ip_address = address; +void NetworkTable::SetIPAddress(StringRef address) { s_ip_address = address; } + +void NetworkTable::SetNetworkIdentity(StringRef name) { + nt::SetNetworkIdentity(name); +} + +void NetworkTable::GlobalDeleteAll() { nt::DeleteAllEntries(); } + +void NetworkTable::Flush() { nt::Flush(); } + +void NetworkTable::SetUpdateRate(double interval) { + nt::SetUpdateRate(interval); +} + +const char* NetworkTable::SavePersistent(llvm::StringRef filename) { + return nt::SavePersistent(filename); +} + +const char* NetworkTable::LoadPersistent( + llvm::StringRef filename, + std::function warn) { + return nt::LoadPersistent(filename, warn); } std::shared_ptr NetworkTable::GetTable(StringRef key) { @@ -139,18 +161,51 @@ bool NetworkTable::ContainsSubTable(StringRef key) const { return !nt::GetEntryInfo(path, 0).empty(); } -void NetworkTable::Persist(StringRef key) { - llvm::SmallString<128> path(m_path); - path += PATH_SEPARATOR_CHAR; - path += key; - nt::SetEntryFlags(path, NT_PERSISTENT); +void NetworkTable::SetPersistent(StringRef key) { + SetFlags(key, NT_PERSISTENT); } -void NetworkTable::PutNumber(StringRef key, double value) { +void NetworkTable::ClearPersistent(StringRef key) { + ClearFlags(key, NT_PERSISTENT); +} + +bool NetworkTable::IsPersistent(StringRef key) { + return (GetFlags(key) & NT_PERSISTENT) != 0; +} + +void NetworkTable::SetFlags(StringRef key, unsigned int flags) { llvm::SmallString<128> path(m_path); path += PATH_SEPARATOR_CHAR; path += key; - nt::SetEntryValue(path, nt::Value::MakeDouble(value)); + nt::SetEntryFlags(path, nt::GetEntryFlags(key) | flags); +} + +void NetworkTable::ClearFlags(StringRef key, unsigned int flags) { + llvm::SmallString<128> path(m_path); + path += PATH_SEPARATOR_CHAR; + path += key; + nt::SetEntryFlags(path, nt::GetEntryFlags(path) & ~flags); +} + +unsigned int NetworkTable::GetFlags(StringRef key) { + llvm::SmallString<128> path(m_path); + path += PATH_SEPARATOR_CHAR; + path += key; + return nt::GetEntryFlags(path); +} + +void NetworkTable::Delete(StringRef key) { + llvm::SmallString<128> path(m_path); + path += PATH_SEPARATOR_CHAR; + path += key; + nt::DeleteEntry(path); +} + +bool NetworkTable::PutNumber(StringRef key, double value) { + llvm::SmallString<128> path(m_path); + path += PATH_SEPARATOR_CHAR; + path += key; + return nt::SetEntryValue(path, nt::Value::MakeDouble(value)); } double NetworkTable::GetNumber(StringRef key, double defaultValue) const { @@ -163,11 +218,11 @@ double NetworkTable::GetNumber(StringRef key, double defaultValue) const { return value->GetDouble(); } -void NetworkTable::PutString(StringRef key, StringRef value) { +bool 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)); + return nt::SetEntryValue(path, nt::Value::MakeString(value)); } std::string NetworkTable::GetString(StringRef key, @@ -181,11 +236,11 @@ std::string NetworkTable::GetString(StringRef key, return value->GetString(); } -void NetworkTable::PutBoolean(StringRef key, bool value) { +bool 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)); + return nt::SetEntryValue(path, nt::Value::MakeBoolean(value)); } bool NetworkTable::GetBoolean(StringRef key, bool defaultValue) const { @@ -198,11 +253,11 @@ bool NetworkTable::GetBoolean(StringRef key, bool defaultValue) const { return value->GetBoolean(); } -void NetworkTable::PutValue(StringRef key, std::shared_ptr value) { +bool NetworkTable::PutValue(StringRef key, std::shared_ptr value) { llvm::SmallString<128> path(m_path); path += PATH_SEPARATOR_CHAR; path += key; - nt::SetEntryValue(path, value); + return nt::SetEntryValue(path, value); } std::shared_ptr NetworkTable::GetValue(StringRef key) const {