#pragma once #include #include #include #include #include #include "wire.h" struct responder { uint32_t message_id; std::function)> send; template void respond(const T& msg) const { uint8_t buf[1024]; span_writer out(buf, sizeof(buf)); auto r = encode_response_into(out, message_id, msg); if (r) send({buf, *r}); } }; using handler_fn = void (*)(responder resp, std::span payload); struct handler_entry { int8_t type_id; handler_fn handle; }; template void typed_handler(responder resp, std::span payload) { msgpack::parser p(payload.data(), static_cast(payload.size())); Req req; auto tup = req.as_tuple(); auto r = msgpack::unpack(p, tup); if (!r) { char err[64]; snprintf(err, sizeof(err), "decode request ext_id=%d: msgpack error %d", Req::ext_id, static_cast(r.error())); resp.respond(DeviceError{1, err}); return; } auto result = Fn(resp, req); if (result) resp.respond(*result); } void dispatch_init(); void dispatch_schedule_ms(uint32_t ms, std::function fn); [[noreturn]] void dispatch_run(std::span handlers);