涂鸦TuyaOS
Event是一个轻量级的事件通知库。其特点是:
- 支持订阅-发布模式的事件机制,使用非常简单方便,可以在任意位置、任意时间进行时间的订阅;
- 轻量级,专注于进程内部的事件通知,代码小巧,仅400行。
- 跨平台,基于涂鸦
TuyaOS
的跨平台特性,可以在任意平台上运行。
- 有弹性,默认情况下,事件是同步调用,基于涂鸦
TuyaOS
的跨平台特性,可以在订阅函数里使用Work Queue实现多线程的异步机制。
接口描述
发布事件
发布一个事件通知,包含了事件的数据,告知所有订阅者进行处理。事件发布首先会去搜索是否当前事件是否已经创建。
- 没有被创建:说明之前并没有发布过相同的事件,但是可能会存在订阅者,由于他们没有找到事件,会被暂存到
free_subscribe_root
。因此需要从free_subscribe_root
里查找是否有该事件的订阅者,如果有则把这些订阅者从free_subscribe_root
里拿出来,挂载到事件的subscribe_root
,然后再进行事件的发布。
- 已经被创建:说之前已经有发布过相同的事件,所有的订阅者都已经被正常处理,不需要再关心是否有订阅者在
free_subscribe_root
中,可以直接进行事件发布。
- 事件发布,遍历事件
subscribe_root
,对于每个订阅者,发布事件的数据,调用订阅者的回调函数,判断并记录回调函数的返回值。
- 如果不存在订阅者,意味着不需要发布,也不需要创建事件的资源
OPERATE_RET ty_publish_event(CONST CHAR_T *name, VOID_T *data)
: publish event
订阅事件
关注一个事件,包含了事件的名称、关注的用途以及处理数据的回调函数。事件订阅首先会去搜索是否当前事件是否已经创建。
- 没有被创建:说明此事件没有产生过,需要把订阅者暂存到
free_subscribe_root
。
- 已经被创建:说明此时间已经产生过,可以直接把订阅者挂载到事件的
subscribe_root
可以订阅的事件分为3种,可以按照实际需求选择:
- SUBSCRIBE_TYPE_NORMAL, 普通订阅,按照顺序处理
- SUBSCRIBE_TYPE_EMERGENCY,紧急订阅,优先处理
- SUBSCRIBE_TYPE_ONETIME,一次性订阅,处理一次即取消
订阅事件不会拿到事件的上一次状态,一个原因是如果暂存数据会消耗较大的资源,另外一个原因是没有必要。
OPERATE_RET ty_subscribe_event(CONST CHAR_T *name, CONST CHAR_T *desc, CONST EVENT_SUBSCRIBE_CB cb, SUBSCRIBE_TYPE_E type)
: subscribe event
BYTE_T SUBSCRIBE_TYPE_E
subscriber type
Definition: base_event.h:42
INT_T(* EVENT_SUBSCRIBE_CB)(VOID_T *data)
event subscribe callback function type
Definition: base_event.h:61
取消订阅
取消关注一个事件,包含了事件的名称、关注的用途以及处理数据的回调函数。如果当前订阅者没有绑定事件,则从free_subscribe_root
移除;
如果订阅者绑定了事件,且为最后一个订阅者,则需要从事件的subscribe_root
移除,并销毁该事件。否则,仅从事件的subscribe_root
中移除订阅者。
OPERATE_RET ty_unsubscribe_event(CONST CHAR_T *name, CONST CHAR_T *desc, EVENT_SUBSCRIBE_CB cb)
: unsubscribe event
示例代码
#define EVENT_SAMPLE "publish.sample"
OPERATE_RET sample_subcribe_cb(event_data_t *raw_data)
{
event_data_t *data = (event_data_t*)raw_data;
TAL_PR_DEBUG("recv event");
return OPRT_OK;
}
OPERATE_RET sample_subcribe_emergence_cb(event_data_t *raw_data)
{
event_data_t *data = (event_data_t*)raw_data;
TAL_PR_DEBUG("recv event emergence");
return OPRT_OK;
}
OPERATE_RET sample_subcribe_onetime_cb(event_data_t *raw_data)
{
event_data_t *data = (event_data_t*)raw_data;
TAL_PR_DEBUG("recv event emergence");
return OPRT_OK;
}
OPERATE_RET sample_event_test()
{
OPERATE_RET rt = OPRT_OK;
EXPECT_EQ(rt, OPRT_OK);
char desc[] = "subscribe.sample";
EXPECT_EQ(rt, OPRT_OK);
EXPECT_EQ(rt, OPRT_OK);
rt =
ty_subscribe_event(EVENT_SAMPLE, desc, sample_subcribe_emergence_cb, SUBSCRIBE_TYPE_EMERGENCY);
EXPECT_EQ(rt, OPRT_OK);
rt =
ty_subscribe_event(EVENT_SAMPLE, desc, sample_subcribe_onetime_cb, EVENT_TYPE_ONETIME);
EXPECT_EQ(rt, OPRT_OK);
EXPECT_EQ(rt, OPRT_OK);
EXPECT_EQ(rt, OPRT_OK);
EXPECT_EQ(rt, OPRT_OK);
return OPRT_OK;
}