Files
allwpilib/ntcore/src/main/native/cpp/Dispatcher.h

169 lines
5.0 KiB
C
Raw Normal View History

// Copyright (c) FIRST and other WPILib contributors.
// Open Source Software; you can modify and/or share it under the terms of
// the WPILib BSD license file in the root directory of this project.
2015-07-16 22:55:50 -07:00
2017-08-19 23:08:27 -07:00
#ifndef NTCORE_DISPATCHER_H_
#define NTCORE_DISPATCHER_H_
2015-07-16 22:55:50 -07:00
#include <atomic>
#include <functional>
2015-07-16 22:55:50 -07:00
#include <memory>
#include <string>
#include <string_view>
#include <thread>
2017-08-19 23:08:27 -07:00
#include <utility>
2015-07-16 22:55:50 -07:00
#include <vector>
2021-12-12 20:09:57 -08:00
#include <wpi/DataLog.h>
#include <wpi/UidVector.h>
#include <wpi/condition_variable.h>
#include <wpi/mutex.h>
#include <wpi/span.h>
2015-07-16 22:55:50 -07:00
Implement independent instances. Previously, most of the classes were implemented as singletons so only one instance was possible. This change adds an instance handle-based API. In Java, this API is located in a different package than the old API (edu.wpi.first.networktables). Backwards compatibility with ITable and the old NetworkTable API is largely maintained, but a handful of classes have moved to the new package in Java (ConnectionInfo and PersistentException), and the old JNI has been completed replaced. Also: - Move SetTeam implementation to Dispatcher. - Consistently pass time through Java and C++ Value API. - Rename nt_Value.h to NetworkTableValue.h for consistency with Java. - Improve documentation - Make C++ and Java APIs more consistent - Document RPC functions and support RPC in Java. - Add polling features for entry and connection listeners and use them to move callback threads to Java level. - Remove thread start and stop hooks (as polling is available). - Make Notifiers, RpcServer, Dispatcher, and Storage mockable. - Set NOTIFY_NEW on immediate entry notifications. - Make GetTable("/") and GetTable("") equivalent. - Generate local notification for flags update when loading persistent file. And many unit test updates/changes: - Use InitGoogleMock instead of InitGoogleTest in test main. - Move test printers to TestPrinter.h/cpp. - Provide printers for StringRef, EntryNotifier, and Handle. - StorageTest: Check notifications. - Add entry notifier unit tests. - Storage: Add test for incoming entry assignment. - Update connection listener tests. - Add entry listener unit tests. Fixes #11, #140, #189, #190, #192, #193, #221
2017-04-23 10:26:17 -07:00
#include "IDispatcher.h"
#include "INetworkConnection.h"
2015-07-16 22:55:50 -07:00
namespace wpi {
Implement independent instances. Previously, most of the classes were implemented as singletons so only one instance was possible. This change adds an instance handle-based API. In Java, this API is located in a different package than the old API (edu.wpi.first.networktables). Backwards compatibility with ITable and the old NetworkTable API is largely maintained, but a handful of classes have moved to the new package in Java (ConnectionInfo and PersistentException), and the old JNI has been completed replaced. Also: - Move SetTeam implementation to Dispatcher. - Consistently pass time through Java and C++ Value API. - Rename nt_Value.h to NetworkTableValue.h for consistency with Java. - Improve documentation - Make C++ and Java APIs more consistent - Document RPC functions and support RPC in Java. - Add polling features for entry and connection listeners and use them to move callback threads to Java level. - Remove thread start and stop hooks (as polling is available). - Make Notifiers, RpcServer, Dispatcher, and Storage mockable. - Set NOTIFY_NEW on immediate entry notifications. - Make GetTable("/") and GetTable("") equivalent. - Generate local notification for flags update when loading persistent file. And many unit test updates/changes: - Use InitGoogleMock instead of InitGoogleTest in test main. - Move test printers to TestPrinter.h/cpp. - Provide printers for StringRef, EntryNotifier, and Handle. - StorageTest: Check notifications. - Add entry notifier unit tests. - Storage: Add test for incoming entry assignment. - Update connection listener tests. - Add entry listener unit tests. Fixes #11, #140, #189, #190, #192, #193, #221
2017-04-23 10:26:17 -07:00
class Logger;
class NetworkAcceptor;
class NetworkStream;
2017-08-19 23:08:27 -07:00
} // namespace wpi
2015-07-17 22:39:36 -07:00
namespace nt {
2015-07-16 22:55:50 -07:00
Implement independent instances. Previously, most of the classes were implemented as singletons so only one instance was possible. This change adds an instance handle-based API. In Java, this API is located in a different package than the old API (edu.wpi.first.networktables). Backwards compatibility with ITable and the old NetworkTable API is largely maintained, but a handful of classes have moved to the new package in Java (ConnectionInfo and PersistentException), and the old JNI has been completed replaced. Also: - Move SetTeam implementation to Dispatcher. - Consistently pass time through Java and C++ Value API. - Rename nt_Value.h to NetworkTableValue.h for consistency with Java. - Improve documentation - Make C++ and Java APIs more consistent - Document RPC functions and support RPC in Java. - Add polling features for entry and connection listeners and use them to move callback threads to Java level. - Remove thread start and stop hooks (as polling is available). - Make Notifiers, RpcServer, Dispatcher, and Storage mockable. - Set NOTIFY_NEW on immediate entry notifications. - Make GetTable("/") and GetTable("") equivalent. - Generate local notification for flags update when loading persistent file. And many unit test updates/changes: - Use InitGoogleMock instead of InitGoogleTest in test main. - Move test printers to TestPrinter.h/cpp. - Provide printers for StringRef, EntryNotifier, and Handle. - StorageTest: Check notifications. - Add entry notifier unit tests. - Storage: Add test for incoming entry assignment. - Update connection listener tests. - Add entry listener unit tests. Fixes #11, #140, #189, #190, #192, #193, #221
2017-04-23 10:26:17 -07:00
class IConnectionNotifier;
class IStorage;
class NetworkConnection;
Implement independent instances. Previously, most of the classes were implemented as singletons so only one instance was possible. This change adds an instance handle-based API. In Java, this API is located in a different package than the old API (edu.wpi.first.networktables). Backwards compatibility with ITable and the old NetworkTable API is largely maintained, but a handful of classes have moved to the new package in Java (ConnectionInfo and PersistentException), and the old JNI has been completed replaced. Also: - Move SetTeam implementation to Dispatcher. - Consistently pass time through Java and C++ Value API. - Rename nt_Value.h to NetworkTableValue.h for consistency with Java. - Improve documentation - Make C++ and Java APIs more consistent - Document RPC functions and support RPC in Java. - Add polling features for entry and connection listeners and use them to move callback threads to Java level. - Remove thread start and stop hooks (as polling is available). - Make Notifiers, RpcServer, Dispatcher, and Storage mockable. - Set NOTIFY_NEW on immediate entry notifications. - Make GetTable("/") and GetTable("") equivalent. - Generate local notification for flags update when loading persistent file. And many unit test updates/changes: - Use InitGoogleMock instead of InitGoogleTest in test main. - Move test printers to TestPrinter.h/cpp. - Provide printers for StringRef, EntryNotifier, and Handle. - StorageTest: Check notifications. - Add entry notifier unit tests. - Storage: Add test for incoming entry assignment. - Update connection listener tests. - Add entry listener unit tests. Fixes #11, #140, #189, #190, #192, #193, #221
2017-04-23 10:26:17 -07:00
class DispatcherBase : public IDispatcher {
friend class DispatcherTest;
2015-07-16 22:55:50 -07:00
public:
using Connector = std::function<std::unique_ptr<wpi::NetworkStream>()>;
Implement independent instances. Previously, most of the classes were implemented as singletons so only one instance was possible. This change adds an instance handle-based API. In Java, this API is located in a different package than the old API (edu.wpi.first.networktables). Backwards compatibility with ITable and the old NetworkTable API is largely maintained, but a handful of classes have moved to the new package in Java (ConnectionInfo and PersistentException), and the old JNI has been completed replaced. Also: - Move SetTeam implementation to Dispatcher. - Consistently pass time through Java and C++ Value API. - Rename nt_Value.h to NetworkTableValue.h for consistency with Java. - Improve documentation - Make C++ and Java APIs more consistent - Document RPC functions and support RPC in Java. - Add polling features for entry and connection listeners and use them to move callback threads to Java level. - Remove thread start and stop hooks (as polling is available). - Make Notifiers, RpcServer, Dispatcher, and Storage mockable. - Set NOTIFY_NEW on immediate entry notifications. - Make GetTable("/") and GetTable("") equivalent. - Generate local notification for flags update when loading persistent file. And many unit test updates/changes: - Use InitGoogleMock instead of InitGoogleTest in test main. - Move test printers to TestPrinter.h/cpp. - Provide printers for StringRef, EntryNotifier, and Handle. - StorageTest: Check notifications. - Add entry notifier unit tests. - Storage: Add test for incoming entry assignment. - Update connection listener tests. - Add entry listener unit tests. Fixes #11, #140, #189, #190, #192, #193, #221
2017-04-23 10:26:17 -07:00
DispatcherBase(IStorage& storage, IConnectionNotifier& notifier,
wpi::Logger& logger);
~DispatcherBase() override;
2015-07-16 22:55:50 -07:00
unsigned int GetNetworkMode() const;
void StartLocal();
void StartServer(std::string_view persist_filename,
std::unique_ptr<wpi::NetworkAcceptor> acceptor);
void StartClient();
2015-07-16 22:55:50 -07:00
void Stop();
void SetUpdateRate(double interval);
void SetIdentity(std::string_view name);
2015-07-17 22:39:36 -07:00
void Flush();
2015-08-02 10:47:05 -07:00
std::vector<ConnectionInfo> GetConnections() const;
Implement independent instances. Previously, most of the classes were implemented as singletons so only one instance was possible. This change adds an instance handle-based API. In Java, this API is located in a different package than the old API (edu.wpi.first.networktables). Backwards compatibility with ITable and the old NetworkTable API is largely maintained, but a handful of classes have moved to the new package in Java (ConnectionInfo and PersistentException), and the old JNI has been completed replaced. Also: - Move SetTeam implementation to Dispatcher. - Consistently pass time through Java and C++ Value API. - Rename nt_Value.h to NetworkTableValue.h for consistency with Java. - Improve documentation - Make C++ and Java APIs more consistent - Document RPC functions and support RPC in Java. - Add polling features for entry and connection listeners and use them to move callback threads to Java level. - Remove thread start and stop hooks (as polling is available). - Make Notifiers, RpcServer, Dispatcher, and Storage mockable. - Set NOTIFY_NEW on immediate entry notifications. - Make GetTable("/") and GetTable("") equivalent. - Generate local notification for flags update when loading persistent file. And many unit test updates/changes: - Use InitGoogleMock instead of InitGoogleTest in test main. - Move test printers to TestPrinter.h/cpp. - Provide printers for StringRef, EntryNotifier, and Handle. - StorageTest: Check notifications. - Add entry notifier unit tests. - Storage: Add test for incoming entry assignment. - Update connection listener tests. - Add entry listener unit tests. Fixes #11, #140, #189, #190, #192, #193, #221
2017-04-23 10:26:17 -07:00
bool IsConnected() const;
2015-07-17 22:39:36 -07:00
unsigned int AddListener(
std::function<void(const ConnectionNotification& event)> callback,
bool immediate_notify) const;
unsigned int AddPolledListener(unsigned int poller_uid,
bool immediate_notify) const;
2021-12-12 20:09:57 -08:00
unsigned int StartDataLog(wpi::log::DataLog& log, std::string_view name);
void StopDataLog(unsigned int logger);
void SetConnector(Connector connector);
void SetConnectorOverride(Connector connector);
void ClearConnectorOverride();
2015-07-17 22:39:36 -07:00
bool active() const { return m_active; }
2015-07-16 22:55:50 -07:00
DispatcherBase(const DispatcherBase&) = delete;
DispatcherBase& operator=(const DispatcherBase&) = delete;
2015-07-16 22:55:50 -07:00
private:
2015-07-16 22:55:50 -07:00
void DispatchThreadMain();
void ServerThreadMain();
void ClientThreadMain();
2015-07-16 22:55:50 -07:00
2015-07-31 20:32:52 -07:00
bool ClientHandshake(
NetworkConnection& conn,
std::function<std::shared_ptr<Message>()> get_msg,
std::function<void(wpi::span<std::shared_ptr<Message>>)> send_msgs);
2015-07-31 20:32:52 -07:00
bool ServerHandshake(
NetworkConnection& conn,
std::function<std::shared_ptr<Message>()> get_msg,
std::function<void(wpi::span<std::shared_ptr<Message>>)> send_msgs);
2015-07-31 20:32:52 -07:00
void ClientReconnect(unsigned int proto_rev = 0x0300);
2015-07-17 22:39:36 -07:00
void QueueOutgoing(std::shared_ptr<Message> msg, INetworkConnection* only,
INetworkConnection* except) override;
2015-07-17 22:39:36 -07:00
Implement independent instances. Previously, most of the classes were implemented as singletons so only one instance was possible. This change adds an instance handle-based API. In Java, this API is located in a different package than the old API (edu.wpi.first.networktables). Backwards compatibility with ITable and the old NetworkTable API is largely maintained, but a handful of classes have moved to the new package in Java (ConnectionInfo and PersistentException), and the old JNI has been completed replaced. Also: - Move SetTeam implementation to Dispatcher. - Consistently pass time through Java and C++ Value API. - Rename nt_Value.h to NetworkTableValue.h for consistency with Java. - Improve documentation - Make C++ and Java APIs more consistent - Document RPC functions and support RPC in Java. - Add polling features for entry and connection listeners and use them to move callback threads to Java level. - Remove thread start and stop hooks (as polling is available). - Make Notifiers, RpcServer, Dispatcher, and Storage mockable. - Set NOTIFY_NEW on immediate entry notifications. - Make GetTable("/") and GetTable("") equivalent. - Generate local notification for flags update when loading persistent file. And many unit test updates/changes: - Use InitGoogleMock instead of InitGoogleTest in test main. - Move test printers to TestPrinter.h/cpp. - Provide printers for StringRef, EntryNotifier, and Handle. - StorageTest: Check notifications. - Add entry notifier unit tests. - Storage: Add test for incoming entry assignment. - Update connection listener tests. - Add entry listener unit tests. Fixes #11, #140, #189, #190, #192, #193, #221
2017-04-23 10:26:17 -07:00
IStorage& m_storage;
IConnectionNotifier& m_notifier;
unsigned int m_networkMode = NT_NET_MODE_NONE;
std::string m_persist_filename;
2015-07-16 22:55:50 -07:00
std::thread m_dispatch_thread;
std::thread m_clientserver_thread;
std::unique_ptr<wpi::NetworkAcceptor> m_server_acceptor;
Connector m_client_connector_override;
Connector m_client_connector;
Implement independent instances. Previously, most of the classes were implemented as singletons so only one instance was possible. This change adds an instance handle-based API. In Java, this API is located in a different package than the old API (edu.wpi.first.networktables). Backwards compatibility with ITable and the old NetworkTable API is largely maintained, but a handful of classes have moved to the new package in Java (ConnectionInfo and PersistentException), and the old JNI has been completed replaced. Also: - Move SetTeam implementation to Dispatcher. - Consistently pass time through Java and C++ Value API. - Rename nt_Value.h to NetworkTableValue.h for consistency with Java. - Improve documentation - Make C++ and Java APIs more consistent - Document RPC functions and support RPC in Java. - Add polling features for entry and connection listeners and use them to move callback threads to Java level. - Remove thread start and stop hooks (as polling is available). - Make Notifiers, RpcServer, Dispatcher, and Storage mockable. - Set NOTIFY_NEW on immediate entry notifications. - Make GetTable("/") and GetTable("") equivalent. - Generate local notification for flags update when loading persistent file. And many unit test updates/changes: - Use InitGoogleMock instead of InitGoogleTest in test main. - Move test printers to TestPrinter.h/cpp. - Provide printers for StringRef, EntryNotifier, and Handle. - StorageTest: Check notifications. - Add entry notifier unit tests. - Storage: Add test for incoming entry assignment. - Update connection listener tests. - Add entry listener unit tests. Fixes #11, #140, #189, #190, #192, #193, #221
2017-04-23 10:26:17 -07:00
uint8_t m_connections_uid = 0;
2015-07-17 22:39:36 -07:00
// Mutex for user-accessible items
mutable wpi::mutex m_user_mutex;
std::vector<std::shared_ptr<INetworkConnection>> m_connections;
2015-07-16 22:55:50 -07:00
std::string m_identity;
std::atomic_bool m_active; // set to false to terminate threads
2015-07-17 22:39:36 -07:00
std::atomic_uint m_update_rate; // periodic dispatch update rate, in ms
// Condition variable for forced dispatch wakeup (flush)
wpi::mutex m_flush_mutex;
wpi::condition_variable m_flush_cv;
uint64_t m_last_flush = 0;
bool m_do_flush = false;
2015-07-17 22:39:36 -07:00
// Condition variable for client reconnect (uses user mutex)
wpi::condition_variable m_reconnect_cv;
unsigned int m_reconnect_proto_rev = 0x0300;
bool m_do_reconnect = true;
Implement independent instances. Previously, most of the classes were implemented as singletons so only one instance was possible. This change adds an instance handle-based API. In Java, this API is located in a different package than the old API (edu.wpi.first.networktables). Backwards compatibility with ITable and the old NetworkTable API is largely maintained, but a handful of classes have moved to the new package in Java (ConnectionInfo and PersistentException), and the old JNI has been completed replaced. Also: - Move SetTeam implementation to Dispatcher. - Consistently pass time through Java and C++ Value API. - Rename nt_Value.h to NetworkTableValue.h for consistency with Java. - Improve documentation - Make C++ and Java APIs more consistent - Document RPC functions and support RPC in Java. - Add polling features for entry and connection listeners and use them to move callback threads to Java level. - Remove thread start and stop hooks (as polling is available). - Make Notifiers, RpcServer, Dispatcher, and Storage mockable. - Set NOTIFY_NEW on immediate entry notifications. - Make GetTable("/") and GetTable("") equivalent. - Generate local notification for flags update when loading persistent file. And many unit test updates/changes: - Use InitGoogleMock instead of InitGoogleTest in test main. - Move test printers to TestPrinter.h/cpp. - Provide printers for StringRef, EntryNotifier, and Handle. - StorageTest: Check notifications. - Add entry notifier unit tests. - Storage: Add test for incoming entry assignment. - Update connection listener tests. - Add entry listener unit tests. Fixes #11, #140, #189, #190, #192, #193, #221
2017-04-23 10:26:17 -07:00
2021-12-12 20:09:57 -08:00
struct DataLogger {
DataLogger() = default;
DataLogger(wpi::log::DataLog& log, std::string_view name, int64_t time)
: entry{log, name,
"{\"schema\":\"NTConnectionInfo\",\"source\":\"NT\"}", "json",
time} {}
explicit operator bool() const { return static_cast<bool>(entry); }
wpi::log::StringLogEntry entry;
unsigned int notifier = 0;
};
wpi::UidVector<DataLogger, 4> m_dataloggers;
Implement independent instances. Previously, most of the classes were implemented as singletons so only one instance was possible. This change adds an instance handle-based API. In Java, this API is located in a different package than the old API (edu.wpi.first.networktables). Backwards compatibility with ITable and the old NetworkTable API is largely maintained, but a handful of classes have moved to the new package in Java (ConnectionInfo and PersistentException), and the old JNI has been completed replaced. Also: - Move SetTeam implementation to Dispatcher. - Consistently pass time through Java and C++ Value API. - Rename nt_Value.h to NetworkTableValue.h for consistency with Java. - Improve documentation - Make C++ and Java APIs more consistent - Document RPC functions and support RPC in Java. - Add polling features for entry and connection listeners and use them to move callback threads to Java level. - Remove thread start and stop hooks (as polling is available). - Make Notifiers, RpcServer, Dispatcher, and Storage mockable. - Set NOTIFY_NEW on immediate entry notifications. - Make GetTable("/") and GetTable("") equivalent. - Generate local notification for flags update when loading persistent file. And many unit test updates/changes: - Use InitGoogleMock instead of InitGoogleTest in test main. - Move test printers to TestPrinter.h/cpp. - Provide printers for StringRef, EntryNotifier, and Handle. - StorageTest: Check notifications. - Add entry notifier unit tests. - Storage: Add test for incoming entry assignment. - Update connection listener tests. - Add entry listener unit tests. Fixes #11, #140, #189, #190, #192, #193, #221
2017-04-23 10:26:17 -07:00
protected:
wpi::Logger& m_logger;
};
class Dispatcher : public DispatcherBase {
friend class DispatcherTest;
public:
Implement independent instances. Previously, most of the classes were implemented as singletons so only one instance was possible. This change adds an instance handle-based API. In Java, this API is located in a different package than the old API (edu.wpi.first.networktables). Backwards compatibility with ITable and the old NetworkTable API is largely maintained, but a handful of classes have moved to the new package in Java (ConnectionInfo and PersistentException), and the old JNI has been completed replaced. Also: - Move SetTeam implementation to Dispatcher. - Consistently pass time through Java and C++ Value API. - Rename nt_Value.h to NetworkTableValue.h for consistency with Java. - Improve documentation - Make C++ and Java APIs more consistent - Document RPC functions and support RPC in Java. - Add polling features for entry and connection listeners and use them to move callback threads to Java level. - Remove thread start and stop hooks (as polling is available). - Make Notifiers, RpcServer, Dispatcher, and Storage mockable. - Set NOTIFY_NEW on immediate entry notifications. - Make GetTable("/") and GetTable("") equivalent. - Generate local notification for flags update when loading persistent file. And many unit test updates/changes: - Use InitGoogleMock instead of InitGoogleTest in test main. - Move test printers to TestPrinter.h/cpp. - Provide printers for StringRef, EntryNotifier, and Handle. - StorageTest: Check notifications. - Add entry notifier unit tests. - Storage: Add test for incoming entry assignment. - Update connection listener tests. - Add entry listener unit tests. Fixes #11, #140, #189, #190, #192, #193, #221
2017-04-23 10:26:17 -07:00
Dispatcher(IStorage& storage, IConnectionNotifier& notifier,
wpi::Logger& logger)
: DispatcherBase(storage, notifier, logger) {}
void StartServer(std::string_view persist_filename,
const char* listen_address, unsigned int port);
void SetServer(const char* server_name, unsigned int port);
void SetServer(
wpi::span<const std::pair<std::string_view, unsigned int>> servers);
Implement independent instances. Previously, most of the classes were implemented as singletons so only one instance was possible. This change adds an instance handle-based API. In Java, this API is located in a different package than the old API (edu.wpi.first.networktables). Backwards compatibility with ITable and the old NetworkTable API is largely maintained, but a handful of classes have moved to the new package in Java (ConnectionInfo and PersistentException), and the old JNI has been completed replaced. Also: - Move SetTeam implementation to Dispatcher. - Consistently pass time through Java and C++ Value API. - Rename nt_Value.h to NetworkTableValue.h for consistency with Java. - Improve documentation - Make C++ and Java APIs more consistent - Document RPC functions and support RPC in Java. - Add polling features for entry and connection listeners and use them to move callback threads to Java level. - Remove thread start and stop hooks (as polling is available). - Make Notifiers, RpcServer, Dispatcher, and Storage mockable. - Set NOTIFY_NEW on immediate entry notifications. - Make GetTable("/") and GetTable("") equivalent. - Generate local notification for flags update when loading persistent file. And many unit test updates/changes: - Use InitGoogleMock instead of InitGoogleTest in test main. - Move test printers to TestPrinter.h/cpp. - Provide printers for StringRef, EntryNotifier, and Handle. - StorageTest: Check notifications. - Add entry notifier unit tests. - Storage: Add test for incoming entry assignment. - Update connection listener tests. - Add entry listener unit tests. Fixes #11, #140, #189, #190, #192, #193, #221
2017-04-23 10:26:17 -07:00
void SetServerTeam(unsigned int team, unsigned int port);
void SetServerOverride(const char* server_name, unsigned int port);
void ClearServerOverride();
2015-07-16 22:55:50 -07:00
};
} // namespace nt
2015-07-16 22:55:50 -07:00
2017-08-19 23:08:27 -07:00
#endif // NTCORE_DISPATCHER_H_