improve emitter

This commit is contained in:
lixianjing 2023-01-29 17:48:19 +08:00
parent 52d556ff7f
commit 54951573d0
4 changed files with 43 additions and 13 deletions

View File

@ -2,6 +2,7 @@
2023/01/29
* 完善how\_to\_use\_3rd\_lib.md文档(感谢雨欣提供补丁)
* 修复emitter多层消息分发递归后释放最顶级的iter后出现野指针导致崩溃的问题(感谢智明提供补丁)
2023/01/28
* 将scroll\_view的虚拟宽高作为布局时的宽高(感谢雨欣提供补丁)

View File

@ -71,7 +71,7 @@ static ret_t emitter_item_destroy(emitter_item_t* iter) {
static ret_t emitter_remove(emitter_t* emitter, emitter_item_t* prev, emitter_item_t* iter) {
return_value_if_fail(emitter != NULL && iter != NULL, RET_BAD_PARAMS);
if (emitter->curr_iter == iter) {
if (iter->working) {
iter->pending_remove = TRUE;
return RET_OK;
}
@ -121,16 +121,18 @@ ret_t emitter_dispatch(emitter_t* emitter, event_t* e) {
if (e->target == NULL) {
e->target = emitter;
}
emitter_curr_iter = emitter->curr_iter;
if (emitter->disable == 0 && emitter->items) {
emitter_item_t* iter = emitter->items;
while (iter != NULL) {
emitter->curr_iter = iter;
if (iter->type == e->type) {
bool_t is_working = iter->working;
iter->working = TRUE;
ret = iter->handler(iter->ctx, e);
if (!is_working) {
iter->working = FALSE;
}
if (ret == RET_STOP) {
emitter->curr_iter = emitter_curr_iter;
if (iter->pending_remove) {
emitter_remove_item(emitter, iter);
}
@ -138,7 +140,6 @@ ret_t emitter_dispatch(emitter_t* emitter, event_t* e) {
} else if (ret == RET_REMOVE || iter->pending_remove) {
emitter_item_t* next = iter->next;
emitter->curr_iter = NULL;
emitter_remove_item(emitter, iter);
iter = next;
@ -149,7 +150,6 @@ ret_t emitter_dispatch(emitter_t* emitter, event_t* e) {
iter = iter->next;
}
}
emitter->curr_iter = emitter_curr_iter;
return RET_OK;
}

View File

@ -36,6 +36,7 @@ struct _emitter_item_t {
event_func_t handler;
uint32_t tag;
bool_t working;
bool_t pending_remove;
tk_destroy_t on_destroy;
void* on_destroy_ctx;
@ -68,13 +69,6 @@ typedef struct _emitter_t {
* dispatch无效
*/
int32_t disable;
/**
* @property {emitter_item_t*} curr_iter
* @annotation ["private"]
* dispatch的项
*/
emitter_item_t* curr_iter;
} emitter_t;
/**

View File

@ -228,6 +228,41 @@ TEST(Emitter, remove_in_func2) {
emitter_destroy(emitter);
}
static ret_t on_emitter_dispatch(void* ctx, event_t* e) {
event_t e1;
uint32_t type = *((uint32_t*)ctx);
emitter_t* emitter = (emitter_t*)e->target;
e1 = event_init(type, emitter);
emitter_dispatch(emitter, &e1);
return RET_REMOVE;
}
TEST(Emitter, remove_in_func3) {
event_t e;
uint32_t n1 = 0;
uint32_t n2 = 0;
uint32_t id1 = 0;
uint32_t id2 = 0;
uint32_t type1 = 12;
uint32_t type2 = 13;
emitter_t* emitter = emitter_create();
e = event_init(type1, emitter);
emitter_on(emitter, type1, on_event, &n2);
id1 = emitter_on(emitter, type1, on_emitter_dispatch, &type2);
id2 = emitter_on(emitter, type2, on_remove_id, &id1);
emitter_on(emitter, type2, on_event, &n1);
ASSERT_EQ(emitter_dispatch(emitter, &e), RET_OK);
ASSERT_EQ(emitter_size(emitter), 2u);
ASSERT_EQ(n1, 1u);
ASSERT_EQ(n2, 1u);
emitter_destroy(emitter);
}
TEST(Emitter, remove_item) {
uint32_t i = 0;
uint32_t n = 5000;