嵌入式-订阅发布资源池
直接上源代码,自己体会。
头文件 topic.h
#ifndef __TOPIC_H
#define __TOPIC_H
#include <stdint.h>
#include <stdbool.h>
#define TOPIC_POOL_MAX (40) // 主题资源池最大支持主题数
typedef void (*TopicCb)(void* msg);
bool Topic_Init(uint8_t topic, TopicCb* buff, uint8_t size);
bool Topic_Pushlish(uint8_t topic, void *msg);
bool Topic_Subscrib(uint8_t topic, TopicCb cb);
#endif
源文件 topic.c
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <stdbool.h>
#include "topic.h"
#define TOPICCB_PER_ID_COUNT (3) // 每个主题最大支持订阅者数量
#define TOPICCB_POOL_MAX (TOPIC_POOL_MAX * TOPICCB_PER_ID_COUNT) // 订阅者池
typedef struct _Topic{
uint8_t id; // 主题标识
TopicCb* buff; // 订阅主题目标
uint8_t size; // 目标最大容量
uint8_t count; // 目标使用数
}Topic_t;
static Topic_t s_Topic_Pool[TOPIC_POOL_MAX]; // 主题资源池
static uint8_t s_Topic_Count = 0; // 资源池使用个数
static TopicCb s_TopicCb_Pool[TOPICCB_POOL_MAX]; // 订阅者资源池
static uint8_t s_TopicCb_Count = 0; // 资源池已占用个数
Topic_t* Topic_Find(uint8_t topic)
{
int i = 0;
for(i = 0;i < s_Topic_Count; i++)
{
if(topic == s_Topic_Pool[i].id)
{
return &s_Topic_Pool[i];
}
}
return NULL;
}
/*****************************************************************************
* Function : Topic_Init
* Description : 主题初始化
* Input : uint8_t topic 主题标识符
TopicCb* buff 订阅者缓冲区
uint8_t size 最大支持订阅者数量
* Output : bool
*****************************************************************************/
bool Topic_Init(uint8_t topic, TopicCb* buff, uint8_t size)
{
if(s_Topic_Count >= TOPIC_POOL_MAX)
{
return false;
}
Topic_t* pTopic = Topic_Find(topic);
if(pTopic)
{
return true;
}
pTopic = &s_Topic_Pool[s_Topic_Count];
s_Topic_Count ++;
pTopic->id = topic;
if(pTopic->buff)
{
pTopic->buff = buff;
pTopic->size = size;
}
else
{
pTopic->buff = &s_TopicCb_Pool[s_TopicCb_Count];
pTopic->size = TOPICCB_PER_ID_COUNT;
s_TopicCb_Count += TOPICCB_PER_ID_COUNT;
}
pTopic->count = 0;
memset(pTopic->buff, 0x0, pTopic->size);
return true;
}
bool Topic_Pushlish(uint8_t topic, void *msg)
{
if(s_Topic_Count == 0)
{
return false;
}
Topic_t* pTopic = Topic_Find(topic);
if(pTopic == NULL)
{
return false;
}
int i = 0;
for(i = 0; i < pTopic->count; i ++)
{
if(pTopic->buff[i])
{
pTopic->buff[i](msg);
}
}
return true;
}
bool Topic_Subscrib(uint8_t topic, TopicCb cb)
{
Topic_t* pTopic = Topic_Find(topic);
if(pTopic == NULL)
{
return false;
}
if(pTopic->count >= pTopic->size)
{
return false;
}
pTopic->buff[pTopic->count] = cb;
pTopic->count++;
return true;
}