9#include <condition_variable>
15 using Handler = std::function<void(
const uint8_t*,
size_t)>;
19 using logic_error::logic_error;
24 using logic_error::logic_error;
33 template <
typename MessageType>
36 template <
typename MessageType>
44 char const*
const name;
46 std::map<MessageType, Handler> handlers;
47 std::map<MessageType, char const*> message_labels;
49 std::string get_error_prefix()
51 return std::string(
"[") + std::string(name) + std::string(
"] ");
54 char const* get_message_name(MessageType m)
56 const auto it = message_labels.find(m);
57 if (it == message_labels.end())
65 static std::string decorate_message_name(MessageType m,
char const* s)
67 return fmt::format(
"<{}:{}>", s, m);
70 std::string get_decorated_message_name(MessageType m)
72 return decorate_message_name(m, get_message_name(m));
91 MessageType m,
char const* message_label,
Handler h)
94 auto it = handlers.find(m);
95 if (it != handlers.end())
98 get_error_prefix() +
"MessageType " + std::to_string(m) +
99 " already handled by " + get_decorated_message_name(m) +
100 ", cannot set handler for " +
101 decorate_message_name(m, message_label));
104 LOG_DEBUG_FMT(
"Setting handler for {} ({})", message_label, m);
105 handlers.insert(it, {m, h});
107 if (message_label !=
nullptr)
109 message_labels.emplace(m, message_label);
122 auto it = handlers.find(m);
123 if (it == handlers.end())
127 "Can't remove non-existent handler for this message: " +
128 get_decorated_message_name(m));
141 return handlers.find(m) != handlers.end();
151 void dispatch(MessageType m,
const uint8_t* data,
size_t size)
153 auto it = handlers.find(m);
154 if (it == handlers.end())
158 "No handler for this message: " + get_decorated_message_name(m));
164 it->second(data, size);
166 catch (
const std::exception& e)
169 "Exception while processing message {} of size {}",
170 get_decorated_message_name(m),
181 static inline void default_idle_behaviour(
size_t )
183 std::this_thread::yield();
189 std::atomic<bool> finished;
200 template <
typename... Ts>
213 return finished.load();
218 size_t total_read = 0;
219 size_t previous_read = -1;
221 while (!finished.load() && total_read < max_messages)
228 d.dispatch(m, data, size);
236 if (read == 0 && previous_read == 0)
241 previous_read = read;
249 size_t total_read = 0;
252 const auto read =
read_n(1, r);
265 size_t total_read = 0;
266 size_t consecutive_idles = 0u;
268 while (!finished.load())
271 total_read += num_read;
275 idler(consecutive_idles++);
279 consecutive_idles = 0;
292#define DISPATCHER_SET_MESSAGE_HANDLER(DISP, MSG, ...) \
293 DISP.set_message_handler(MSG, #MSG, __VA_ARGS__)
Definition messaging.h:187
void set_message_handler(Ts &&... ts)
Definition messaging.h:201
bool get_finished()
Definition messaging.h:211
RingbufferDispatcher & get_dispatcher()
Definition messaging.h:195
size_t read_n(size_t max_messages, ringbuffer::Reader &r)
Definition messaging.h:216
BufferProcessor(char const *name="")
Definition messaging.h:192
size_t read_all(ringbuffer::Reader &r)
Definition messaging.h:247
size_t run(ringbuffer::Reader &r, IdleBehaviour idler=default_idle_behaviour)
Definition messaging.h:262
void set_finished(bool v=true)
Definition messaging.h:206
Definition messaging.h:38
void set_message_handler(MessageType m, char const *message_label, Handler h)
Definition messaging.h:90
void dispatch(MessageType m, const uint8_t *data, size_t size)
Definition messaging.h:151
Dispatcher(char const *name)
Definition messaging.h:76
MessageCounts< MessageType > MessageCounts
Definition messaging.h:40
bool has_handler(MessageType m)
Definition messaging.h:139
void remove_message_handler(MessageType m)
Definition messaging.h:120
Definition messaging.h:23
Definition messaging.h:18
Definition ring_buffer.h:175
size_t read(size_t limit, Handler f)
Definition ring_buffer.h:208
#define LOG_TRACE_FMT
Definition internal_logger.h:13
#define LOG_DEBUG_FMT
Definition internal_logger.h:14
#define LOG_FAIL_FMT
Definition internal_logger.h:16
Definition messaging.h:14
std::function< void(size_t num_consecutive_idles)> IdleBehaviour
Definition messaging.h:180
std::unordered_map< MessageType, Counts > MessageCounts
Definition messaging.h:34
std::function< void(const uint8_t *, size_t)> Handler
Definition messaging.h:15
uint32_t Message
Definition ring_buffer_types.h:19
Definition messaging.h:28
size_t messages
Definition messaging.h:29
size_t bytes
Definition messaging.h:30