/*----------------------------------------------------------------------------*/ /* Copyright (c) FIRST 2015. 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 NT_NOTIFIER_H_ #define NT_NOTIFIER_H_ #include #include #include #include #include #include #include #include "atomic_static.h" #include "ntcore_cpp.h" namespace nt { class Notifier { friend class NotifierTest; public: static Notifier& GetInstance() { ATOMIC_STATIC(Notifier, instance); return instance; } ~Notifier(); void Start(); void Stop(); bool active() const { return m_active; } static bool destroyed() { return s_destroyed; } unsigned int AddEntryListener(StringRef prefix, EntryListenerCallback callback, bool local_notify); void RemoveEntryListener(unsigned int entry_listener_uid); void NotifyEntry(StringRef name, std::shared_ptr value, bool is_new, bool is_local, EntryListenerCallback only = nullptr); unsigned int AddConnectionListener(ConnectionListenerCallback callback); void RemoveConnectionListener(unsigned int conn_listener_uid); void NotifyConnection(bool connected, const ConnectionInfo& conn_info, ConnectionListenerCallback only = nullptr); private: Notifier(); void ThreadMain(); std::atomic_bool m_active; std::atomic_bool m_local_notifiers; std::mutex m_mutex; std::condition_variable m_cond; struct EntryListener { EntryListener(StringRef prefix_, EntryListenerCallback callback_, bool local_notify_) : prefix(prefix_), callback(callback_), local_notify(local_notify_) {} std::string prefix; EntryListenerCallback callback; bool local_notify; }; std::vector m_entry_listeners; std::vector m_conn_listeners; struct EntryNotification { EntryNotification(StringRef name_, std::shared_ptr value_, bool is_new_, bool is_local_, EntryListenerCallback only_) : name(name_), value(value_), is_new(is_new_), is_local(is_local_), only(only_) {} std::string name; std::shared_ptr value; bool is_new; bool is_local; EntryListenerCallback only; }; std::queue m_entry_notifications; struct ConnectionNotification { ConnectionNotification(bool connected_, const ConnectionInfo& conn_info_, ConnectionListenerCallback only_) : connected(connected_), conn_info(conn_info_), only(only_) {} bool connected; ConnectionInfo conn_info; ConnectionListenerCallback only; }; std::queue m_conn_notifications; std::thread m_thread; ATOMIC_STATIC_DECL(Notifier) static bool s_destroyed; }; } // namespace nt #endif // NT_NOTIFIER_H_