mirror of
https://gitee.com/dlmu-cone/bf_original_balance_chassis
synced 2026-07-24 03:27:45 +08:00
Merge branch 'master' of gitee.com:hnuyuelurm/basic_framework
This commit is contained in:
@@ -2,78 +2,11 @@
|
||||
#include "stdlib.h"
|
||||
#include "string.h"
|
||||
|
||||
/* 消息初始化用 */
|
||||
static char pname[MAX_EVENT_COUNT][MAX_EVENT_NAME_LEN + 1];
|
||||
static char sname[MAX_EVENT_COUNT][MAX_EVENT_NAME_LEN + 1];
|
||||
static void *p_ptr[MAX_EVENT_COUNT] = {NULL};
|
||||
static void **s_pptr[MAX_EVENT_COUNT] = {NULL}; // 因为要修改指针,所以需要二重指针
|
||||
|
||||
/* ----------------------------------第三方指针传递版的实现,deprecated----------------------------------- */
|
||||
|
||||
void MessageInit()
|
||||
{
|
||||
// pub必须唯一,即消息名称不能重复,不得有多个pub发布相同消息名称
|
||||
// 对每一个subscriber,寻找相同消息名称的publisher,可能有多个sub从相同pub获取消息
|
||||
for (size_t i = 0; i < MAX_EVENT_COUNT; ++i)
|
||||
{
|
||||
if (s_pptr[i] != NULL)
|
||||
{
|
||||
for (size_t j = 0; j < MAX_EVENT_COUNT; ++j) // 遍历publisher
|
||||
{
|
||||
if (p_ptr[j] != NULL) // 不为空
|
||||
{
|
||||
if (strcmp(sname[i], pname[j]) == 0) // 比较消息名是否一致
|
||||
{
|
||||
*s_pptr[i] = p_ptr[j]; // 将sub的指针指向pub的数据
|
||||
break;
|
||||
}
|
||||
}
|
||||
else // 到结尾,退出
|
||||
{
|
||||
while (1)
|
||||
; // 如果你卡在这里,说明没有找到消息发布者!请确认消息名称是否键入错误
|
||||
}
|
||||
}
|
||||
}
|
||||
else // 说明已经遍历完所有的subs
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* 传入数据地址 */
|
||||
void PublisherRegister(char *name, void *data)
|
||||
{
|
||||
static uint8_t idx;
|
||||
for (size_t i = 0; i < idx; ++i)
|
||||
{
|
||||
if (strcmp(pname[i], name) == 0)
|
||||
while (1)
|
||||
; // 运行至此说明pub的消息发布名称冲突
|
||||
}
|
||||
strcpy(pname[idx], name);
|
||||
p_ptr[idx++] = data;
|
||||
}
|
||||
|
||||
/* 注意传入的是指针的地址,传参时使用&对数据指针取地址 */
|
||||
void SubscribeEvent(char *name, void **data_ptr)
|
||||
{
|
||||
static uint8_t idx;
|
||||
strcpy(sname[idx], name);
|
||||
s_pptr[idx++] = data_ptr;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/* ----------------------------------链表-队列版的实现----------------------------------- */
|
||||
|
||||
/* message_center是fake head node,是方便链表编写的技巧,这样就不需要处理链表头的特殊情况 */
|
||||
static Publisher_t message_center = {
|
||||
.event_name = "Message_Manager",
|
||||
.first_subs = NULL,
|
||||
.next_event_node = NULL
|
||||
};
|
||||
.next_event_node = NULL};
|
||||
|
||||
static void CheckName(char *name)
|
||||
{
|
||||
@@ -112,18 +45,18 @@ Subscriber_t *SubRegister(char *name, uint8_t data_len)
|
||||
{ // 给消息队列的每一个元素分配空间,queue里保存的实际上是数据执指针,这样可以兼容不同的数据长度
|
||||
ret->queue[i] = malloc(sizeof(data_len));
|
||||
}
|
||||
//如果是第一个订阅者,特殊处理一下
|
||||
if(node->first_subs==NULL)
|
||||
// 如果是第一个订阅者,特殊处理一下
|
||||
if (node->first_subs == NULL)
|
||||
{
|
||||
node->first_subs=ret;
|
||||
node->first_subs = ret;
|
||||
return ret;
|
||||
}
|
||||
// 遍历订阅者链表,直到到达尾部
|
||||
Subscriber_t *sub = node->first_subs; // 作为iterator
|
||||
while (sub->next_subs_queue) // 遍历订阅了该事件的订阅者链表
|
||||
while (sub->next_subs_queue) // 遍历订阅了该事件的订阅者链表
|
||||
{
|
||||
sub = sub->next_subs_queue; // 移动到下一个订阅者,遇到空指针停下,说明到了链表尾部
|
||||
}
|
||||
}
|
||||
sub->next_subs_queue = ret; // 把刚刚创建的订阅者接上
|
||||
return ret;
|
||||
}
|
||||
@@ -157,6 +90,7 @@ Publisher_t *PubRegister(char *name, uint8_t data_len)
|
||||
if (strcmp(node->event_name, name) == 0) // 如果已经注册了相同的事件,直接返回结点指针
|
||||
{
|
||||
CheckLen(data_len, node->data_len);
|
||||
node->pub_registered_flag = 1;
|
||||
return node;
|
||||
}
|
||||
} // 遍历完发现尚未创建name对应的事件
|
||||
@@ -165,6 +99,7 @@ Publisher_t *PubRegister(char *name, uint8_t data_len)
|
||||
memset(node->next_event_node, 0, sizeof(Publisher_t));
|
||||
node->next_event_node->data_len = data_len;
|
||||
strcpy(node->next_event_node->event_name, name);
|
||||
node->pub_registered_flag = 1;
|
||||
return node->next_event_node;
|
||||
}
|
||||
|
||||
@@ -189,7 +124,7 @@ uint8_t PubPushMessage(Publisher_t *pub, void *data_ptr)
|
||||
while (iter)
|
||||
{
|
||||
if (iter->temp_size == QUEUE_SIZE) // 如果队列已满,则需要删除最老的数据(头部),再填入
|
||||
{
|
||||
{
|
||||
// 队列头索引前移动,相当于抛弃前一个位置的数据,被抛弃的位置稍后会被写入新的数据
|
||||
iter->front_idx = (iter->front_idx + 1) % QUEUE_SIZE;
|
||||
iter->temp_size--; // 相当于出队,size-1
|
||||
|
||||
@@ -19,30 +19,6 @@
|
||||
#define MAX_EVENT_COUNT 12 // 最多支持的事件数量
|
||||
#define QUEUE_SIZE 1
|
||||
|
||||
/**
|
||||
* @brief 在所有应用初始化结束之后调用,当作app的"回调函数"
|
||||
*
|
||||
*/
|
||||
void MessageInit();
|
||||
|
||||
/**
|
||||
* @brief 注册成为消息发布者
|
||||
*
|
||||
* @param name 消息标识名,注意不要超过MAX_EVENT_NAME_LEN
|
||||
* @param data 发布者的数据地址
|
||||
*/
|
||||
void PublisherRegister(char *name, void *data);
|
||||
|
||||
/**
|
||||
* @brief 订阅消息,成为消息订阅者
|
||||
*
|
||||
* @param name 消息标识名
|
||||
* @param data 保存数据的指针的地址,注意这是一个二级指针,传入的时候对数据指针取地址(&)
|
||||
*/
|
||||
void SubscribeEvent(char *name, void **data);
|
||||
|
||||
#endif // !PUBSUB_H
|
||||
|
||||
typedef struct mqt
|
||||
{
|
||||
/* 用数组模拟FIFO队列 */
|
||||
@@ -69,6 +45,7 @@ typedef struct ent
|
||||
Subscriber_t *first_subs;
|
||||
/* 指向下一个Publisher的指针 */
|
||||
struct ent *next_event_node;
|
||||
uint8_t pub_registered_flag; // 用于标记该发布者是否已经注册
|
||||
} Publisher_t;
|
||||
|
||||
/**
|
||||
@@ -105,3 +82,5 @@ uint8_t SubGetMessage(Subscriber_t *sub, void *data_ptr);
|
||||
* @return uint8_t 新消息成功推送给几个订阅者
|
||||
*/
|
||||
uint8_t PubPushMessage(Publisher_t *pub, void *data_ptr);
|
||||
|
||||
#endif // !PUBSUB_H
|
||||
Reference in New Issue
Block a user