12#include "libxr_cb.hpp"
13#include "libxr_def.hpp"
14#include "libxr_mem.hpp"
15#include "libxr_time.hpp"
16#include "libxr_type.hpp"
17#include "lock_queue.hpp"
18#include "lockfree_list.hpp"
19#include "lockfree_queue.hpp"
23#include "semaphore.hpp"
28template <
typename Data>
30 !std::is_reference_v<Data> && !std::is_const_v<Data> && !std::is_volatile_v<Data> &&
31 std::is_object_v<Data> && std::is_default_constructible_v<Data> &&
32 std::is_copy_assignable_v<Data> && std::is_trivially_destructible_v<Data>;
34template <
typename Data>
35constexpr void CheckTopicPayload()
38 "LibXR::Topic typed payload must be a non-cv/ref object type that is "
39 "default-constructible, copy-assignable, and trivially destructible.");
62 enum class LockState : uint32_t
66 USE_MUTEX = UINT32_MAX,
81 std::atomic<LockState>
busy;
98 struct PackedDataHeader
101 uint8_t data_len_raw[3];
104 uint8_t timestamp_us_raw[8];
105 uint8_t pack_header_crc8;
107 void SetDataLen(uint32_t len);
109 uint32_t GetDataLen()
const;
117 template <
typename Data>
120 static constexpr uint8_t PACKET_PREFIX = 0x5A;
121 static constexpr size_t PACK_BASE_SIZE =
sizeof(PackedDataHeader) +
sizeof(uint8_t);
122 static_assert(
sizeof(PackedDataHeader) == 17);
123 static_assert(offsetof(PackedDataHeader, prefix) == 0);
124 static_assert(offsetof(PackedDataHeader, data_len_raw) == 1);
125 static_assert(offsetof(PackedDataHeader, topic_name_crc32) == 4);
126 static_assert(offsetof(PackedDataHeader, timestamp_us_raw) == 8);
127 static_assert(offsetof(PackedDataHeader, pack_header_crc8) == 16);
141 template <
typename Data>
154 template <
typename Data>
221 template <
typename Data>
223 enum class ASyncSubscriberState : uint32_t;
225 template <
typename Data>
281 Topic(
const char* name, uint32_t max_length,
Domain* domain =
nullptr,
282 bool multi_publisher =
false,
bool cache =
false,
bool check_length =
false);
302 template <
typename Data>
304 bool multi_publisher =
false,
bool cache =
false,
305 bool check_length =
false)
307 CheckTopicPayload<Data>();
308 return Topic(name,
sizeof(Data), domain, multi_publisher, cache, check_length);
349 template <
typename Data>
351 bool multi_publisher =
false,
bool cache =
false,
352 bool check_length =
false)
354 CheckTopicPayload<Data>();
355 auto topic =
Find(name, domain);
356 if (topic ==
nullptr)
380 template <
typename Data>
383 CheckTopicPayload<Data>();
384 Publish(
static_cast<void*
>(&data),
static_cast<uint32_t
>(
sizeof(Data)));
387 template <
typename Data>
390 CheckTopicPayload<Data>();
391 Publish(
static_cast<void*
>(&data),
static_cast<uint32_t
>(
sizeof(Data)), timestamp);
400 void Publish(
void* addr, uint32_t size);
402 void Publish(
void* addr, uint32_t size, MicrosecondTimestamp timestamp);
411 template <
typename Data>
414 CheckTopicPayload<Data>();
419 template <
typename Data>
422 CheckTopicPayload<Data>();
453 static void PackData(uint32_t topic_name_crc32, RawData buffer,
454 MicrosecondTimestamp timestamp, ConstRawData data);
462 template <
typename Data>
468 template <SizeLimitMode Mode = SizeLimitMode::MORE>
472 return DumpPayload<Mode>(data, timestamp);
475 template <SizeLimitMode Mode = SizeLimitMode::MORE>
478 return DumpPayload<Mode>(data, timestamp);
493 template <
typename Data>
494 requires(!std::same_as<std::remove_cv_t<Data>, RawData>)
501 template <
typename Data>
502 requires(!std::same_as<std::remove_cv_t<Data>,
RawData>)
505 CheckTopicPayload<Data>();
506 return DumpPayload<SizeLimitMode::LESS>(
RawData(data), timestamp);
509 MicrosecondTimestamp GetTimestamp()
const;
523 Domain* domain =
nullptr);
565 static void EnsureDomainRegistry();
566 static Domain* EnsureDefaultDomain();
572 template <
typename Data>
575 CheckTopicPayload<Data>();
578 ASSERT(topic.
block_->
data_.max_length ==
sizeof(Data));
582 ASSERT(topic.
block_->
data_.max_length <=
sizeof(Data));
590 template <
typename Data>
593 CheckTopicPayload<Data>();
594 auto* data =
new Data;
598 template <SizeLimitMode Mode = SizeLimitMode::MORE>
606 const size_t payload_size =
block_->
data_.data.size_;
607 size_t copy_size = payload_size;
611 if (payload_size != buffer.
size_)
618 if (payload_size < buffer.
size_)
622 copy_size = buffer.
size_;
626 if (payload_size > buffer.
size_)
640 template <SizeLimitMode Mode = SizeLimitMode::MORE>
656 void PublishRaw(
void* addr, uint32_t size, MicrosecondTimestamp timestamp,
657 bool from_callback,
bool in_isr);
659 static void CheckPublishSize(
TopicHandle topic, uint32_t size);
660 static RawData StorePublishedData(
TopicHandle topic,
void* addr, uint32_t size,
661 MicrosecondTimestamp timestamp);
662 static void DispatchSubscriber(SuberBlock& block, MicrosecondTimestamp timestamp,
663 RawData data,
bool from_callback,
bool in_isr);
664 static void DispatchSubscribers(
TopicHandle topic, MicrosecondTimestamp timestamp,
665 RawData data,
bool from_callback,
bool in_isr);
669#include "message/packet.hpp"
670#include "message/server.hpp"
671#include "message/subscriber.hpp"
static void SizeLimitCheck(size_t limit, size_t size)
在非调试模式下的占位大小检查函数(无实际作用)。 Dummy size limit check for non-debug builds.
链表实现,用于存储和管理数据节点。 A linked list implementation for storing and managing data nodes.
static void FastCopy(void *dst, const void *src, size_t size)
快速内存拷贝 / Fast memory copy
微秒时间戳 / Microsecond timestamp
互斥锁类,提供线程同步机制 (Mutex class providing thread synchronization mechanisms).
红黑树的泛型数据节点,继承自 BaseNode (Generic data node for Red-Black Tree, inheriting from BaseNode).
Data data_
存储的数据 (Stored data).
红黑树实现,支持泛型键和值,并提供线程安全操作 (Red-Black Tree implementation supporting generic keys and values with thread...
可写原始数据视图 / Mutable raw data view
size_t size_
数据字节数 / Data size in bytes
void * addr_
数据起始地址 / Data start address
异步订阅者类,用于订阅异步数据 Asynchronous subscriber class for subscribing to asynchronous data
主题域(Domain)管理器,用于组织多个主题。Domain manager for organizing multiple topics.
Domain(const char *name)
构造函数,初始化或查找指定名称的主题域。Constructor initializing or looking up a domain by name.
RBTree< uint32_t >::Node< RBTree< uint32_t > > * node_
指向该域的根节点。Pointer to the root node of the domain.
同步订阅者类,允许同步方式接收数据。Synchronous subscriber class allowing data reception in a synchronous manner.
主题(Topic)管理类 / Topic management class
SuberType
订阅者类型。Subscriber type.
void Publish(Data &data)
发布数据 Publishes data
static Domain * def_domain_
默认的主题域,所有未指定域的主题都会归入此域 Default domain where all topics without a specified domain are assigned
static void Unlock(TopicHandle topic)
解锁主题。Unlock the topic.
RBTree< uint32_t >::Node< Block > * TopicHandle
主题句柄,指向存储数据的红黑树节点。Handle pointing to a red-black tree node storing data.
static RawData NewSubscriberBuffer()
为异步订阅者分配长期存在的接收缓冲区。 Allocates a long-lived receive buffer for an async subscriber.
ErrorCode DumpData(Data &data)
转储数据到普通数据结构 Dumps data into a normal data structure
static MicrosecondTimestamp NowTimestamp()
生成默认发布时刻。Create the default publish timestamp.
ErrorCode DumpData(PackedData< Data > &data)
转储数据到 PackedData Dumps data into PackedData format
static void CheckSubscriberDataSize(Topic topic)
校验订阅者数据类型和主题最大长度是否兼容。 Checks whether subscriber data type is compatible with topic max length.
static void Lock(TopicHandle topic)
锁定主题,防止其被多个订阅者同时访问。Lock the topic to prevent it from being accessed by multiple subscribers at the sa...
static void UnlockFromCallback(TopicHandle topic)
从回调中解锁主题。Unlock the topic from a callback.
static TopicHandle FindOrCreate(const char *name, Domain *domain=nullptr, bool multi_publisher=false, bool cache=false, bool check_length=false)
在指定域中查找或创建主题 Finds or creates a topic in the specified domain
static void LockFromCallback(TopicHandle topic)
从回调中锁定主题,防止其被多个订阅者同时访问。Lock the topic from a callback to prevent it from being accessed by multiple s...
void EnableCache()
启用主题的缓存功能 Enables caching for the topic
static TopicHandle WaitTopic(const char *name, uint32_t timeout=UINT32_MAX, Domain *domain=nullptr)
等待主题的创建并返回其句柄 Waits for a topic to be created and returns its handle
static void PackData(uint32_t topic_name_crc32, RawData buffer, MicrosecondTimestamp timestamp, ConstRawData data)
打包数据
void PublishFromCallback(Data &data, bool in_isr)
在回调函数中发布数据 Publishes data in a callback
uint32_t GetKey() const
获取主题的键值 Gets the key value of the topic
TopicHandle block_
主题句柄,指向当前主题的内存块 Topic handle pointing to the memory block of the current topic
void RegisterCallback(Callback &cb)
注册回调函数 Registers a callback function
static TopicHandle Find(const char *name, Domain *domain=nullptr)
在指定域中查找主题 Finds a topic in the specified domain
static RBTree< uint32_t > * domain_
主题域的红黑树结构,存储不同的主题 Red-Black Tree structure for storing different topics in the domain
static Topic CreateTopic(const char *name, Domain *domain=nullptr, bool multi_publisher=false, bool cache=false, bool check_length=false)
创建一个新的主题 Creates a new topic
Topic()
默认构造函数,创建一个空的 Topic 实例 Default constructor, creates an empty Topic instance
ErrorCode DumpData(RawData data)
转储数据到原始缓冲区。Dumps data into a raw buffer.
@ SIZE_ERR
尺寸错误 | Size error
@ OK
操作成功 | Operation successful
@ LESS
尺寸必须小于 | Size must be less
@ EQUAL
尺寸必须相等 | Size must be equal
@ MORE
尺寸必须大于 | Size must be more
异步订阅块,继承自 SuberBlock Asynchronous subscription block, inheriting from SuberBlock
存储主题运行状态和静态配置。Stores topic runtime state and static configuration.
bool cache
是否启用数据缓存。Indicates whether data caching is enabled.
bool check_length
是否检查数据长度。Indicates whether data length is checked.
std::atomic< LockState > busy
是否忙碌。Indicates whether it is busy.
uint32_t max_length
数据的最大长度。Maximum length of data.
Mutex * mutex
线程同步互斥锁。Mutex for thread synchronization.
uint32_t crc32
主题名称的 CRC32 校验码。CRC32 checksum of the topic name.
RawData data
最近一次发布的数据视图。Latest published data view.
LockFreeList subers
订阅者列表。List of subscribers.
MicrosecondTimestamp timestamp
最近一次消息时间戳。Latest message timestamp.
回调订阅块,继承自 SuberBlock Callback subscription block, inheriting from SuberBlock
带时间戳的类型化消息。Timestamped typed message.
Data data
消息数据。Message payload.
MicrosecondTimestamp timestamp
消息时间戳。Message timestamp.
带时间戳的类型化消息视图。Timestamped typed message view.
Data & data
消息数据引用。Message data reference.
MicrosecondTimestamp timestamp
消息时间戳。Message timestamp.
队列订阅块,继承自 SuberBlock Queue subscription block, inheriting from SuberBlock
订阅者信息存储结构。Structure storing subscriber information.
同步订阅者存储结构。Structure storing synchronous subscriber data.