20#include <sertial/sertial.hpp>
36template<
typename... Ts>
37struct is_tuple<std::tuple<Ts...>> : std::true_type {};
87template<
typename UserRegistry,
90 typename... CommandTypes>
96 typename ExtractInputPayload<typename NormalizeInput<InputSpec_>::Type>::type,
97 typename ExtractOutputPayload<typename NormalizeOutput<OutputSpec_>::Type>::type
100 typename OutputTypesTuple<typename NormalizeOutput<OutputSpec_>::Type>::type,
101 typename ExtractInputPayload<typename NormalizeInput<InputSpec_>::Type>::type
104 typename ExtractInputPayload<typename NormalizeInput<InputSpec_>::Type>::type,
105 typename ExtractOutputPayload<typename NormalizeOutput<OutputSpec_>::Type>::type
112 ,
public MultiOutputManager<Module<UserRegistry, OutputSpec_, InputSpec_, CommandTypes...>, UserRegistry, typename OutputTypesTuple<typename NormalizeOutput<OutputSpec_>::Type>::type>
113 ,
public LoopExecutor<Module<UserRegistry, OutputSpec_, InputSpec_, CommandTypes...>>
115 ,
public CommandDispatcher<Module<UserRegistry, OutputSpec_, InputSpec_, CommandTypes...>, CommandTypes...>
120 ,
public std::conditional_t<
121 module_traits::ModuleTypes<UserRegistry, OutputSpec_, InputSpec_>::has_multi_input,
122 MultiInputInfrastructure<Module<UserRegistry, OutputSpec_, InputSpec_, CommandTypes...>, UserRegistry, typename module_traits::ModuleTypes<UserRegistry, OutputSpec_, InputSpec_>::InputTypesTuple, module_traits::ModuleTypes<UserRegistry, OutputSpec_, InputSpec_>::InputCount>,
125 ,
public std::conditional_t<
126 module_traits::ModuleTypes<UserRegistry, OutputSpec_, InputSpec_>::has_multi_input,
127 MultiInputProcessor<Module<UserRegistry, OutputSpec_, InputSpec_, CommandTypes...>, typename module_traits::ModuleTypes<UserRegistry, OutputSpec_, InputSpec_>::InputTypesTuple, typename module_traits::ModuleTypes<UserRegistry, OutputSpec_, InputSpec_>::OutputData, typename module_traits::ModuleTypes<UserRegistry, OutputSpec_, InputSpec_>::OutputTypesTuple, module_traits::ModuleTypes<UserRegistry, OutputSpec_, InputSpec_>::InputCount>,
134 ,
public LifecycleManager<Module<UserRegistry, OutputSpec_, InputSpec_, CommandTypes...>>
135 ,
public WorkLoopHandler<Module<UserRegistry, OutputSpec_, InputSpec_, CommandTypes...>>
140 friend class LoopExecutor<
Module<UserRegistry, OutputSpec_, InputSpec_, CommandTypes...>>;
143 friend class
CommandDispatcher<Module<UserRegistry, OutputSpec_, InputSpec_, CommandTypes...>, CommandTypes...>;
144 friend class
MultiInputInfrastructure<Module<UserRegistry, OutputSpec_, InputSpec_, CommandTypes...>, UserRegistry, typename module_traits::ModuleTypes<UserRegistry, OutputSpec_, InputSpec_>::InputTypesTuple, module_traits::ModuleTypes<UserRegistry, OutputSpec_, InputSpec_>::InputCount>;
145 friend class
MultiInputProcessor<Module<UserRegistry, OutputSpec_, InputSpec_, CommandTypes...>, typename module_traits::ModuleTypes<UserRegistry, OutputSpec_, InputSpec_>::InputTypesTuple, typename module_traits::ModuleTypes<UserRegistry, OutputSpec_, InputSpec_>::OutputData, typename module_traits::ModuleTypes<UserRegistry, OutputSpec_, InputSpec_>::OutputTypesTuple, module_traits::ModuleTypes<UserRegistry, OutputSpec_, InputSpec_>::InputCount>;
146 friend class
LifecycleManager<Module<UserRegistry, OutputSpec_, InputSpec_, CommandTypes...>>;
147 friend class
WorkLoopHandler<Module<UserRegistry, OutputSpec_, InputSpec_, CommandTypes...>>;
149 friend class
InputMetadataManager<Module<UserRegistry, OutputSpec_, InputSpec_, CommandTypes...>>;
187 template<typename Dummy = void>
188 struct ValidatePrimaryInputImpl {
189 static constexpr bool check() {
190 if constexpr (has_primary_input_spec && has_multi_input) {
192 return PrimaryInputIndex_v<PrimaryPayloadType, InputTypesTuple> >= 0;
196 static constexpr bool value = check();
198 static_assert(ValidatePrimaryInputImpl<>::value,
199 "PrimaryInput validation failed - see error above for details");
230 static_assert(num_output_types == 1,
"publish_mailbox() accessor only available for single-output modules. Use get_publish_mailbox<Index>() for multi-output");
235 template<std::
size_t Index>
241 template<std::
size_t Index>
247 template<std::
size_t Index>
253 template<std::
size_t Index>
284 Module<UserRegistry, OutputSpec_, InputSpec_, CommandTypes...>
315 static constexpr std::size_t
num_inputs = InputCount_v<InputSpec>;
330 template<std::size_t... Is>
343 config.has_multi_output_config() ? config.system_id(0) : config.system_id(),
344 config.has_multi_output_config() ? config.instance_id(0) : config.instance_id(),
346 .message_slots = config.message_slots,
347 .max_message_size = UserRegistry::max_message_size,
348 .send_priority = static_cast<uint8_t>(config.priority),
349 .realtime = config.realtime,
350 .mailbox_name = config.name +
"_data"
372 if constexpr (has_multi_input) {
373 this->initialize_multi_input_mailboxes();
405 typename = std::enable_if_t<!std::is_void_v<O> && !is_tuple_v<O>>>
423 template<std::
size_t Index>
432 template<std::
size_t Index>
505 template<
typename T = OutputData>
506 requires (!std::is_void_v<T>)
516 template<
typename... Ts>
521 template<
typename... Ts>
554 static constexpr size_t get_primary_input_index() {
556 if constexpr (has_primary_input_spec) {
558 return PrimaryInputIndex_v<PrimaryPayloadType, InputTypesTuple>;
Command dispatcher mixin.
virtual void process(const ExtractInputPayload< NormalizeInput< InputSpec_ >::Type >::type &input, ExtractOutputPayload< NormalizeOutput< OutputSpec_ >::Type >::type &output)
Phase 6: Lifecycle Management CRTP Mixin.
void stop()
Stop the module.
Loop execution logic for Module data threads.
Phase 8: Mailbox Infrastructure Builder.
Timestamp Management Architecture.
void initialize_mailbox_infrastructure_impl(const ModuleConfig &config, std::index_sequence< Is... >)
void handle_unsubscribe_request(const UnsubscribeRequestPayload &req)
void handle_subscribe_request(const SubscribeRequestPayload &req, std::size_t output_idx=0)
auto & get_publish_mailbox_public()
Get publish mailbox by index (public for Publisher access)
auto & get_publish_mailbox()
Module(const ModuleConfig &config)
void handle_subscribe_reply(const SubscribeReplyPayload &reply)
typename ModuleTypes::OutputData OutputData
static constexpr std::size_t num_inputs
Storage for input message metadata.
PublishMailbox & publish_mailbox()
void remove_subscriber(uint32_t subscriber_base_addr)
Remove subscriber (for unsubscribe)
CmdMailbox & cmd_mailbox()
MailboxSetTuple mailbox_infrastructure_
typename ModuleTypes::InputData InputData
std::atomic< bool > running_
void publish_multi_outputs_with_timestamp(std::tuple< Ts... > &outputs, uint64_t timestamp_ns)
auto & get_work_mailbox()
void unsubscribe_from_multi_input_source(const MultiInputConfig::InputSource &source)
void add_subscriber_to_output(uint32_t subscriber_base_addr, uint8_t mailbox_index, std::size_t output_idx=0)
Add subscriber to correct output-specific list.
std::optional< std::thread > command_thread_
void subscribe_to_all_sources()
static TimsMessage< T > create_tims_message(T &&payload, uint64_t timestamp_ns)
static constexpr bool has_periodic_input
SubscriptionProtocolType subscription_protocol_
virtual void on_cleanup()
void unsubscribe_from_source(uint8_t source_system_id, uint8_t source_instance_id)
void subscribe_to_source(uint8_t source_system_id, uint8_t source_instance_id)
void publish_to_subscribers(T &data)
static constexpr bool has_loop_input
auto & get_cmd_mailbox_public()
Get cmd mailbox by index (public for Publisher access) Phase 7: CMD mailbox used for publishing.
std::optional< std::thread > data_thread_
std::array< InputMetadataStorage,(num_inputs > 0 ? num_inputs :1)> input_metadata_
WorkMailbox & work_mailbox()
void process_dispatch(const T &input, O &output)
void publish_multi_outputs(std::tuple< Ts... > &outputs)
Module & operator=(const Module &)=delete
std::optional< DataMailbox > data_mailbox_
static constexpr bool has_continuous_input
Module(const Module &)=delete
static constexpr bool has_multi_output
Module & operator=(Module &&)=delete
void publish_tims_message(TimsMessage< T > &tims_msg)
CRTP mixin for multi-output mailbox and subscriber management.
void initialize_output_subscribers()
Initialize per-output subscriber lists.
void set_module_name(const std::string &name)
void publish_multi_outputs(std::tuple< Ts... > &outputs)
Publish multiple outputs (tuple) to subscribers Each subscriber receives only outputs matching their ...
void publish_to_subscribers(T &data)
Single-output publishing (only enabled when OutputData is not void) Publishes data to all subscribers...
static TimsMessage< T > create_tims_message(T &&payload, uint64_t timestamp_ns)
Create TimsMessage with explicit timestamp Phase 6.10: Single source of truth for timestamps (header....
void set_module_ptr(ModuleType *ptr)
void publish_tims_message(TimsMessage< T > &tims_msg)
Publish TimsMessage<T> for single output Phase 6.10: Uses explicit timestamp from header Phase 7: Use...
void publish_multi_outputs_with_timestamp(std::tuple< Ts... > &outputs, uint64_t timestamp_ns)
Publish multi-outputs with explicit timestamp Phase 6.10: Wraps each output in TimsMessage with times...
Mailbox that takes a MessageRegistry and exposes payload-only interface.
void handle_subscribe_reply(const SubscribeReplyType &reply)
Handle incoming SubscribeReply (consumer side)
void subscribe_to_source(uint8_t source_system_id, uint8_t source_instance_id)
Legacy single-input subscription (backward compatible)
void unsubscribe_from_multi_input_source(const MultiInputConfig::InputSource &source)
Unsubscribe from multi-input source.
void handle_subscribe_request(const SubscribeRequestType &req, SubscriberMgr &sub_mgr, std::size_t output_idx=0)
Handle incoming SubscribeRequest (producer side)
void handle_unsubscribe_request(const UnsubscribeRequestType &req, SubscriberMgr &sub_mgr)
Handle incoming UnsubscribeRequest (producer side)
void unsubscribe_from_source(uint8_t source_system_id, uint8_t source_instance_id)
Unsubscribe from single-input source.
void set_module_name(const std::string &name)
void set_config(const ModuleConfig *cfg)
void subscribe_to_all_sources()
Subscribe to all configured input sources.
void set_work_mailbox(RegistryMailbox< SystemRegistry > *mbx)
Phase 7: Work Loop Handler CRTP Mixin.
RegistryMailbox wrapper with timestamped history for multi-input synchronization (Phase 6....
Core module infrastructure - type traits, specs, and configuration.
CRTP mixins that compose Module functionality.
Module service components - subscription and publishing.
CommRaT - Modern C++ Real-Time Communication Framework.
constexpr bool is_tuple_v
static constexpr uint32_t get_mailbox_address(uint8_t system_id, uint8_t instance_id, uint8_t mailbox_index)
Get specific mailbox address with index.
Maps raw output types to Output<T> format.
Reply to subscription request.
Request to subscribe to continuous data from a producer module.
Request to unsubscribe from continuous data.
Centralized type computation for Module class.
NormalizeOutput_t< OutputSpec_ > OutputSpec
static constexpr bool has_multi_output
typename ExtractInputTypes< InputSpec >::type InputTypesTuple
NormalizeInput_t< InputSpec_ > InputSpec
static constexpr size_t num_command_types
static constexpr size_t InputCount
static constexpr bool has_periodic_input
static constexpr bool has_loop_input
typename ExtractPrimaryPayloadHelper< CommandTypes... >::type PrimaryPayloadType
typename MakeTypedCmdMailbox< UserRegistry, OutputTypesTuple >::type PublishMailbox
typename MakeTypedCmdMailboxWithSend< UserRegistry, CommandTuple, OutputTypesTuple >::type CmdMailbox
static constexpr bool has_continuous_input
typename ExtractDataTypes< InputSpec >::type DataTypesTuple
static constexpr bool has_primary_input_spec
static constexpr bool use_mailbox_sets
typename ExtractInputPayload< InputSpec >::type InputData
typename MakeTypedDataMailbox< UserRegistry, DataTypesTuple >::type DataMailbox
std::tuple< CommandTypes... > CommandTuple
typename MakeMailboxSetTuple< UserRegistry, OutputTypesTuple, CommandTypes... >::type MailboxSetTuple
static constexpr size_t num_output_types
typename ::commrat::OutputTypesTuple< OutputSpec >::type OutputTypesTuple
static constexpr bool has_multi_input
decltype(std::tuple_cat(std::declval< CommandTuple >(), std::declval< OutputTypesTuple >())) CombinedCmdTypes
typename ExtractOutputPayload< OutputSpec >::type OutputData
Unified threading and synchronization abstractions for CommRaT.
Unified timestamp and time utility abstractions for CommRaT.
Type-restricted mailbox with optimized buffer sizing (Phase 7)