21#include "../platform/threading.hpp"
62template<
typename UserRegistry, std::
size_t HistorySize = 100>
69 template<std::size_t... Is>
72 std::unique_ptr<TimestampedRingBuffer<TimsMessage<typename Registry::template type_at<Is>>, HistorySize>>...
77 std::make_index_sequence<Registry::num_types>{}
92 ) : mailbox_(config), default_tolerance_(default_tolerance) {
94 init_history_buffers();
102 auto result = mailbox_.
start();
104 std::cerr <<
"[HistoricalMailbox] Start failed for mailbox "
106 <<
static_cast<int>(result.get_error()) <<
"\n";
108 std::cout <<
"[HistoricalMailbox] Started mailbox "
109 << mailbox_.
mailbox_id() <<
" successfully\n";
141 auto result = mailbox_.template receive<T>();
145 store_in_history(result.value());
187 auto& buffer = get_history_buffer<T>();
188 return buffer.getData(timestamp, tolerance, mode);
197 const auto& buffer = get_history_buffer<T>();
198 return buffer.getTimestampRange();
206 auto& buffer = get_history_buffer<T>();
226 return mailbox_.template
send(message, dest_mailbox);
240 return mailbox_.is_initialized();
253 auto& buffer = get_history_buffer<T>();
257 buffer.push(tims_msg);
264 const TimestampedRingBuffer<TimsMessage<T>, HistorySize>& get_history_buffer()
const {
265 constexpr auto type_index = Registry::template get_type_index<T>();
266 return *std::get<type_index>(history_buffers_);
273 TimestampedRingBuffer<TimsMessage<T>, HistorySize>& get_history_buffer() {
274 constexpr auto type_index = Registry::template get_type_index<T>();
275 return *std::get<type_index>(history_buffers_);
281 void init_history_buffers() {
282 init_buffers_impl(std::make_index_sequence<Registry::num_types>{});
288 template<std::size_t... Is>
289 void init_buffers_impl(std::index_sequence<Is...>) {
290 ((init_buffer<Is>()), ...);
296 template<std::
size_t I>
298 using PayloadType =
typename Registry::template type_at<I>;
299 std::get<I>(history_buffers_) =
300 std::make_unique<TimestampedRingBuffer<TimsMessage<PayloadType>, HistorySize>>(
308 void clear_all_buffers() {
309 clear_all_impl(std::make_index_sequence<Registry::num_types>{});
312 template<std::size_t... Is>
313 void clear_all_impl(std::index_sequence<Is...>) {
314 ((std::get<Is>(history_buffers_)->clear()), ...);
Mailbox with timestamped history for getData synchronization.
auto send(T &message, uint32_t dest_mailbox) -> MailboxResult< void >
Send a message (pass-through to underlying mailbox)
void clearHistory()
Clear history for type T.
void stop()
Stop the mailbox (pass-through to underlying mailbox)
auto receive() -> MailboxResult< TimsMessage< T > >
Receive a message and automatically store in history.
HistoricalMailbox(const MailboxConfig &config, Milliseconds default_tolerance=Milliseconds(50))
Constructor with mailbox config and default tolerance.
std::optional< TimsMessage< T > > getData(uint64_t timestamp, Milliseconds tolerance=Milliseconds(-1), InterpolationMode mode=InterpolationMode::NEAREST) const
decltype(make_history_tuple_type(std::make_index_sequence< Registry::num_types >{})) HistoryBufferTuple
void clearAllHistory()
Clear all history buffers.
auto start() -> MailboxResult< void >
Start the mailbox (pass-through to underlying mailbox)
bool is_initialized() const
Check if mailbox is initialized.
static auto make_history_tuple_type(std::index_sequence< Is... >)
std::pair< uint64_t, uint64_t > getTimestampRange() const
Get timestamp range currently buffered for type T.
uint32_t get_mailbox_id() const
Get mailbox ID.
RegistryMailbox< UserRegistry > MailboxType
uint32_t mailbox_id() const
auto start() -> MailboxResult< void >
CommRaT - Modern C++ Real-Time Communication Framework.
InterpolationMode
Interpolation mode for timestamp-based lookup.
@ NEAREST
Return closest message by timestamp.
std::chrono::milliseconds Milliseconds
Thread-safe timestamped ring buffer for multi-input synchronization (Phase 6)