rework emitter

This commit is contained in:
xianjimli 2018-06-21 10:16:11 +08:00
parent 75c53ca461
commit 2cda38f2f7
6 changed files with 390 additions and 103 deletions

View File

@ -118,13 +118,13 @@
#include "res/inc/images/unchecked.data" #include "res/inc/images/unchecked.data"
#include "res/inc/images/unmuted.data" #include "res/inc/images/unmuted.data"
#include "res/inc/images/warn.data" #include "res/inc/images/warn.data"
#endif/*WITH_STB_IMAGE*/ #endif /*WITH_STB_IMAGE*/
#ifdef WITH_STB_FONT #ifdef WITH_STB_FONT
#include "res/inc/fonts/default.res" #include "res/inc/fonts/default.res"
#else #else
#include "res/inc/fonts/default.data" #include "res/inc/fonts/default.data"
#endif/*WITH_STB_FONT*/ #endif /*WITH_STB_FONT*/
#endif/*WITH_FS_RES*/ #endif /*WITH_FS_RES*/
ret_t resource_init(void) { ret_t resource_init(void) {
resource_manager_t* rm = resource_manager(); resource_manager_t* rm = resource_manager();

View File

@ -31,80 +31,86 @@ emitter_t* emitter_create() {
emitter_t* emitter_init(emitter_t* emitter) { emitter_t* emitter_init(emitter_t* emitter) {
return_value_if_fail(emitter, NULL); return_value_if_fail(emitter, NULL);
memset(emitter, 0x00, sizeof(emitter_t)); memset(emitter, 0x00, sizeof(emitter_t));
emitter->enable = TRUE; emitter->enable = TRUE;
emitter->curr_id = 1; emitter->next_id = TK_INVALID_ID + 1;
return emitter; return emitter;
} }
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) {
emitter->remove_curr_iter = TRUE;
return RET_OK;
}
if (iter == emitter->items) {
emitter->items = iter->next;
} else {
prev->next = iter->next;
}
TKMEM_FREE(iter);
return RET_OK;
}
ret_t emitter_dispatch(emitter_t* emitter, event_t* e) { ret_t emitter_dispatch(emitter_t* emitter, event_t* e) {
ret_t ret = RET_OK;
return_value_if_fail(emitter != NULL && e != NULL, RET_BAD_PARAMS); return_value_if_fail(emitter != NULL && e != NULL, RET_BAD_PARAMS);
if (!(e->time)) { if (!(e->time)) {
e->time = time_now_ms(); e->time = time_now_ms();
} }
if (e->target == NULL) {
e->target = emitter;
}
if (emitter->enable && emitter->items) { if (emitter->enable && emitter->items) {
uint32_t i = 0; emitter_item_t* iter = emitter->items;
uint32_t size = emitter->size; emitter_item_t* prev = emitter->items;
emitter_item_t* items = emitter->items;
while (iter != NULL) {
emitter->curr_iter = iter;
emitter->stop = FALSE;
for (i = 0; i < size; i++) {
emitter_item_t* iter = items + i;
if (iter->type == e->type) { if (iter->type == e->type) {
iter->handler(iter->ctx, e); ret = iter->handler(iter->ctx, e);
if (ret == RET_STOP) {
return ret;
} else if (ret == RET_REMOVE || emitter->remove_curr_iter) {
emitter->curr_iter = NULL;
emitter->remove_curr_iter = FALSE;
emitter_remove(emitter, prev, iter);
}
} }
if (emitter->stop) { prev = iter;
break; iter = iter->next;
}
} }
} }
emitter->curr_iter = NULL;
emitter->remove_curr_iter = FALSE;
return RET_OK; return RET_OK;
} }
static ret_t emitter_extends(emitter_t* emitter, uint32_t nr) { uint32_t emitter_on(emitter_t* emitter, uint32_t etype, event_func_t handler, void* ctx) {
uint32_t capacity = 0;
emitter_item_t* items = NULL;
if (emitter->items && emitter->size < emitter->capacity) {
return RET_OK;
}
if (emitter->items == NULL) {
emitter->items = TKMEM_ZALLOC(emitter_item_t);
return_value_if_fail(emitter->items != NULL, RET_FAIL);
emitter->size = 0;
emitter->capacity = 1;
return RET_OK;
}
capacity = emitter->capacity + 5;
items = TKMEM_REALLOC(emitter_item_t, emitter->items, capacity);
return_value_if_fail(items != NULL, RET_FAIL);
emitter->items = items;
emitter->capacity = capacity;
return RET_OK;
}
uint32_t emitter_on(emitter_t* emitter, uint16_t etype, event_func_t handler, void* ctx) {
emitter_item_t* iter = NULL; emitter_item_t* iter = NULL;
return_value_if_fail(emitter != NULL && handler != NULL, 0); return_value_if_fail(emitter != NULL && handler != NULL, TK_INVALID_ID);
return_value_if_fail(emitter_extends(emitter, 1) == RET_OK, 0);
iter = TKMEM_ZALLOC(emitter_item_t);
return_value_if_fail(iter != NULL, TK_INVALID_ID);
iter = emitter->items + emitter->size;
iter->type = etype; iter->type = etype;
iter->ctx = ctx; iter->ctx = ctx;
iter->handler = handler; iter->handler = handler;
iter->id = emitter->curr_id++; iter->id = emitter->next_id++;
iter->next = emitter->items;
emitter->size++; emitter->items = iter;
return iter->id; return iter->id;
} }
@ -113,76 +119,76 @@ emitter_item_t* emitter_find(emitter_t* emitter, uint32_t id) {
return_value_if_fail(emitter != NULL, NULL); return_value_if_fail(emitter != NULL, NULL);
if (emitter->items) { if (emitter->items) {
uint32_t i = 0; emitter_item_t* iter = emitter->items;
uint32_t size = emitter->size;
emitter_item_t* items = emitter->items;
for (i = 0; i < size; i++) { while (iter != NULL) {
emitter_item_t* iter = items + i;
if (iter->id == id) { if (iter->id == id) {
return iter; return iter;
} }
iter = iter->next;
} }
} }
return NULL; return NULL;
} }
uint32_t emitter_size(emitter_t* emitter) {
uint32_t size = 0;
return_value_if_fail(emitter != NULL, size);
if (emitter->items) {
emitter_item_t* iter = emitter->items;
while (iter != NULL) {
size++;
iter = iter->next;
}
}
return size;
}
ret_t emitter_off(emitter_t* emitter, uint32_t id) { ret_t emitter_off(emitter_t* emitter, uint32_t id) {
return_value_if_fail(emitter != NULL, RET_BAD_PARAMS); return_value_if_fail(emitter != NULL, RET_BAD_PARAMS);
if (emitter->items) { if (emitter->items) {
uint32_t i = 0; emitter_item_t* iter = emitter->items;
uint32_t size = emitter->size; emitter_item_t* prev = emitter->items;
emitter_item_t* items = emitter->items;
for (i = 0; i < size; i++) { while (iter != NULL) {
emitter_item_t* iter = items + i;
if (iter->id == id) { if (iter->id == id) {
for (; i < (size - 1); i++) { return emitter_remove(emitter, prev, iter);
items[i] = items[i + 1];
}
emitter->size--;
return RET_OK;
} }
prev = iter;
iter = iter->next;
} }
} }
return RET_FAIL; return RET_FAIL;
} }
ret_t emitter_off_by_func(emitter_t* emitter, uint16_t etype, event_func_t handler, void* ctx) { ret_t emitter_off_by_func(emitter_t* emitter, uint32_t etype, event_func_t handler, void* ctx) {
return_value_if_fail(emitter != NULL && handler != NULL, RET_BAD_PARAMS); return_value_if_fail(emitter != NULL && handler != NULL, RET_BAD_PARAMS);
if (emitter->items) { if (emitter->items) {
uint32_t i = 0; emitter_item_t* iter = emitter->items;
uint32_t size = emitter->size; emitter_item_t* prev = emitter->items;
emitter_item_t* items = emitter->items;
for (i = 0; i < size; i++) { while (iter != NULL) {
emitter_item_t* iter = items + i;
if (iter->type == etype && iter->ctx == ctx && iter->handler == handler) { if (iter->type == etype && iter->ctx == ctx && iter->handler == handler) {
for (; i < (size - 1); i++) { return emitter_remove(emitter, prev, iter);
items[i] = items[i + 1];
}
emitter->size--;
return RET_OK;
} }
prev = iter;
iter = iter->next;
} }
} }
return RET_FAIL; return RET_FAIL;
} }
ret_t emitter_stop(emitter_t* emitter) {
return_value_if_fail(emitter != NULL, RET_BAD_PARAMS);
emitter->stop = TRUE;
return RET_OK;
}
ret_t emitter_enable(emitter_t* emitter) { ret_t emitter_enable(emitter_t* emitter) {
return_value_if_fail(emitter != NULL, RET_BAD_PARAMS); return_value_if_fail(emitter != NULL, RET_BAD_PARAMS);
emitter->enable = TRUE; emitter->enable = TRUE;
@ -200,7 +206,15 @@ ret_t emitter_disable(emitter_t* emitter) {
ret_t emitter_deinit(emitter_t* emitter) { ret_t emitter_deinit(emitter_t* emitter) {
return_value_if_fail(emitter != NULL, RET_BAD_PARAMS); return_value_if_fail(emitter != NULL, RET_BAD_PARAMS);
if (emitter->items) { if (emitter->items) {
TKMEM_FREE(emitter->items); emitter_item_t* iter = emitter->items;
emitter_item_t* next = emitter->items;
while (iter != NULL) {
next = iter->next;
TKMEM_FREE(iter);
iter = next;
}
emitter->items = NULL;
} }
return RET_OK; return RET_OK;

View File

@ -26,36 +26,175 @@
BEGIN_C_DECLS BEGIN_C_DECLS
typedef struct _emitter_item_t { struct _emitter_item_t;
uint32_t id; typedef struct _emitter_item_t emitter_item_t;
uint16_t type;
void* ctx;
event_func_t handler;
} emitter_item_t;
struct _emitter_item_t {
void* ctx;
uint32_t id;
uint32_t type;
event_func_t handler;
emitter_item_t* next;
};
/**
* @class emitter_t
* @scriptable no
* ,
*/
typedef struct _emitter_t { typedef struct _emitter_t {
uint8_t size; /**
uint8_t capacity; * @property {emitter_item_t*} items
uint8_t stop; * @private
uint8_t enable; *
*/
emitter_item_t* items; emitter_item_t* items;
uint32_t curr_id; /**
* @property {uint32_t} next_id
* @private
* emitter_on返回的IDemitter_on成功后会自动增加next_id
*/
uint32_t next_id;
/**
* @property {bool_t} enable
* @readonly
* dispatch无效
*/
bool_t enable;
/**
* @property {bool_t} remove_curr_iter
* @private
* emitter_off当前正在dispatch的回调函数remove_curr_iter为TRUE
* XXX: dispatch的回调函数RET_REMOVE是最好的选择
*/
bool_t remove_curr_iter;
/**
* @property {emitter_item_t*} curr_iter
* @private
* dispatch的项
*/
emitter_item_t* curr_iter;
} emitter_t; } emitter_t;
/**
* @method emitter_create
* @constructor
* emitter对象
*
* @return {emitter_t*}
*/
emitter_t* emitter_create(void); emitter_t* emitter_create(void);
/**
* @method emitter_init
* @constructor
* emitter对象
* @param {emitter_t*} emitter emitter对象
*
* @return {emitter_t*}
*/
emitter_t* emitter_init(emitter_t* emitter); emitter_t* emitter_init(emitter_t* emitter);
/**
* @method emitter_dispatch
* RET_REMOVE
*
* @param {emitter_t*} emitter emitter对象
* @param {event_t*} e
* @return {ret_t}
RET_STOPdispatch中断分发RET_STOPRET_OK
*/
ret_t emitter_dispatch(emitter_t* emitter, event_t* e); ret_t emitter_dispatch(emitter_t* emitter, event_t* e);
uint32_t emitter_on(emitter_t* emitter, uint16_t etype, event_func_t handler, void* ctx); /**
ret_t emitter_off(emitter_t* emitter, uint32_t id); * @method emitter_on
emitter_item_t* emitter_find(emitter_t* emitter, uint32_t id); *
ret_t emitter_off_by_func(emitter_t* emitter, uint16_t etype, event_func_t handler, void* ctx); * @param {emitter_t*} emitter emitter对象
* @param {event_type_t} type
* @param {event_func_t} on_event
* @param {void*} ctx
*
* @return {uint32_t} idemitter_off
*/
uint32_t emitter_on(emitter_t* emitter, uint32_t etype, event_func_t handler, void* ctx);
ret_t emitter_stop(emitter_t* emitter); /**
* @method emitter_off
*
* @param {emitter_t*} emitter emitter对象
* @param {uint32_t} id emitter_on返回的ID
*
* @return {ret_t} RET_OK表示成功
*/
ret_t emitter_off(emitter_t* emitter, uint32_t id);
/**
* @method emitter_off_by_func
*
* @param {emitter_t*} emitter emitter对象
* @param {event_type_t} type
* @param {event_func_t} on_event
* @param {void*} ctx
*
* @return {ret_t} RET_OK表示成功
*/
ret_t emitter_off_by_func(emitter_t* emitter, uint32_t etype, event_func_t handler, void* ctx);
/**
* @method emitter_find
* ID查找emitter_item_t
* @param {emitter_t*} emitter emitter对象
* @param {uint32_t} id emitter_on返回的ID
*
* @return {ret_t} RET_OK表示成功
*/
emitter_item_t* emitter_find(emitter_t* emitter, uint32_t id);
/**
* @method emitter_enable
*
* @param {emitter_t*} emitter emitter对象
*
* @return {ret_t} RET_OK表示成功
*/
ret_t emitter_enable(emitter_t* emitter); ret_t emitter_enable(emitter_t* emitter);
/**
* @method emitter_disable
* emitter_dispatch无效
* @param {emitter_t*} emitter emitter对象
*
* @return {ret_t} RET_OK表示成功
*/
ret_t emitter_disable(emitter_t* emitter); ret_t emitter_disable(emitter_t* emitter);
/**
* @method emitter_size
*
* @param {emitter_t*} emitter emitter对象
*
* @return {uint32_t}
*/
uint32_t emitter_size(emitter_t* emitter);
/**
* @method emitter_deinit
*
* @param {emitter_t*} emitter emitter对象
*
* @return {ret_t} RET_OK表示成功
*/
ret_t emitter_deinit(emitter_t* emitter); ret_t emitter_deinit(emitter_t* emitter);
/**
* @method emitter_destroy
*
* @param {emitter_t*} emitter emitter对象
*
* @return {ret_t} RET_OK表示成功
*/
ret_t emitter_destroy(emitter_t* emitter); ret_t emitter_destroy(emitter_t* emitter);
END_C_DECLS END_C_DECLS

View File

@ -94,6 +94,11 @@ typedef enum _ret_t {
* *
*/ */
RET_DONE, RET_DONE,
/**
* @const RET_STOP
*
*/
RET_STOP,
/** /**
* @const RET_BAD_PARAMS * @const RET_BAD_PARAMS
* *
@ -236,5 +241,6 @@ typedef float float_t;
#define TK_MAX_FPS 100 #define TK_MAX_FPS 100
#define TK_OPACITY_ALPHA 0xfa #define TK_OPACITY_ALPHA 0xfa
#define TK_TRANSPARENT_ALPHA 0x05 #define TK_TRANSPARENT_ALPHA 0x05
#define TK_INVALID_ID 0
#endif /*TYPES_DEF_H*/ #endif /*TYPES_DEF_H*/

4
src/window_animators/vtranslate.inc Executable file → Normal file
View File

@ -44,8 +44,8 @@ static ret_t window_animator_open_vtranslate_draw_curr(window_animator_t* wa) {
#ifdef WITH_NANOVG #ifdef WITH_NANOVG
vgcanvas_t* vg = lcd_get_vgcanvas(c->lcd); vgcanvas_t* vg = lcd_get_vgcanvas(c->lcd);
vgcanvas_draw_image(vg, &(wa->curr_img), win->x*ratio, win->y*ratio, win->w * ratio, h * ratio, win->x, y, win->w, vgcanvas_draw_image(vg, &(wa->curr_img), win->x * ratio, win->y * ratio, win->w * ratio,
h); h * ratio, win->x, y, win->w, h);
#else #else
rect_t src; rect_t src;
rect_t dst; rect_t dst;

View File

@ -15,12 +15,37 @@ static ret_t on_event(void* ctx, event_t* e) {
return RET_OK; return RET_OK;
} }
static ret_t on_remove(void* ctx, event_t* e) {
uint32_t* p = (uint32_t*)ctx;
*p = *p + 1;
(void)e;
return RET_REMOVE;
}
static ret_t on_remove_id(void* ctx, event_t* e) {
uint32_t id = *((uint32_t*)ctx);
emitter_t* emitter = (emitter_t*)e->target;
emitter_off(emitter, id);
return RET_REMOVE;
}
static ret_t on_stop(void* ctx, event_t* e) {
uint32_t* p = (uint32_t*)ctx;
*p = *p + 1;
(void)e;
return RET_STOP;
}
TEST(Emitter, basic) { TEST(Emitter, basic) {
event_t e; event_t e;
uint32_t n = 0; uint32_t n = 0;
emitter_t emitter; emitter_t emitter;
emitter_init(&emitter); emitter_init(&emitter);
uint16_t type = 12; uint32_t type = 12;
e.type = type; e.type = type;
ASSERT_EQ(emitter_on(NULL, type, on_event, NULL), 0); ASSERT_EQ(emitter_on(NULL, type, on_event, NULL), 0);
ASSERT_EQ(emitter_on(&emitter, type, NULL, NULL), 0); ASSERT_EQ(emitter_on(&emitter, type, NULL, NULL), 0);
@ -50,3 +75,106 @@ TEST(Emitter, basic) {
emitter_deinit(&emitter); emitter_deinit(&emitter);
} }
TEST(Emitter, off) {
event_t e;
uint32_t n = 0;
uint32_t id = 0;
uint32_t type = 12;
emitter_t* emitter = emitter_create();
e.type = type;
id = emitter_on(emitter, type, on_event, &n);
ASSERT_EQ(id > TK_INVALID_ID, true);
ASSERT_EQ(emitter_size(emitter), 1);
ASSERT_EQ(emitter_find(emitter, id) != NULL, true);
ASSERT_EQ(emitter_off(emitter, id), RET_OK);
ASSERT_EQ(emitter_size(emitter), 0);
ASSERT_EQ(emitter_find(emitter, id) == NULL, true);
id = emitter_on(emitter, type, on_event, &n);
ASSERT_EQ(id > TK_INVALID_ID, true);
ASSERT_EQ(emitter_size(emitter), 1);
ASSERT_EQ(emitter_find(emitter, id) != NULL, true);
id = emitter_on(emitter, type, on_event, &n);
ASSERT_EQ(id > TK_INVALID_ID, true);
ASSERT_EQ(emitter_size(emitter), 2);
ASSERT_EQ(emitter_find(emitter, id) != NULL, true);
ASSERT_EQ(emitter_off(emitter, id), RET_OK);
ASSERT_EQ(emitter_size(emitter), 1);
emitter_destroy(emitter);
}
TEST(Emitter, remove) {
event_t e;
uint32_t n = 0;
uint32_t id = 0;
uint32_t type = 12;
emitter_t* emitter = emitter_create();
e.type = type;
id = emitter_on(emitter, type, on_remove, &n);
id = emitter_on(emitter, type, on_remove, &n);
id = emitter_on(emitter, type, on_remove, &n);
id = emitter_on(emitter, type, on_remove, &n);
n = 0;
ASSERT_EQ(emitter_dispatch(emitter, &e), RET_OK);
ASSERT_EQ(emitter_size(emitter), 0);
ASSERT_EQ(n, 4);
emitter_destroy(emitter);
}
TEST(Emitter, stop) {
event_t e;
uint32_t n = 0;
uint32_t id = 0;
uint32_t type = 12;
emitter_t* emitter = emitter_create();
e.type = type;
id = emitter_on(emitter, type, on_stop, &n);
id = emitter_on(emitter, type, on_stop, &n);
id = emitter_on(emitter, type, on_stop, &n);
id = emitter_on(emitter, type, on_stop, &n);
n = 0;
ASSERT_EQ(emitter_size(emitter), 4);
ASSERT_EQ(emitter_dispatch(emitter, &e), RET_STOP);
ASSERT_EQ(emitter_size(emitter), 4);
ASSERT_EQ(n, 1);
emitter_destroy(emitter);
}
TEST(Emitter, remove_in_func) {
event_t e;
uint32_t n = 0;
uint32_t id1 = 0;
uint32_t id2 = 0;
uint32_t type = 12;
emitter_t* emitter = emitter_create();
e.type = type;
e.target = emitter;
id1 = emitter_on(emitter, type, on_event, &n);
id2 = emitter_on(emitter, type, on_remove_id, &id1);
ASSERT_EQ(emitter_dispatch(emitter, &e), RET_OK);
ASSERT_EQ(emitter_size(emitter), 0);
id1 = emitter_on(emitter, type, on_event, &n);
id2 = emitter_on(emitter, type, on_remove_id, &id2);
ASSERT_EQ(emitter_dispatch(emitter, &e), RET_OK);
ASSERT_EQ(emitter_size(emitter), 1);
emitter_destroy(emitter);
}