5#include "libxr_def.hpp"
6#include "libxr_type.hpp"
8#include "lock_queue.hpp"
9#include "lockfree_queue.hpp"
13#include "semaphore.hpp"
14#include "spin_lock.hpp"
55 uint32_t data_len : 24;
56 uint8_t pack_header_crc8;
67 template <
typename Data>
77 struct __attribute__((packed))
79 PackedDataHeader header;
91 const Data &operator=(
const Data &data)
94 crc8_ = CRC8::Calculate(&raw,
sizeof(raw));
102 operator Data() {
return raw.data_; }
107 Data *operator->() {
return &(raw.data_); }
113 const Data *operator->()
const {
return &(raw.data_); }
149 {
return static_cast<int>(
a) -
static_cast<int>(
b); });
166 {
return static_cast<int>(
a) -
static_cast<int>(
b); });
214 template <
typename Data>
238 if (
topic.block_->data_.check_length)
240 ASSERT(
topic.block_->data_.max_length ==
sizeof(
Data));
244 ASSERT(
topic.block_->data_.max_length <=
sizeof(
Data));
260 return block_->data_.sem.Wait(timeout);
284 template <
typename Data>
306 if (
topic.block_->data_.check_length)
308 ASSERT(
topic.block_->data_.max_length ==
sizeof(
Data));
312 ASSERT(
topic.block_->data_.max_length <=
sizeof(
Data));
339 block_->data_.data_ready =
false;
340 return *
reinterpret_cast<Data *
>(
block_->data_.buff.addr_);
376 template <
typename Data, u
int32_t Length>
390 template <
typename Data>
393 if (
topic.block_->data_.check_length)
395 ASSERT(
topic.block_->data_.max_length ==
sizeof(
Data));
399 ASSERT(
topic.block_->data_.max_length <=
sizeof(
Data));
404 block->data_.queue = &queue;
423 template <
typename Data>
436 template <
typename Data>
439 if (
topic.block_->data_.check_length)
441 ASSERT(
topic.block_->data_.max_length ==
sizeof(
Data));
445 ASSERT(
topic.block_->data_.max_length <=
sizeof(
Data));
450 block->data_.queue = &queue;
504 bool cache =
false,
bool check_length =
false)
513 {
return static_cast<int>(
a) -
static_cast<int>(
b); });
533 ASSERT(
topic->data_.max_length == max_length);
534 ASSERT(
topic->data_.check_length == check_length);
542 block_->data_.crc32 = crc32;
543 block_->data_.data.addr_ =
nullptr;
544 block_->data_.cache =
false;
545 block_->data_.check_length = check_length;
550 if (cache && !
block_->data_.cache)
568 template <
typename Data>
570 bool check_length =
true)
614 template <
typename Data>
616 bool cache =
false,
bool check_length =
true)
619 if (
topic ==
nullptr)
632 block_->data_.mutex.Lock();
635 block_->data_.cache =
true;
638 block_->data_.mutex.Unlock();
647 template <
typename Data>
660 template <
typename Data>
674 block_->data_.mutex.Lock();
675 if (
block_->data_.check_length)
677 ASSERT(size ==
block_->data_.max_length);
687 block_->data_.data.size_ = size;
691 block_->data_.data.addr_ = addr;
692 block_->data_.data.size_ = size;
714 async->data_ready =
true;
731 return ErrorCode::OK;
736 block_->data_.mutex.Unlock();
748 if (
block_->data_.mutex.TryLockInCallback(
in_isr) != ErrorCode::OK)
753 if (
block_->data_.check_length)
755 ASSERT(size ==
block_->data_.max_length);
765 block_->data_.data.size_ = size;
769 block_->data_.data.addr_ = addr;
770 block_->data_.data.size_ = size;
790 async->data_ready =
true;
806 return ErrorCode::OK;
823 template <SizeLimitMode Mode = SizeLimitMode::MORE>
826 if (
block_->data_.data.addr_ ==
nullptr)
828 return ErrorCode::EMPTY;
833 Assert::SizeLimitCheck<Mode>(
block_->data_.data.size_, data.
size_);
834 block_->data_.mutex.Lock();
836 block_->data_.mutex.Unlock();
842 block_->data_.mutex.Lock();
843 PackData(
block_->data_.crc32, data,
block_->data_.data);
844 block_->data_.mutex.Unlock();
847 return ErrorCode::OK;
856 pack->raw.header.prefix = 0xa5;
858 pack->raw.header.data_len =
source.size_;
859 pack->raw.header.pack_header_crc8 =
873 template <
typename Data>
876 if (
block_->data_.data.addr_ ==
nullptr)
878 return ErrorCode::EMPTY;
881 ASSERT(
sizeof(
Data) ==
block_->data_.data.size_);
892 template <
typename Data>
895 if (
block_->data_.data.addr_ ==
nullptr)
897 return ErrorCode::EMPTY;
900 ASSERT(
sizeof(
Data) ==
block_->data_.data.size_);
923 if (
topic ==
nullptr)
931 }
while (
topic ==
nullptr);
971 {
return static_cast<int>(
a) -
static_cast<int>(
b); }),
基础队列类,提供固定大小的循环缓冲区 (Base queue class providing a fixed-size circular buffer).
ErrorCode Pop(void *data=nullptr)
移除队列头部的元素 (Pop the front element from the queue).
size_t Size()
获取队列中的元素个数 (Get the number of elements in the queue).
ErrorCode PopBatch(void *data, size_t size)
批量移除多个元素 (Pop multiple elements from the queue).
ErrorCode Peek(void *data)
获取队列头部的元素但不移除 (Peek at the front element without removing it).
ErrorCode PushBatch(const void *data, size_t size)
批量推入多个元素 (Push multiple elements into the queue).
static uint32_t Calculate(const void *raw, size_t len)
计算数据的 CRC32 校验码 / Computes the CRC32 checksum for the given data
static uint8_t Calculate(const void *raw, size_t len)
计算数据的 CRC8 校验码 / Computes the CRC8 checksum for the given data
static bool Verify(const void *raw, size_t len)
验证数据的 CRC8 校验码 / Verifies the CRC8 checksum of the given data
提供一个通用的回调包装,支持动态参数传递。 Provides a generic callback wrapper, supporting dynamic argument passing.
常量原始数据封装类。 A class for encapsulating constant raw data.
size_t size_
数据大小(字节)。 The size of the data (in bytes).
const void * addr_
数据存储地址(常量)。 The storage address of the data (constant).
数据节点模板,继承自 BaseNode,用于存储具体数据类型。 Template data node that inherits from BaseNode to store specific data...
Data data_
存储的数据。 The stored data.
链表实现,用于存储和管理数据节点。 A linked list implementation for storing and managing data nodes.
无锁队列实现 / Lock-free queue implementation
ErrorCode Push(ElementData &&item)
向队列中推入数据 / Pushes data into the queue
线程安全的队列实现,基于 FreeRTOS 消息队列 Thread-safe queue implementation based on FreeRTOS message queue
ErrorCode PushFromCallback(const Data &data, bool in_isr)
从 ISR(中断服务例程)推入数据 Pushes data into the queue from an ISR (Interrupt Service Routine)
互斥锁类,提供线程同步机制 (Mutex class providing thread synchronization mechanisms).
红黑树的泛型数据节点,继承自 BaseNode (Generic data node for Red-Black Tree, inheriting from BaseNode).
红黑树实现,支持泛型键和值,并提供线程安全操作 (Red-Black Tree implementation supporting generic keys and values with thread...
Node< Data > * Search(const Key &key)
搜索红黑树中的节点 (Search for a node in the Red-Black Tree).
void Insert(BaseNode &node, KeyType &&key)
在树中插入新节点 (Insert a new node into the tree).
原始数据封装类。 A class for encapsulating raw data.
size_t size_
数据大小(字节)。 The size of the data (in bytes).
void * addr_
数据存储地址。 The storage address of the data.
信号量类,实现线程同步机制 Semaphore class implementing thread synchronization
轻量级自旋锁实现 / Lightweight spinlock implementation
void Lock() noexcept
阻塞直到获取锁 / Blocks until the lock is acquired
void Unlock() noexcept
释放锁 / Releases the lock
static uint32_t GetTime()
获取当前系统时间(毫秒) Gets the current system time in milliseconds
static void Sleep(uint32_t milliseconds)
让线程进入休眠状态 Puts the thread to sleep
异步订阅者类,用于订阅异步数据 Asynchronous subscriber class for subscribing to asynchronous data
ASyncSubscriber(Topic topic)
构造函数,使用 Topic 进行初始化 Constructor using a Topic for initialization
Data & GetData()
获取当前数据 Retrieves the current data
bool Available()
检查数据是否可用 Checks if data is available
List::Node< ASyncBlock > * block_
订阅者数据块。Subscriber data block.
ASyncSubscriber(const char *name, Domain *domain=nullptr)
构造函数,通过名称和数据创建订阅者 Constructor to create a subscriber with a name and data
void StartWaiting()
开始等待数据更新 Starts waiting for data update
主题域(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.
构造函数,使用名称和无锁队列进行初始化 Constructor using a name and a lock-free queue
QueuedSubscriber(Topic topic, LockFreeQueue< Data > &queue)
构造函数,使用 Topic 和无锁队列进行初始化 Constructor using a Topic and a lock-free queue
QueuedSubscriber(const char *name, LockQueue< Data > &queue, Domain *domain=nullptr)
构造函数,使用名称和带锁队列进行初始化 Constructor using a name and a locked queue
QueuedSubscriber(Topic topic, LockQueue< Data > &queue)
构造函数,使用 Topic 和带锁队列进行初始化 Constructor using a Topic and a locked queue
服务器类,负责解析数据并将其分发到相应的主题 Server class responsible for parsing data and distributing it to corresponding...
RBTree< uint32_t > topic_map_
主题映射表 Topic mapping table
void Register(TopicHandle topic)
注册一个主题 Registers a topic
Server(size_t buffer_length)
构造函数,初始化服务器并分配缓冲区 Constructor to initialize the server and allocate buffer
BaseQueue queue_
数据队列 Data queue
size_t ParseData(ConstRawData data)
解析接收到的数据 Parses received data
TopicHandle current_topic_
当前主题句柄 Current topic handle
uint32_t data_len_
当前数据长度 Current data length
Status
服务器解析状态枚举 Enumeration of server parsing states
@ WAIT_DATA_CRC
等待数据校验 Waiting for data CRC validation
@ WAIT_START
等待起始标志 Waiting for start flag
@ WAIT_TOPIC
等待主题信息 Waiting for topic information
RawData parse_buff_
解析数据缓冲区 Data buffer for parsing
Status status_
服务器的当前解析状态 Current parsing state of the server
同步订阅者类,允许同步方式接收数据。Synchronous subscriber class allowing data reception in a synchronous manner.
SyncSubscriber(Topic topic, Data &data)
通过 Topic 句柄构造同步订阅者。Constructs a synchronous subscriber using a Topic handle.
ErrorCode Wait(uint32_t timeout=UINT32_MAX)
等待接收数据。Waits for data reception.
List::Node< SyncBlock > * block_
订阅者数据块。Subscriber data block.
SyncSubscriber(const char *name, Data &data, Domain *domain=nullptr)
通过主题名称构造同步订阅者。Constructs a synchronous subscriber by topic name.
主题(Topic)管理类 / Topic management class
void Publish(void *addr, uint32_t size)
以原始地址和大小发布数据 Publishes data using raw address and size
SuberType
订阅者类型。Subscriber type.
@ SYNC
同步订阅者。Synchronous subscriber.
@ ASYNC
异步订阅者。Asynchronous subscriber.
@ QUEUE
队列订阅者。Queued subscriber.
@ CALLBACK
回调订阅者。Callback subscriber.
RBTree< uint32_t >::Node< Block > * TopicHandle
主题句柄,指向存储数据的红黑树节点。Handle pointing to a red-black tree node storing data.
void Publish(Data &data)
发布数据 Publishes data
Topic(const char *name, uint32_t max_length, Domain *domain=nullptr, bool cache=false, bool check_length=false)
构造函数,使用指定名称、最大长度、域及其他选项初始化主题 Constructor to initialize a topic with the specified name,...
static Domain * def_domain_
默认的主题域,所有未指定域的主题都会归入此域 Default domain where all topics without a specified domain are assigned
ErrorCode DumpData(Data &data)
转储数据到普通数据结构 Dumps data into a normal data structure
void PublishFromCallback(void *addr, uint32_t size, bool in_isr)
从回调函数发布数据 Publishes data from a callback function
static Topic CreateTopic(const char *name, Domain *domain=nullptr, bool cache=false, bool check_length=true)
创建一个新的主题 Creates a new topic
static TopicHandle FindOrCreate(const char *name, Domain *domain=nullptr, bool cache=false, bool check_length=true)
在指定域中查找或创建主题 Finds or creates a topic in the specified domain
Topic()
默认构造函数,创建一个空的 Topic 实例 Default constructor, creates an empty Topic instance
void EnableCache()
启用主题的缓存功能 Enables caching for the topic
void RegisterCallback(Callback< RawData & > &cb)
注册回调函数 Registers a callback function
ErrorCode DumpData(PackedData< Data > &data)
转储数据到 PackedData Dumps data into PackedData format
static TopicHandle Find(const char *name, Domain *domain=nullptr)
在指定域中查找主题 Finds a topic in the specified domain
Topic(TopicHandle topic)
通过句柄构造主题 Constructs a topic from a topic handle
ErrorCode DumpData(RawData data, bool pack=false)
转储数据 Dump data
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
void PublishFromCallback(Data &data, bool in_isr)
从回调函数发布数据 Publishes data from a callback function
static SpinLock domain_lock_
主题域访问的自旋锁,确保多线程安全 SpinLock for domain access to ensure thread safety
TopicHandle block_
主题句柄,指向当前主题的内存块 Topic handle pointing to the memory block of the current topic
static RBTree< uint32_t > * domain_
主题域的红黑树结构,存储不同的主题 Red-Black Tree structure for storing different topics in the domain
LibXR Color Control Library / LibXR终端颜色控制库
constexpr auto min(T1 a, T2 b) -> typename std::common_type< T1, T2 >::type
计算两个数的最小值
异步订阅块,继承自 SuberBlock Asynchronous subscription block, inheriting from SuberBlock
RawData buff
缓冲区数据 Buffer data
bool waiting
等待中标志 Waiting flag
bool data_ready
数据就绪标志 Data ready flag
存储主题(Topic)数据的结构体。Structure storing topic data.
bool cache
是否启用数据缓存。Indicates whether data caching is enabled.
Mutex mutex
线程同步互斥锁。Mutex for thread synchronization.
List subers
订阅者列表。List of subscribers.
bool check_length
是否检查数据长度。Indicates whether data length is checked.
uint32_t max_length
数据的最大长度。Maximum length of data.
uint32_t crc32
主题名称的 CRC32 校验码。CRC32 checksum of the topic name.
RawData data
存储的数据。Stored data.
回调订阅块,继承自 SuberBlock Callback subscription block, inheriting from SuberBlock
Callback< RawData & > cb
订阅的回调函数 Subscribed callback function
队列订阅块,继承自 SuberBlock Queue subscription block, inheriting from SuberBlock
void * queue
指向订阅队列的指针 Pointer to the subscribed queue
void(* fun)(RawData &, void *, bool)
处理数据的回调函数 Callback function to handle data
订阅者信息存储结构。Structure storing subscriber information.
SuberType type
订阅者类型。Type of subscriber.
同步订阅者存储结构。Structure storing synchronous subscriber data.
Semaphore sem
信号量,用于同步等待数据。Semaphore for data synchronization.
RawData buff
存储的数据缓冲区。Data buffer.