pub_sub_feature.c代码分析
该文件主要功能
文件路径
一、背景知识
1.结构体和宏定义
消费节点结构体
typedef struct ConsumerNode {
UTILS_DL_LIST node;
Consumer *consumer;
} ConsumerNode;
关系结构体
typedef struct Relation {
UTILS_DL_LIST node; //节点
ConsumerNode callbacks; ///回调的消费节点
Topic topic; //定义关系主题
} Relation;
typedef struct PubSubFeature PubSubFeature;
PubSub 模式,是 Publish/Subscribe 的缩写,意为“发布/订阅”模式。
在实际使用中,我们应该也会接触到 PubSub 模式,例如 Nodejs 中的 EventEmitter、Backbone 中的事件模型、以及 jQuery 中的事件。 以 EventEmitter 为栗子,它提供了 addListener(event, listener),removeListener(event, listener),emit(event, [arg1], [arg2], […]) 方法。
struct PubSubFeature {
INHERIT_FEATURE; //特征信息
Relation *(*GetRelation)(PubSubFeature *feature, const Topic *topic);
MutexId mutex; //定义一个互斥锁
Relation relations; //定义一个关系结点
Identity identity; //一个身份信息
};
来自.c文件的结构体
将不同函数封装一下
static PubSubFeature g_broadcastFeature = {
.GetName = GetName, //获取名字
.OnInitialize = OnInitialize, //初始化变量
.OnStop = OnStop, //停止
.OnMessage = OnMessage, //消息信息的处理
.GetRelation = GetRelation,
};
二、代码分析
//初始化函数,一个初始化功能的封装。将一些常用全局变量进行初始化赋值
static void Init(void)
{
PubSubFeature *feature = &g_broadcastFeature;
feature->relations.topic = -1;
feature->relations.callbacks.consumer = NULL;
UtilsListInit(&feature->relations.callbacks.node);
UtilsListInit(&feature->relations.node);
feature->mutex = MUTEX_InitValue();
SAMGR_GetInstance()->RegisterFeature(BROADCAST_SERVICE, (Feature *)feature);
PubSubImplement *apiEntry = BCE_CreateInstance((Feature *)feature);
SAMGR_GetInstance()->RegisterFeatureApi(BROADCAST_SERVICE, PUB_SUB_FEATURE, GET_IUNKNOWN(*apiEntry));
}
消息写进topic进行比对,遍历链表判断身份值
//处理消息
static BOOL OnMessage(Feature *feature, Request *request)
{
PubSubFeature *broadcast = (PubSubFeature *)feature;
switch (request->msgId) {
//对消息的id
case MSG_PUBLISH: {
//id为1的处理
Topic topic = request->msgValue;//消息值写进topic
Relation *relation = broadcast->GetRelation(broadcast, &topic);
//根据topic和broadcast来获取关系
if (relation == NULL) {
return FALSE;
}
MUTEX_Lock(broadcast->mutex);
ConsumerNode *item = NULL;
UTILS_DL_LIST_FOR_EACH_ENTRY(item, &relation->callbacks.node, ConsumerNode, node) {
//遍历链表,判断身份是否为空
if (item->consumer->identity == NULL) {
item->consumer->Notify(item->consumer, &topic, request);
}
}
MUTEX_Unlock(broadcast->mutex);
//遍历结束就释放锁
}
break;
default:
break;
}
return TRUE;
}
//一个获取relation的函数,传入特征和topic就能指定具体一个relation
static Relation *GetRelation(PubSubFeature *feature, const Topic *topic)
{
if (feature == NULL || topic == NULL) {
return NULL;
}
UTILS_DL_LIST *list = &feature->relations.node;
Relation *item = NULL;
MUTEX_Lock(feature->mutex); //对特征信息中制定一个互斥锁变量
UTILS_DL_LIST_FOR_EACH_ENTRY(item, list, Relation, node) {
// 对链表的一个重要的操作就是对链表进行遍历,以达到某种应用目的,比如统计链表结点的个数等等。
if (IsTopicEqual(&item->topic, topic)) {
//遍历判断是否topic是否一致
MUTEX_Unlock(feature->mutex);
//释放锁
return item;
}
}
MUTEX_Unlock(feature->mutex);
return NULL;
}
//一个bool函数来判断topic是否相等
static BOOL IsTopicEqual(const Topic *current, const Topic *other)
{
return *current == *other;
//判断当前主题和传入的other主题是否一致
}
感谢阅读和点赞