涂鸦TuyaOS Event是一个轻量级的事件通知库。其特点是:
- 支持订阅-发布模式的事件机制,使用非常简单方便,可以在任意位置、任意时间进行时间的订阅;
- 轻量级,专注于进程内部的事件通知,代码小巧,仅400行。
- 跨平台,基于涂鸦
TuyaOS的跨平台特性,可以在任意平台上运行。
- 有弹性,默认情况下,事件是同步调用,基于涂鸦
TuyaOS的跨平台特性,可以在订阅函数里使用Work Queue或者Timer Queue实现多线程的异步机制。
接口描述
发布事件
int ty_publish_event(const char *name, void *data)
: publish event
发布一个事件通知,包含了事件的数据,告知所有订阅者进行处理。事件发布首先会去搜索是否当前事件是否已经创建。
- 没有被创建:说明之前并没有发布过相同的事件,但是可能会存在订阅者,由于他们没有找到事件,会被暂存到
free_subscribe_root。因此需要从free_subscribe_root里查找是否有该事件的订阅者,如果有则把这些订阅者从free_subscribe_root里拿出来,挂载到事件的subscribe_root,然后再进行事件的发布。
- 已经被创建:说之前已经有发布过相同的事件,所有的订阅者都已经被正常处理,不需要再关心是否有订阅者在
free_subscribe_root中,可以直接进行事件发布。
- 事件发布,遍历事件
subscribe_root,对于每个订阅者,发布事件的数据,调用订阅者的回调函数,判断并记录回调函数的返回值。
- 如果不存在订阅者,意味着不需要发布,也不需要创建事件的资源
订阅事件
int(* event_subscribe_cb)(void *data)
event subscribe callback function type
Definition: base_event.h:60
BYTE_T SUBSCRIBE_TYPE_E
subscriber type
Definition: base_event.h:41
int ty_subscribe_event(const char *name, const char *desc, const event_subscribe_cb cb, SUBSCRIBE_TYPE_E type)
: subscribe event
关注一个事件,包含了事件的名称、关注的用途以及处理数据的回调函数。事件订阅首先会去搜索是否当前事件是否已经创建。
- 没有被创建:说明此事件没有产生过,需要把订阅者暂存到
free_subscribe_root。
- 已经被创建:说明此时间已经产生过,可以直接把订阅者挂载到事件的
subscribe_root
订阅事件不会拿到事件的上一次状态,一个原因是如果暂存数据会消耗较大的资源,另外一个原因是没有必要。
取消订阅
int ty_unsubscribe_event(const char *name, const char *desc, event_subscribe_cb cb)
: unsubscribe event
取消关注一个事件,包含了事件的名称、关注的用途以及处理数据的回调函数。如果当前订阅者没有绑定事件,则从free_subscribe_root移除;
如果订阅者绑定了事件,且为最后一个订阅者,则需要从事件的subscribe_root移除,并销毁该事件。否则,仅从事件的subscribe_root中移除订阅者。
示例代码
#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()
{
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);
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);
return OPRT_OK;
}