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
|
|
|
/*----------------------------------------------------------------------------*/
|
2018-01-01 17:29:13 -08:00
|
|
|
/* Copyright (c) FIRST 2017-2018. All Rights Reserved. */
|
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
|
|
|
/* 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. */
|
|
|
|
|
/*----------------------------------------------------------------------------*/
|
|
|
|
|
|
2017-08-19 23:08:27 -07:00
|
|
|
#ifndef NTCORE_CALLBACKMANAGER_H_
|
|
|
|
|
#define NTCORE_CALLBACKMANAGER_H_
|
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 <atomic>
|
|
|
|
|
#include <climits>
|
|
|
|
|
#include <functional>
|
2017-08-19 23:08:27 -07:00
|
|
|
#include <memory>
|
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 <queue>
|
|
|
|
|
#include <utility>
|
2017-08-19 23:08:27 -07:00
|
|
|
#include <vector>
|
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
|
|
|
|
2018-04-29 23:33:19 -07:00
|
|
|
#include <wpi/SafeThread.h>
|
|
|
|
|
#include <wpi/UidVector.h>
|
|
|
|
|
#include <wpi/condition_variable.h>
|
|
|
|
|
#include <wpi/mutex.h>
|
|
|
|
|
#include <wpi/raw_ostream.h>
|
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
|
|
|
|
|
|
|
|
namespace nt {
|
|
|
|
|
|
|
|
|
|
namespace impl {
|
|
|
|
|
|
|
|
|
|
template <typename Callback>
|
|
|
|
|
class ListenerData {
|
|
|
|
|
public:
|
|
|
|
|
ListenerData() = default;
|
2017-08-19 23:08:27 -07:00
|
|
|
explicit ListenerData(Callback callback_) : callback(callback_) {}
|
|
|
|
|
explicit ListenerData(unsigned int poller_uid_) : poller_uid(poller_uid_) {}
|
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
|
|
|
|
|
|
|
|
explicit operator bool() const { return callback || poller_uid != UINT_MAX; }
|
|
|
|
|
|
|
|
|
|
Callback callback;
|
|
|
|
|
unsigned int poller_uid = UINT_MAX;
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
// CRTP callback manager thread
|
|
|
|
|
// @tparam Derived derived class
|
|
|
|
|
// @tparam NotifierData data buffered for each callback
|
|
|
|
|
// @tparam ListenerData data stored for each listener
|
|
|
|
|
// Derived must define the following functions:
|
|
|
|
|
// bool Matches(const ListenerData& listener, const NotifierData& data);
|
|
|
|
|
// void SetListener(NotifierData* data, unsigned int listener_uid);
|
|
|
|
|
// void DoCallback(Callback callback, const NotifierData& data);
|
|
|
|
|
template <typename Derived, typename TUserInfo,
|
|
|
|
|
typename TListenerData =
|
|
|
|
|
ListenerData<std::function<void(const TUserInfo& info)>>,
|
|
|
|
|
typename TNotifierData = TUserInfo>
|
|
|
|
|
class CallbackThread : public wpi::SafeThread {
|
|
|
|
|
public:
|
|
|
|
|
typedef TUserInfo UserInfo;
|
|
|
|
|
typedef TNotifierData NotifierData;
|
|
|
|
|
typedef TListenerData ListenerData;
|
|
|
|
|
|
|
|
|
|
~CallbackThread() {
|
|
|
|
|
// Wake up any blocked pollers
|
2017-08-19 23:08:27 -07:00
|
|
|
for (size_t i = 0; i < m_pollers.size(); ++i) {
|
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
|
|
|
if (auto poller = m_pollers[i]) poller->Terminate();
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void Main() override;
|
|
|
|
|
|
|
|
|
|
wpi::UidVector<ListenerData, 64> m_listeners;
|
|
|
|
|
|
|
|
|
|
std::queue<std::pair<unsigned int, NotifierData>> m_queue;
|
2017-11-13 09:51:05 -08:00
|
|
|
wpi::condition_variable m_queue_empty;
|
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
|
|
|
|
|
|
|
|
struct Poller {
|
|
|
|
|
void Terminate() {
|
|
|
|
|
{
|
2017-11-13 09:51:05 -08:00
|
|
|
std::lock_guard<wpi::mutex> lock(poll_mutex);
|
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
|
|
|
terminating = true;
|
|
|
|
|
}
|
|
|
|
|
poll_cond.notify_all();
|
|
|
|
|
}
|
|
|
|
|
std::queue<NotifierData> poll_queue;
|
2017-11-13 09:51:05 -08:00
|
|
|
wpi::mutex poll_mutex;
|
|
|
|
|
wpi::condition_variable poll_cond;
|
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 terminating = false;
|
|
|
|
|
bool cancelling = false;
|
|
|
|
|
};
|
|
|
|
|
wpi::UidVector<std::shared_ptr<Poller>, 64> m_pollers;
|
|
|
|
|
|
|
|
|
|
// Must be called with m_mutex held
|
|
|
|
|
template <typename... Args>
|
|
|
|
|
void SendPoller(unsigned int poller_uid, Args&&... args) {
|
|
|
|
|
if (poller_uid > m_pollers.size()) return;
|
|
|
|
|
auto poller = m_pollers[poller_uid];
|
|
|
|
|
if (!poller) return;
|
|
|
|
|
{
|
2017-11-13 09:51:05 -08:00
|
|
|
std::lock_guard<wpi::mutex> lock(poller->poll_mutex);
|
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
|
|
|
poller->poll_queue.emplace(std::forward<Args>(args)...);
|
|
|
|
|
}
|
|
|
|
|
poller->poll_cond.notify_one();
|
|
|
|
|
}
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
template <typename Derived, typename TUserInfo, typename TListenerData,
|
|
|
|
|
typename TNotifierData>
|
|
|
|
|
void CallbackThread<Derived, TUserInfo, TListenerData, TNotifierData>::Main() {
|
2017-11-13 09:51:05 -08:00
|
|
|
std::unique_lock<wpi::mutex> lock(m_mutex);
|
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
|
|
|
while (m_active) {
|
|
|
|
|
while (m_queue.empty()) {
|
|
|
|
|
m_cond.wait(lock);
|
|
|
|
|
if (!m_active) return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
while (!m_queue.empty()) {
|
|
|
|
|
if (!m_active) return;
|
|
|
|
|
auto item = std::move(m_queue.front());
|
|
|
|
|
|
|
|
|
|
if (item.first != UINT_MAX) {
|
|
|
|
|
if (item.first < m_listeners.size()) {
|
|
|
|
|
auto& listener = m_listeners[item.first];
|
|
|
|
|
if (listener &&
|
|
|
|
|
static_cast<Derived*>(this)->Matches(listener, item.second)) {
|
|
|
|
|
static_cast<Derived*>(this)->SetListener(&item.second, item.first);
|
|
|
|
|
if (listener.callback) {
|
|
|
|
|
lock.unlock();
|
|
|
|
|
static_cast<Derived*>(this)->DoCallback(listener.callback,
|
|
|
|
|
item.second);
|
|
|
|
|
lock.lock();
|
|
|
|
|
} else if (listener.poller_uid != UINT_MAX) {
|
|
|
|
|
SendPoller(listener.poller_uid, std::move(item.second));
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
} else {
|
|
|
|
|
// Use index because iterator might get invalidated.
|
|
|
|
|
for (size_t i = 0; i < m_listeners.size(); ++i) {
|
|
|
|
|
auto& listener = m_listeners[i];
|
|
|
|
|
if (!listener) continue;
|
|
|
|
|
if (!static_cast<Derived*>(this)->Matches(listener, item.second))
|
|
|
|
|
continue;
|
|
|
|
|
static_cast<Derived*>(this)->SetListener(&item.second, i);
|
|
|
|
|
if (listener.callback) {
|
|
|
|
|
lock.unlock();
|
|
|
|
|
static_cast<Derived*>(this)->DoCallback(listener.callback,
|
|
|
|
|
item.second);
|
|
|
|
|
lock.lock();
|
|
|
|
|
} else if (listener.poller_uid != UINT_MAX) {
|
|
|
|
|
SendPoller(listener.poller_uid, item.second);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
m_queue.pop();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
m_queue_empty.notify_all();
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
} // namespace impl
|
|
|
|
|
|
|
|
|
|
// CRTP callback manager
|
|
|
|
|
// @tparam Derived derived class
|
|
|
|
|
// @tparam Thread custom thread (must be derived from impl::CallbackThread)
|
|
|
|
|
//
|
|
|
|
|
// Derived must define the following functions:
|
|
|
|
|
// void Start();
|
|
|
|
|
template <typename Derived, typename Thread>
|
|
|
|
|
class CallbackManager {
|
|
|
|
|
friend class RpcServerTest;
|
|
|
|
|
|
|
|
|
|
public:
|
|
|
|
|
void Stop() { m_owner.Stop(); }
|
|
|
|
|
|
|
|
|
|
void Remove(unsigned int listener_uid) {
|
|
|
|
|
auto thr = m_owner.GetThread();
|
|
|
|
|
if (!thr) return;
|
|
|
|
|
thr->m_listeners.erase(listener_uid);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
unsigned int CreatePoller() {
|
|
|
|
|
static_cast<Derived*>(this)->Start();
|
|
|
|
|
auto thr = m_owner.GetThread();
|
|
|
|
|
return thr->m_pollers.emplace_back(
|
|
|
|
|
std::make_shared<typename Thread::Poller>());
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void RemovePoller(unsigned int poller_uid) {
|
|
|
|
|
auto thr = m_owner.GetThread();
|
|
|
|
|
if (!thr) return;
|
|
|
|
|
|
|
|
|
|
// Remove any listeners that are associated with this poller
|
2017-08-19 23:08:27 -07:00
|
|
|
for (size_t i = 0; i < thr->m_listeners.size(); ++i) {
|
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
|
|
|
if (thr->m_listeners[i].poller_uid == poller_uid)
|
|
|
|
|
thr->m_listeners.erase(i);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Wake up any blocked pollers
|
|
|
|
|
if (poller_uid >= thr->m_pollers.size()) return;
|
|
|
|
|
auto poller = thr->m_pollers[poller_uid];
|
|
|
|
|
if (!poller) return;
|
|
|
|
|
poller->Terminate();
|
|
|
|
|
return thr->m_pollers.erase(poller_uid);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
bool WaitForQueue(double timeout) {
|
|
|
|
|
auto thr = m_owner.GetThread();
|
|
|
|
|
if (!thr) return true;
|
|
|
|
|
|
|
|
|
|
auto& lock = thr.GetLock();
|
|
|
|
|
#if defined(_MSC_VER) && _MSC_VER < 1900
|
|
|
|
|
auto timeout_time = std::chrono::steady_clock::now() +
|
|
|
|
|
std::chrono::duration<int64_t, std::nano>(
|
|
|
|
|
static_cast<int64_t>(timeout * 1e9));
|
|
|
|
|
#else
|
|
|
|
|
auto timeout_time = std::chrono::steady_clock::now() +
|
|
|
|
|
std::chrono::duration<double>(timeout);
|
|
|
|
|
#endif
|
|
|
|
|
while (!thr->m_queue.empty()) {
|
|
|
|
|
if (!thr->m_active) return true;
|
|
|
|
|
if (timeout == 0) return false;
|
|
|
|
|
if (timeout < 0) {
|
|
|
|
|
thr->m_queue_empty.wait(lock);
|
|
|
|
|
} else {
|
|
|
|
|
auto cond_timed_out = thr->m_queue_empty.wait_until(lock, timeout_time);
|
|
|
|
|
if (cond_timed_out == std::cv_status::timeout) return false;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return true;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
std::vector<typename Thread::UserInfo> Poll(unsigned int poller_uid) {
|
|
|
|
|
bool timed_out = false;
|
|
|
|
|
return Poll(poller_uid, -1, &timed_out);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
std::vector<typename Thread::UserInfo> Poll(unsigned int poller_uid,
|
|
|
|
|
double timeout, bool* timed_out) {
|
|
|
|
|
std::vector<typename Thread::UserInfo> infos;
|
|
|
|
|
std::shared_ptr<typename Thread::Poller> poller;
|
|
|
|
|
{
|
|
|
|
|
auto thr = m_owner.GetThread();
|
|
|
|
|
if (!thr) return infos;
|
|
|
|
|
if (poller_uid > thr->m_pollers.size()) return infos;
|
|
|
|
|
poller = thr->m_pollers[poller_uid];
|
|
|
|
|
if (!poller) return infos;
|
|
|
|
|
}
|
|
|
|
|
|
2017-11-13 09:51:05 -08:00
|
|
|
std::unique_lock<wpi::mutex> lock(poller->poll_mutex);
|
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
|
|
|
#if defined(_MSC_VER) && _MSC_VER < 1900
|
|
|
|
|
auto timeout_time = std::chrono::steady_clock::now() +
|
|
|
|
|
std::chrono::duration<int64_t, std::nano>(
|
|
|
|
|
static_cast<int64_t>(timeout * 1e9));
|
|
|
|
|
#else
|
|
|
|
|
auto timeout_time = std::chrono::steady_clock::now() +
|
|
|
|
|
std::chrono::duration<double>(timeout);
|
|
|
|
|
#endif
|
|
|
|
|
*timed_out = false;
|
|
|
|
|
while (poller->poll_queue.empty()) {
|
|
|
|
|
if (poller->terminating) return infos;
|
|
|
|
|
if (poller->cancelling) {
|
|
|
|
|
// Note: this only works if there's a single thread calling this
|
|
|
|
|
// function for any particular poller, but that's the intended use.
|
|
|
|
|
poller->cancelling = false;
|
|
|
|
|
return infos;
|
|
|
|
|
}
|
|
|
|
|
if (timeout == 0) {
|
|
|
|
|
*timed_out = true;
|
|
|
|
|
return infos;
|
|
|
|
|
}
|
|
|
|
|
if (timeout < 0) {
|
|
|
|
|
poller->poll_cond.wait(lock);
|
|
|
|
|
} else {
|
|
|
|
|
auto cond_timed_out = poller->poll_cond.wait_until(lock, timeout_time);
|
|
|
|
|
if (cond_timed_out == std::cv_status::timeout) {
|
|
|
|
|
*timed_out = true;
|
|
|
|
|
return infos;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
while (!poller->poll_queue.empty()) {
|
|
|
|
|
infos.emplace_back(std::move(poller->poll_queue.front()));
|
|
|
|
|
poller->poll_queue.pop();
|
|
|
|
|
}
|
|
|
|
|
return infos;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void CancelPoll(unsigned int poller_uid) {
|
|
|
|
|
std::shared_ptr<typename Thread::Poller> poller;
|
|
|
|
|
{
|
|
|
|
|
auto thr = m_owner.GetThread();
|
|
|
|
|
if (!thr) return;
|
|
|
|
|
if (poller_uid > thr->m_pollers.size()) return;
|
|
|
|
|
poller = thr->m_pollers[poller_uid];
|
|
|
|
|
if (!poller) return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
{
|
2017-11-13 09:51:05 -08:00
|
|
|
std::lock_guard<wpi::mutex> lock(poller->poll_mutex);
|
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
|
|
|
poller->cancelling = true;
|
|
|
|
|
}
|
|
|
|
|
poller->poll_cond.notify_one();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
protected:
|
|
|
|
|
template <typename... Args>
|
|
|
|
|
void DoStart(Args&&... args) {
|
|
|
|
|
auto thr = m_owner.GetThread();
|
|
|
|
|
if (!thr) m_owner.Start(new Thread(std::forward<Args>(args)...));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
template <typename... Args>
|
|
|
|
|
unsigned int DoAdd(Args&&... args) {
|
|
|
|
|
static_cast<Derived*>(this)->Start();
|
|
|
|
|
auto thr = m_owner.GetThread();
|
|
|
|
|
return thr->m_listeners.emplace_back(std::forward<Args>(args)...);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
template <typename... Args>
|
|
|
|
|
void Send(unsigned int only_listener, Args&&... args) {
|
|
|
|
|
auto thr = m_owner.GetThread();
|
|
|
|
|
if (!thr || thr->m_listeners.empty()) return;
|
|
|
|
|
thr->m_queue.emplace(std::piecewise_construct,
|
|
|
|
|
std::make_tuple(only_listener),
|
|
|
|
|
std::forward_as_tuple(std::forward<Args>(args)...));
|
|
|
|
|
thr->m_cond.notify_one();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
typename wpi::SafeThreadOwner<Thread>::Proxy GetThread() const {
|
|
|
|
|
return m_owner.GetThread();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private:
|
|
|
|
|
wpi::SafeThreadOwner<Thread> m_owner;
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
} // namespace nt
|
|
|
|
|
|
2017-08-19 23:08:27 -07:00
|
|
|
#endif // NTCORE_CALLBACKMANAGER_H_
|