6#include "libxr_def.hpp"
23 template <
typename Function>
33 template <
typename Return,
typename... Args>
37 static constexpr size_t ARITY =
sizeof...(Args);
43 template <
size_t Index>
44 using Arg = std::tuple_element_t<Index, std::tuple<Args...>>;
67 template <
typename Data>
82 using RemoveCVRef = std::remove_cv_t<std::remove_reference_t<T>>;
100 template <
typename T>
109 template <
typename T>
121 template <
typename T>
132 template <
typename T>
135 !std::is_const_v<std::remove_reference_t<T>>;
169 template <
typename PayloadArg>
173 "LibXR::Topic::Callback does not accept MessageView<T>&; "
174 "use MessageView<T> or const MessageView<T>& instead.");
188 "LibXR::Topic::Callback payload must be Topic::MessageView<T>, "
189 "Topic::RawMessageView, ConstRawData, T, T&, or const T&.");
200 template <
typename PayloadArg>
220 template <
typename Function,
typename BoundArg,
typename PayloadArg>
225 if constexpr (std::same_as<RemoveCVRef<PayloadArg>,
ConstRawData>)
228 fun(in_isr, arg, raw_payload);
230 else if constexpr (std::same_as<RemoveCVRef<PayloadArg>,
RawMessageView>)
233 fun(in_isr, arg, raw_message);
238 using Data =
typename View::DataType;
245 fun(in_isr, arg, *
reinterpret_cast<Data*
>(payload_addr));
256 template <
typename Function,
typename BoundArg,
typename PayloadArg>
287 block->fun_,
const_cast<BoundArg&
>(block->arg_), in_isr, timestamp,
288 payload_addr, payload_size);
303 template <
typename Function,
typename BoundArg,
typename PayloadArg>
333 if constexpr (std::same_as<RemoveCVRef<PayloadArg>,
ConstRawData>)
336 block->fun_(in_isr, block->arg_, timestamp, raw_payload);
338 else if constexpr (std::same_as<RemoveCVRef<PayloadArg>,
RawMessageView>)
341 block->fun_(in_isr, block->arg_, timestamp, raw_message);
346 using Data =
typename View::DataType;
347 block->fun_(in_isr, block->arg_, timestamp,
353 block->fun_(in_isr, block->arg_, timestamp,
354 *
reinterpret_cast<Data*
>(payload_addr));
370 template <
typename Function,
typename BoundArg,
size_t Arity>
373 static_assert(Arity == 3 || Arity == 4,
374 "LibXR::Topic::Callback function must be void(bool, Arg, Payload) "
375 "or void(bool, Arg, MicrosecondTimestamp, Payload).");
384 template <
typename Function,
typename BoundArg>
389 typename Traits::template Arg<2>;
402 static_assert(std::same_as<typename Traits::ReturnType, void>);
403 static_assert(std::same_as<typename Traits::template Arg<0>,
bool>);
404 static_assert(std::same_as<typename Traits::template Arg<1>, BoundArg>);
416 template <
typename Function,
typename BoundArg>
421 typename Traits::template Arg<2>;
425 typename Traits::template Arg<3>;
438 static_assert(std::same_as<typename Traits::ReturnType, void>);
439 static_assert(std::same_as<typename Traits::template Arg<0>,
bool>);
440 static_assert(std::same_as<typename Traits::template Arg<1>, BoundArg>);
463 UNUSED(payload_addr);
464 UNUSED(payload_size);
507 template <
typename BoundArg,
typename Callable>
510 using Function =
decltype(+std::declval<Callable>());
512 static_assert(Traits::ARITY == 3 || Traits::ARITY == 4,
513 "LibXR::Topic::Callback::Create expects a capture-free callable "
514 "with bool and bound-argument parameters.");
527 size_t payload_size)
const
只读原始数据视图 / Immutable raw data view
数据节点模板,继承自 BaseNode,用于存储具体数据类型。 Template data node that inherits from BaseNode to store specific data...
微秒时间戳 / Microsecond timestamp
Data data_
存储的数据 (Stored data).
每次发布时直接执行函数的订阅句柄 / Subscription handle that runs a function on each publish
static constexpr bool IS_MESSAGE_VIEW
是否为带时间戳的类型化消息视图参数 / Whether one callback payload argument is a timestamped typed message view
void Run(bool in_isr, MicrosecondTimestamp timestamp, void *payload_addr, size_t payload_size) const
执行回调 / Run the callback
static void InvokePayload(Function fun, BoundArg &arg, bool in_isr, MicrosecondTimestamp timestamp, void *payload_addr, size_t payload_size)
按回调声明的参数形式,把当前消息拼成实参再调函数 / Build the actual call arguments from the current message in the form decla...
static void EmptyRun(const BlockHeader *header, bool in_isr, MicrosecondTimestamp timestamp, void *payload_addr, size_t payload_size)
空回调块的执行函数 / Execution function of the empty callback block
bool IsRawPayloadView() const
判断该回调是否按 raw payload 视图接收消息 / Tell whether this callback receives messages as a raw payload view
Callback & operator=(const Callback &other)=default
拷贝赋值回调句柄 / Copy-assign one callback handle
static constexpr bool IS_CALLBACK_PAYLOAD
是否是回调接口允许的 payload 参数写法 / Whether one payload argument form is accepted by this callback interface
Callback(const Callback &other)=default
拷贝构造回调句柄 / Copy-construct one callback handle
Callback(BlockHeader *block)
用指定执行块构造回调句柄 / Construct one callback handle from the given execution block
static constexpr bool IS_MUTABLE_MESSAGE_VIEW_REF
是否错误地使用了可变 MessageView<T>& / Whether one payload argument is an invalid mutable MessageView<T>&
static Callback Create(Callable fun, BoundArg arg)
创建一个回调订阅句柄 / Create a callback subscription handle
static BlockHeader empty_block_
Callback()=default
构造一个空回调句柄 / Construct one empty callback handle
TypeID::ID PayloadTypeID() const
读取这个回调句柄期望的 payload 类型标识 / Read the payload type ID expected by this callback handle
std::remove_cv_t< std::remove_reference_t< T > > RemoveCVRef
去掉引用和 cv 限定后的规范类型 / Canonical type after removing reference and cv qualifiers
static constexpr bool IS_RAW_DATA_VIEW
是否为只读 raw payload 视图参数 / Whether one callback payload argument is a read-only raw payload view
static constexpr bool AcceptsRawPayload()
回调 payload 参数是否是 raw 字节视图 / Whether the callback payload argument is a raw byte view
static constexpr bool IS_TYPED_DATA
是否把 payload 直接当成一个对象接收 / Whether one callback payload argument receives the payload directly as one o...
static TypeID::ID PayloadTypeID()
取回调 payload 参数对应的精确类型标识 / Get the exact type ID expected by one callback payload argument
@ CALLBACK
回调执行型订阅者。Callback-executing subscriber.
void RegisterCallback(Callback &cb)
注册一个回调订阅者 / Register one callback subscriber
static ID GetID()
获取类型的唯一标识符 / Get a unique identifier for type T
topic 可承载 payload 的类型约束 / Type constraint for payloads carried by one topic
constexpr size_t CONCURRENCY_ALIGNMENT
并发结构对齐粒度(用于降低多核伪共享) / Alignment policy used by concurrency-oriented structures
typename Traits::template Arg< 2 > PayloadArg
static BlockHeader * Create(Function fun, BoundArg &&arg)
创建只转发负载的回调块 / Create one callback block that forwards only the payload
static BlockHeader * Create(Function fun, BoundArg &&arg)
创建同时转发时间戳和负载的回调块 / Create one callback block that forwards both timestamp and payload
typename Traits::template Arg< 3 > PayloadArg
typename Traits::template Arg< 2 > TimestampArg
看回调有几个参数,决定分配哪种回调块 / Choose which callback block to allocate from the callback parameter count
std::tuple_element_t< Index, std::tuple< Args... > > Arg
取出指定下标的参数类型 / Fetch the argument type at the given index
Return ReturnType
回调返回类型。Callback return type.
把一个无捕获回调函数拆成返回类型和参数类型 / Split one callback function without captures into its return type and paramet...
Data DataType
MessageView 对应的数据类型。Payload type behind the MessageView.
判断某个参数是否为 MessageView<T> / Tell whether one argument is MessageView<T>
static constexpr bool VALUE
默认不是 MessageView。Not a MessageView by default.
只转发负载的回调块 / Callback block that forwards only the payload
BoundArg arg_
绑定到回调中的参数副本。Stored copy of the bound argument.
Function fun_
目标回调函数。Target callback function.
PayloadOnlyBlock(Function fun, BoundArg &&arg)
构造一个只转发负载的具体回调块 / Construct one concrete callback block that forwards only the payload
static void Run(const BlockHeader *header, bool in_isr, MicrosecondTimestamp timestamp, void *payload_addr, size_t payload_size)
根据块头指针取回具体块并执行回调 / Recover the concrete block from the block header pointer and run the callback
同时转发时间戳和负载的回调块 / Callback block that forwards both timestamp and payload
BoundArg arg_
绑定到回调中的参数副本。Stored copy of the bound argument.
Function fun_
目标回调函数。Target callback function.
static void Run(const BlockHeader *header, bool in_isr, MicrosecondTimestamp timestamp, void *payload_addr, size_t payload_size)
根据块头指针取回具体块并执行带时间戳回调 / Recover the concrete block from the block header pointer and run the timestamp...
TimestampPayloadBlock(Function fun, BoundArg &&arg)
构造一个同时转发时间戳和负载的具体回调块 / Construct one concrete callback block that forwards both timestamp and payload
挂在 topic 订阅链表里的回调记录 / Callback record stored in the topic subscriber list
size_t payload_size
注册到的 topic 固定 payload 字节数。Fixed payload size of the subscribed topic.
Callback cb
订阅的回调句柄。Subscribed callback handle.
void Run(bool in_isr, MicrosecondTimestamp timestamp, void *payload_addr) const
通过注册时绑定的 topic payload size 执行回调 / Run the callback with the topic payload size bound at registration...
CallbackBlock(Callback &callback, size_t topic_payload_size)
构造一个回调订阅块 / Construct one callback subscriber block
带时间戳和 payload 指针的只读消息视图 / Read-only message view carrying a timestamp and a payload pointer
带时间戳和只读原始 payload 视图的消息 / Message carrying a timestamp and a read-only raw payload view
所有订阅块共用的公共头 / Common header shared by all subscriber blocks
SuberType type
订阅块的具体种类。Concrete kind of this subscriber block.