/*----------------------------------------------------------------------------*/ /* Copyright (c) 2015-2019 FIRST. All Rights Reserved. */ /* Open Source Software - may be modified and shared by FRC teams. The code */ /* must be accompanied by the FIRST BSD license file in the root directory of */ /* the project. */ /*----------------------------------------------------------------------------*/ #ifndef NTCORE_NETWORKTABLES_NETWORKTABLE_H_ #define NTCORE_NETWORKTABLES_NETWORKTABLE_H_ #include #include #include #include #include #include #include #include #include #include "networktables/NetworkTableEntry.h" #include "networktables/TableEntryListener.h" #include "networktables/TableListener.h" #include "ntcore_c.h" #include "tables/ITable.h" namespace nt { using wpi::ArrayRef; using wpi::StringRef; using wpi::Twine; class NetworkTableInstance; #ifdef __GNUC__ #pragma GCC diagnostic push #pragma GCC diagnostic ignored "-Wdeprecated-declarations" #elif _WIN32 #pragma warning(push) #pragma warning(disable : 4996) #endif /** * @defgroup ntcore_cpp_api ntcore C++ object-oriented API * * Recommended interface for C++, identical to Java API. */ /** * A network table that knows its subtable path. * @ingroup ntcore_cpp_api */ class NetworkTable final : public ITable { private: NT_Inst m_inst; std::string m_path; mutable wpi::mutex m_mutex; mutable wpi::StringMap m_entries; typedef std::pair Listener; std::vector m_listeners; std::vector m_lambdaListeners; static std::vector s_ip_addresses; static std::string s_persistent_filename; static bool s_client; static bool s_enable_ds; static bool s_running; static unsigned int s_port; struct private_init {}; friend class NetworkTableInstance; public: /** * Gets the "base name" of a key. For example, "/foo/bar" becomes "bar". * If the key has a trailing slash, returns an empty string. * * @param key key * @return base name */ static StringRef BasenameKey(StringRef key); /** * Normalizes an network table key to contain no consecutive slashes and * optionally start with a leading slash. For example: * *

   * normalizeKey("/foo/bar", true)  == "/foo/bar"
   * normalizeKey("foo/bar", true)   == "/foo/bar"
   * normalizeKey("/foo/bar", false) == "foo/bar"
   * normalizeKey("foo//bar", false) == "foo/bar"
   * 
* * @param key the key to normalize * @param withLeadingSlash whether or not the normalized key should begin * with a leading slash * @return normalized key */ static std::string NormalizeKey(const Twine& key, bool withLeadingSlash = true); static StringRef NormalizeKey(const Twine& key, wpi::SmallVectorImpl& buf, bool withLeadingSlash = true); /** * Gets a list of the names of all the super tables of a given key. For * example, the key "/foo/bar/baz" has a hierarchy of "/", "/foo", * "/foo/bar", and "/foo/bar/baz". * * @param key the key * @return List of super tables */ static std::vector GetHierarchy(const Twine& key); /** * Constructor. Use NetworkTableInstance::GetTable() or GetSubTable() * instead. */ NetworkTable(NT_Inst inst, const Twine& path, const private_init&); virtual ~NetworkTable(); /** * Gets the instance for the table. * * @return Instance */ NetworkTableInstance GetInstance() const; /** * The path separator for sub-tables and keys */ static const char PATH_SEPARATOR_CHAR; /** * Initializes network tables */ WPI_DEPRECATED( "use NetworkTableInstance::StartServer() or " "NetworkTableInstance::StartClient() instead") static void Initialize(); /** * Shuts down network tables */ WPI_DEPRECATED( "use NetworkTableInstance::StopServer() or " "NetworkTableInstance::StopClient() instead") static void Shutdown(); /** * set that network tables should be a client * This must be called before initialize or GetTable */ WPI_DEPRECATED("use NetworkTableInstance::StartClient() instead") static void SetClientMode(); /** * set that network tables should be a server * This must be called before initialize or GetTable */ WPI_DEPRECATED("use NetworkTableInstance::StartServer() instead") static void SetServerMode(); /** * set the team the robot is configured for (this will set the mdns address * that network tables will connect to in client mode) * This must be called before initialize or GetTable * * @param team the team number */ WPI_DEPRECATED( "use NetworkTableInstance::SetServerTeam() or " "NetworkTableInstance::StartClientTeam() instead") static void SetTeam(int team); /** * @param address the adress that network tables will connect to in client * mode */ WPI_DEPRECATED( "use NetworkTableInstance::SetServer() or " "NetworkTableInstance::StartClient() instead") static void SetIPAddress(StringRef address); /** * @param addresses the addresses that network tables will connect to in * client mode (in round robin order) */ WPI_DEPRECATED( "use NetworkTableInstance::SetServer() or " "NetworkTableInstance::StartClient() instead") static void SetIPAddress(ArrayRef addresses); /** * Set the port number that network tables will connect to in client * mode or listen to in server mode. * * @param port the port number */ WPI_DEPRECATED( "use the appropriate parameters to NetworkTableInstance::SetServer(), " "NetworkTableInstance::StartClient(), " "NetworkTableInstance::StartServer(), and " "NetworkTableInstance::StartDSClient() instead") static void SetPort(unsigned int port); /** * Enable requesting the server address from the Driver Station. * * @param enabled whether to enable the connection to the local DS */ WPI_DEPRECATED( "use NetworkTableInstance::StartDSClient() and " "NetworkTableInstance::StopDSClient() instead") static void SetDSClientEnabled(bool enabled); /** * Sets the persistent filename. * * @param filename the filename that the network tables server uses for * automatic loading and saving of persistent values */ WPI_DEPRECATED( "use the appropriate parameter to NetworkTableInstance::StartServer() " "instead") static void SetPersistentFilename(StringRef filename); /** * Sets the network identity. * This is provided in the connection info on the remote end. * * @param name identity */ WPI_DEPRECATED("use NetworkTableInstance::SetNetworkIdentity() instead") static void SetNetworkIdentity(StringRef name); /** * Deletes ALL keys in ALL subtables. Use with caution! */ WPI_DEPRECATED("use NetworkTableInstance::DeleteAllEntries() instead") 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. */ WPI_DEPRECATED("use NetworkTableInstance::Flush() instead") static void Flush(); /** * Set the periodic update rate. * Sets how frequently updates are sent to other nodes over the network. * * @param interval update interval in seconds (range 0.01 to 1.0) */ WPI_DEPRECATED("use NetworkTableInstance::SetUpdateRate() instead") static void SetUpdateRate(double interval); /** * Saves persistent keys to a file. The server does this automatically. * * @param filename file name * @return Error (or nullptr). */ WPI_DEPRECATED("use NetworkTableInstance::SavePersistent() instead") static const char* SavePersistent(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). */ WPI_DEPRECATED("use NetworkTableInstance::LoadPersistent() instead") static const char* LoadPersistent( StringRef filename, std::function warn); /** * Gets the table with the specified key. If the table does not exist, a new * table will be created.
* This will automatically initialize network tables if it has not been * already. * * @param key the key name * @return the network table requested */ WPI_DEPRECATED( "use NetworkTableInstance::GetTable() or " "NetworkTableInstance::GetEntry() instead") static std::shared_ptr GetTable(StringRef key); /** * Gets the entry for a subkey. * * @param key the key name * @return Network table entry. */ NetworkTableEntry GetEntry(const Twine& key) const; /** * Listen to keys only within this table. * * @param listener listener to add * @param flags EntryListenerFlags bitmask * @return Listener handle */ NT_EntryListener AddEntryListener(TableEntryListener listener, unsigned int flags) const; /** * Listen to a single key. * * @param key the key name * @param listener listener to add * @param flags EntryListenerFlags bitmask * @return Listener handle */ NT_EntryListener AddEntryListener(const Twine& key, TableEntryListener listener, unsigned int flags) const; /** * Remove an entry listener. * * @param listener listener handle */ void RemoveEntryListener(NT_EntryListener listener) const; /** * Listen for sub-table creation. * This calls the listener once for each newly created sub-table. * It immediately calls the listener for any existing sub-tables. * * @param listener listener to add * @param localNotify notify local changes as well as remote * @return Listener handle */ NT_EntryListener AddSubTableListener(TableListener listener, bool localNotify = false); /** * Remove a sub-table listener. * * @param listener listener handle */ void RemoveTableListener(NT_EntryListener listener); WPI_DEPRECATED( "use AddEntryListener() instead with flags value of NT_NOTIFY_NEW | " "NT_NOTIFY_UPDATE") void AddTableListener(ITableListener* listener) override; WPI_DEPRECATED( "use AddEntryListener() instead with flags value of NT_NOTIFY_NEW | " "NT_NOTIFY_UPDATE | NT_NOTIFY_IMMEDIATE") void AddTableListener(ITableListener* listener, bool immediateNotify) override; WPI_DEPRECATED("use AddEntryListener() instead") void AddTableListenerEx(ITableListener* listener, unsigned int flags) override; WPI_DEPRECATED("use AddEntryListener() instead") void AddTableListener(StringRef key, ITableListener* listener, bool immediateNotify) override; WPI_DEPRECATED("use AddEntryListener() instead") void AddTableListenerEx(StringRef key, ITableListener* listener, unsigned int flags) override; WPI_DEPRECATED("use AddSubTableListener(TableListener, bool) instead") void AddSubTableListener(ITableListener* listener) override; WPI_DEPRECATED("use AddSubTableListener(TableListener, bool) instead") void AddSubTableListener(ITableListener* listener, bool localNotify) override; WPI_DEPRECATED("use RemoveTableListener(NT_EntryListener) instead") void RemoveTableListener(ITableListener* listener) override; /** * 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 GetSubTable(const Twine& key) const override; /** * 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 */ bool ContainsKey(const Twine& key) const override; /** * 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 */ bool ContainsSubTable(const Twine& key) const override; /** * Gets all keys in the table (not including sub-tables). * * @param types bitmask of types; 0 is treated as a "don't care". * @return keys currently in the table */ std::vector GetKeys(int types = 0) const override; /** * Gets the names of all subtables in the table. * * @return subtables currently in the table */ std::vector GetSubTables() const override; /** * Makes a key's value persistent through program restarts. * * @param key the key to make persistent */ void SetPersistent(StringRef key) override; /** * Stop making a key's value persistent through program restarts. * The key cannot be null. * * @param key the key name */ void ClearPersistent(StringRef key) override; /** * Returns whether the value is persistent through program restarts. * The key cannot be null. * * @param key the key name */ bool IsPersistent(StringRef key) const override; /** * 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(StringRef key, unsigned int flags) override; /** * 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(StringRef key, unsigned int flags) override; /** * 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(StringRef key) const override; /** * Deletes the specified key in this table. * * @param key the key name */ void Delete(const Twine& key) override; /** * Put a number in the table * * @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 */ bool PutNumber(StringRef key, double value) override; /** * Gets the current value in the table, setting it if it does not exist. * * @param key the key * @param defaultValue the default value to set if key doesn't exist. * @returns False if the table key exists with a different type */ bool SetDefaultNumber(StringRef key, double defaultValue) override; /** * 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 */ double GetNumber(StringRef key, double defaultValue) const override; /** * Put a string in the table * * @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 */ bool PutString(StringRef key, StringRef value) override; /** * Gets the current value in the table, setting it if it does not exist. * * @param key the key * @param defaultValue the default value to set if key doesn't exist. * @returns False if the table key exists with a different type */ bool SetDefaultString(StringRef key, StringRef defaultValue) override; /** * Gets the string associated with the given name. If the key does not * exist or is of different type, it will return the default value. * * @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 */ std::string GetString(StringRef key, StringRef defaultValue) const override; /** * Put a boolean in the table * * @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 */ bool PutBoolean(StringRef key, bool value) override; /** * Gets the current value in the table, setting it if it does not exist. * * @param key the key * @param defaultValue the default value to set if key doesn't exist. * @returns False if the table key exists with a different type */ bool SetDefaultBoolean(StringRef key, bool defaultValue) override; /** * Gets the boolean associated with the given name. If the key does not * exist or is of different type, it will return the default value. * * @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 */ bool GetBoolean(StringRef key, bool defaultValue) const override; /** * Put a boolean array in the table * * @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 * * @note The array must be of int's rather than of bool's because * std::vector is special-cased in C++. 0 is false, any * non-zero value is true. */ bool PutBooleanArray(StringRef key, ArrayRef value) override; /** * Gets the current value in the table, setting it if it does not exist. * * @param key the key * @param defaultValue the default value to set if key doesn't exist. * @return False if the table key exists with a different type */ bool SetDefaultBooleanArray(StringRef key, ArrayRef defaultValue) override; /** * Returns the boolean array the key maps to. If the key does not exist or is * of different type, it will return the default value. * * @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 * * @note This makes a copy of the array. If the overhead of this is a * concern, use GetValue() instead. * * @note The returned array is std::vector instead of std::vector * because std::vector is special-cased in C++. 0 is false, any * non-zero value is true. */ std::vector GetBooleanArray(StringRef key, ArrayRef defaultValue) const override; /** * Put a number array in the table * * @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 */ bool PutNumberArray(StringRef key, ArrayRef value) override; /** * Gets the current value in the table, setting it if it does not exist. * * @param key the key * @param defaultValue the default value to set if key doesn't exist. * @returns False if the table key exists with a different type */ bool SetDefaultNumberArray(StringRef key, ArrayRef defaultValue) override; /** * Returns the number array the key maps to. If the key does not exist or is * of different type, it will return the default value. * * @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 * * @note This makes a copy of the array. If the overhead of this is a * concern, use GetValue() instead. */ std::vector GetNumberArray( StringRef key, ArrayRef defaultValue) const override; /** * Put a string array in the table * * @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 */ bool PutStringArray(StringRef key, ArrayRef value) override; /** * Gets the current value in the table, setting it if it does not exist. * * @param key the key * @param defaultValue the default value to set if key doesn't exist. * @returns False if the table key exists with a different type */ bool SetDefaultStringArray(StringRef key, ArrayRef defaultValue) override; /** * Returns the string array the key maps to. If the key does not exist or is * of different type, it will return the default value. * * @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 * * @note This makes a copy of the array. If the overhead of this is a * concern, use GetValue() instead. */ std::vector GetStringArray( StringRef key, ArrayRef defaultValue) const override; /** * Put a raw value (byte array) in the table * * @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 */ bool PutRaw(StringRef key, StringRef value) override; /** * Gets the current value in the table, setting it if it does not exist. * * @param key the key * @param defaultValue the default value to set if key doesn't exist. * @return False if the table key exists with a different type */ bool SetDefaultRaw(StringRef key, StringRef defaultValue) override; /** * Returns the raw value (byte array) the key maps to. If the key does not * exist or is of different type, it will return the default value. * * @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 * * @note This makes a copy of the raw contents. If the overhead of this is a * concern, use GetValue() instead. */ std::string GetRaw(StringRef key, StringRef defaultValue) const override; /** * Put a value in the table * * @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 */ bool PutValue(const Twine& key, std::shared_ptr value) override; /** * Gets the current value in the table, setting it if it does not exist. * * @param key the key * @param defaultValue the default value to set if key doesn't exist. * @return False if the table key exists with a different type */ bool SetDefaultValue(const Twine& key, std::shared_ptr defaultValue) override; /** * 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, or nullptr if the key * does not exist */ std::shared_ptr GetValue(const Twine& key) const override; /** * Gets the full path of this table. Does not include the trailing "/". * * @return The path (e.g "", "/foo"). */ StringRef GetPath() const override; /** * Save table values to a file. The file format used is identical to * that used for SavePersistent. * * @param filename filename * @return error string, or nullptr if successful */ const char* SaveEntries(const Twine& filename) const; /** * Load table values from a file. The file format used is identical to * that used for SavePersistent / LoadPersistent. * * @param filename filename * @param warn callback function for warnings * @return error string, or nullptr if successful */ const char* LoadEntries( const Twine& filename, std::function warn); }; #ifdef __GNUC__ #pragma GCC diagnostic pop #elif _WIN32 #pragma warning(pop) #endif } // namespace nt // For backwards compatability #ifndef NAMESPACED_NT using nt::NetworkTable; // NOLINT #endif #endif // NTCORE_NETWORKTABLES_NETWORKTABLE_H_