#ifndef SRC_COMMON_EVENTS_HPP_
#define SRC_COMMON_EVENTS_HPP_
#include <map>
using namespace std;
template <class cb_func_type>
class common_events {
public:
common_events() {
next_key_ = 0;
}
common_events(const common_events &) = delete;
common_events & operator = (const common_events &) = delete;
virtual ~common_events() = default;
public:
inline int operator += (cb_func_type &cb_fun) {
return connect(cb_fun);
}
inline int operator += (cb_func_type &&cb_fun) {
return connect(forward<cb_func_type>(cb_fun));
}
template <typename... Args>
bool operator()(Args&&... args) {
return notify(forward<Args>(args)...);
}
inline common_events& operator -= (int key) {
disconnect(key);
return *this;
}
void clear() {
connections_.clear();
}
private:
inline void push_connection(int index, cb_func_type &cb_fun) {
connections_.emplace(index, cb_fun);
}
inline void push_connection(int index, cb_func_type &&cb_fun) {
connections_.emplace(index, move(cb_fun));
}
inline int assgin_connection(cb_func_type &&cb_fun) {
int index = next_key_++;
push_connection(index, forward<cb_func_type>(cb_fun));
return index;
}
inline int connect(cb_func_type &cb_fun) {
return assgin_connection(cb_fun);
}
inline int connect(cb_func_type &&cb_fun) {
return assgin_connection(forward<cb_func_type>(cb_fun));
}
inline void disconnect(int key) {
connections_.erase(key);
}
template <typename... Args>
bool notify(Args&&... args) {
bool succ = true;
for (auto& it : connections_) {
if (false == it.second(forward<Args>(args)...)) {
succ = false;
}
}
return succ;
}
private:
int next_key_;
map<int, cb_func_type>connections_;
};
#endif /* SRC_COMMON_EVENTS_HPP_ */
#ifndef SRC_ZEG_ROBOT_NETWORK_MESSAGE_EXCEPTION_REPORTER_HPP_
#define SRC_ZEG_ROBOT_NETWORK_MESSAGE_EXCEPTION_REPORTER_HPP_
#include <functional>
#include <chrono>
#include "zeg_robot_network_message_exception_logger.hpp"
#include "common_events.hpp"
namespace zeg_robot_scheduler_communication {
class zeg_robot_network_message_exception_reporter {
public:
using handler_delegate = std::function<bool(const zeg_robot_header &)>;
using excception_events = common_events<handler_delegate>;
public:
inline static zeg_robot_network_message_exception_reporter &get() {
static zeg_robot_network_message_exception_reporter reporter;
return reporter;
}
void set_latency_water_mark(unsigned m) {
latency_water_mark = m;
}
bool report_exception(const zeg_robot_header &header) {
if (chrono::duration_cast<chrono::milliseconds>(chrono::system_clock::now().time_since_epoch()).count() - header.timestamp >= latency_water_mark) {
return events_(header);
}
return false;
}
private:
zeg_robot_network_message_exception_reporter() {
latency_water_mark = 100; // 100ms
events_ += std::bind(&zeg_robot_network_message_exception_logger::handler, &logger, std::placeholders::_1);
}
~zeg_robot_network_message_exception_reporter() {
events_.clear();
}
private:
unsigned latency_water_mark;
excception_events events_;
zeg_robot_network_message_exception_logger logger;
};
}
#endif /* SRC_ZEG_ROBOT_NETWORK_MESSAGE_EXCEPTION_REPORTER_HPP_ */