为了实现代码的解耦,根据设计模式中的观察者模式设计了一个消息订阅的机制。当某个模块需要得到某些消息的通知时,可以使用topic_subscribe
订阅想要的消息,并将回调函数注册进去,当消息使用msg_notify
通知时,会触发已经注册了的回调;
整体代码如下:
.h文件
#ifndef __MSG_SUBSCRIBE_H_
#define __MSG_SUBSCRIBE_H_
/*消息的类型都在这个枚举里*/
typedef enum
{
ON_OFF_STATE,
LIGHTNESS,
WORK_MODE,
TOPIC_MAX
}topic_e;
typedef void (*observer_handle)(void* msg);
typedef struct
{
observer_handle func;
topic_e topic;
}observer_t;
/*消息订阅并将回调注册进去*/
int topic_subscribe(observer_t *observer);
/*消息通知*/
int msg_notify(topic_e topic, void *msg);
#endif /* __MSG_SUBSCRIBE_H_ */
.c文件
#include <stdio.h>
#include "msg_subscribe.h"
typedef struct _Link_List
{
observer_handle func;
struct _Link_List* next;
}Observer_Node;
Observer_Node* func_head_node[TOPIC_MAX] = {NULL};
int topic_subscribe(observer_t* observer)
{
assert(observer->topic >= TOPIC_MAX || observer->func == NULL || observer == NULL);
Observer_Node* func_link_tail = func_head_node[observer->topic];
if(func_link_tail != NULL)
{
while(func_link_tail->next != NULL)
{
func_link_tail = func_link_tail->next;
}
}
Observer_Node* observer_node = (Observer_Node*)malloc(sizeof(Observer_Node));
assert(observer_node == NULL)
observer_node->func = observer->func;
observer_node->next = NULL;
if(func_link_tail == NULL)
{
func_head_node[observer->topic] = observer_node;
}
else
{
func_link_tail->next = observer_node;
}
return 0;
}
int msg_notify(topic_e topic, void* msg)
{
assert(topic >= TOPIC_MAX);
Observer_Node* cur_node = func_head_node[topic];
printf("Msg notify %d\r\n", topic);
while(cur_node != NULL)
{
assert(cur_node->func == NULL);
cur_node->func(msg);
cur_node = cur_node->next;
}
return 0;
}