mirror of
https://gitee.com/zlgopen/awtk.git
synced 2024-11-30 11:08:34 +08:00
rework widget pool
This commit is contained in:
parent
fc3554ee3d
commit
b04cafeb24
@ -87,7 +87,7 @@ OS_PROJECTS=[]
|
||||
if OS_NAME == 'Darwin':
|
||||
OS_LIBS = ['stdc++', 'pthread', 'm', 'dl']
|
||||
OS_LINKFLAGS='-framework Cocoa -framework QuartzCore -framework OpenGL -weak_framework Metal -weak_framework MetalKit'
|
||||
COMMON_CCFLAGS = COMMON_CCFLAGS + ' -DWITH_WIDGET_POOL '
|
||||
COMMON_CCFLAGS = COMMON_CCFLAGS + ' -DWITH_WIDGET_POOL=1000 '
|
||||
COMMON_CCFLAGS = COMMON_CCFLAGS + ' -D__APPLE__ -DHAS_PTHREAD -DMACOS -DENABLE_MEM_LEAK_CHECK '
|
||||
COMMON_CCFLAGS = COMMON_CCFLAGS + ' -D__STDC_LIMIT_MACROS -D__STDC_FORMAT_MACROS -D__STDC_CONSTANT_MACROS -DBGFX_CONFIG_RENDERER_METAL=1 '
|
||||
|
||||
|
@ -31,9 +31,10 @@
|
||||
#include "base/input_method.h"
|
||||
#include "base/image_manager.h"
|
||||
#include "base/window_manager.h"
|
||||
#include "base/widget_animator_manager.h"
|
||||
#include "base/widget_factory.h"
|
||||
#include "base/assets_manager.h"
|
||||
#include "base/widget_pool.h"
|
||||
#include "base/widget_animator_manager.h"
|
||||
#include "font_loader/font_loader_bitmap.h"
|
||||
|
||||
#ifdef WITH_SDL
|
||||
@ -101,7 +102,9 @@ ret_t tk_init_internal(void) {
|
||||
#endif /*WITH_TRUETYPE_FONT*/
|
||||
|
||||
return_value_if_fail(platform_prepare() == RET_OK, RET_FAIL);
|
||||
|
||||
#ifdef WITH_WIDGET_POOL
|
||||
return_value_if_fail(widget_pool_set(widget_pool_create(WITH_WIDGET_POOL)) == RET_OK, RET_FAIL);
|
||||
#endif /*WITH_WIDGET_POOL*/
|
||||
return_value_if_fail(timer_init(time_now_ms) == RET_OK, RET_FAIL);
|
||||
return_value_if_fail(idle_manager_set(idle_manager_create()) == RET_OK, RET_FAIL);
|
||||
return_value_if_fail(input_method_set(input_method_create()) == RET_OK, RET_FAIL);
|
||||
@ -161,6 +164,11 @@ ret_t tk_deinit_internal(void) {
|
||||
locale_info_destroy(locale_info());
|
||||
locale_info_set(NULL);
|
||||
|
||||
#ifdef WITH_WIDGET_POOL
|
||||
widget_pool_destroy(widget_pool());
|
||||
widget_pool_set(NULL);
|
||||
#endif /*WITH_WIDGET_POOL*/
|
||||
|
||||
assets_manager_destroy(assets_manager());
|
||||
assets_manager_set(NULL);
|
||||
|
||||
|
@ -29,6 +29,7 @@
|
||||
#include "base/widget.h"
|
||||
#include "base/layout.h"
|
||||
#include "base/main_loop.h"
|
||||
#include "base/widget_pool.h"
|
||||
#include "base/system_info.h"
|
||||
#include "base/widget_vtable.h"
|
||||
#include "base/image_manager.h"
|
||||
@ -36,7 +37,6 @@
|
||||
#include "base/widget_animator_manager.h"
|
||||
#include "base/widget_animator_factory.h"
|
||||
|
||||
static ret_t widget_reset(widget_t* widget);
|
||||
static ret_t widget_do_destroy(widget_t* widget);
|
||||
static ret_t widget_destroy_sync(widget_t* widget);
|
||||
static ret_t widget_destroy_async(widget_t* widget);
|
||||
@ -1398,52 +1398,6 @@ uint32_t widget_add_timer(widget_t* widget, timer_func_t on_timer, uint32_t dura
|
||||
return id;
|
||||
}
|
||||
|
||||
static ret_t widget_reset(widget_t* widget) {
|
||||
if (widget->name != NULL) {
|
||||
widget->name[0] = '\0';
|
||||
}
|
||||
|
||||
if (widget->animation != NULL) {
|
||||
widget->animation[0] = '\0';
|
||||
}
|
||||
|
||||
if (widget->style != NULL) {
|
||||
widget->style[0] = '\0';
|
||||
}
|
||||
|
||||
if (widget->tr_text != NULL) {
|
||||
widget->tr_text[0] = '\0';
|
||||
}
|
||||
|
||||
widget->floating = FALSE;
|
||||
widget->auto_created = FALSE;
|
||||
|
||||
widget->parent = NULL;
|
||||
widget->target = NULL;
|
||||
widget->emitter = NULL;
|
||||
widget->children = NULL;
|
||||
widget->key_target = NULL;
|
||||
widget->self_layout = NULL;
|
||||
widget->grab_widget = NULL;
|
||||
widget->custom_props = NULL;
|
||||
widget->children_layout = NULL;
|
||||
|
||||
return RET_OK;
|
||||
}
|
||||
|
||||
static ret_t widget_recycle(widget_t* widget) {
|
||||
return_value_if_fail(widget != NULL && widget->vt != NULL, RET_BAD_PARAMS);
|
||||
if (widget->vt->recycle != NULL) {
|
||||
if (widget->vt->recycle(widget) == RET_OK) {
|
||||
widget_reset(widget);
|
||||
|
||||
return RET_OK;
|
||||
}
|
||||
}
|
||||
|
||||
return RET_NOT_IMPL;
|
||||
}
|
||||
|
||||
static ret_t widget_destroy_sync(widget_t* widget) {
|
||||
event_t e = event_init(EVT_DESTROY, widget);
|
||||
return_value_if_fail(widget != NULL && widget->vt != NULL, RET_BAD_PARAMS);
|
||||
@ -1482,21 +1436,14 @@ static ret_t widget_destroy_sync(widget_t* widget) {
|
||||
|
||||
widget->destroying = FALSE;
|
||||
|
||||
if (widget_recycle(widget) != RET_OK) {
|
||||
if (widget->vt->on_destroy) {
|
||||
widget->vt->on_destroy(widget);
|
||||
}
|
||||
return widget_pool_destroy_widget(widget_pool(), widget);
|
||||
}
|
||||
|
||||
TKMEM_FREE(widget->name);
|
||||
TKMEM_FREE(widget->style);
|
||||
TKMEM_FREE(widget->tr_text);
|
||||
TKMEM_FREE(widget->animation);
|
||||
widget_t* widget_create(widget_t* parent, const widget_vtable_t* vt, xy_t x, xy_t y, wh_t w,
|
||||
wh_t h) {
|
||||
return_value_if_fail(vt != NULL, NULL);
|
||||
|
||||
memset(widget, 0x00, sizeof(widget_t));
|
||||
TKMEM_FREE(widget);
|
||||
}
|
||||
|
||||
return RET_OK;
|
||||
return widget_init(widget_pool_create_widget(widget_pool(), vt), parent, vt, x, y, w, h);
|
||||
}
|
||||
|
||||
static ret_t widget_destroy_in_idle(const idle_info_t* info) {
|
||||
@ -1635,18 +1582,6 @@ widget_t* widget_init(widget_t* widget, widget_t* parent, const widget_vtable_t*
|
||||
return widget;
|
||||
}
|
||||
|
||||
widget_t* widget_create(widget_t* parent, const widget_vtable_t* vt, xy_t x, xy_t y, wh_t w,
|
||||
wh_t h) {
|
||||
widget_t* widget = NULL;
|
||||
return_value_if_fail(vt != NULL && vt->size >= sizeof(widget_t), NULL);
|
||||
|
||||
widget = TKMEM_ALLOC(vt->size);
|
||||
return_value_if_fail(widget != NULL, NULL);
|
||||
memset(widget, 0x00, vt->size);
|
||||
|
||||
return widget_init(widget, parent, vt, x, y, w, h);
|
||||
}
|
||||
|
||||
ret_t widget_get_prop_default_value(widget_t* widget, const char* name, value_t* v) {
|
||||
ret_t ret = RET_OK;
|
||||
return_value_if_fail(widget != NULL && name != NULL && v != NULL, RET_BAD_PARAMS);
|
||||
|
@ -65,7 +65,6 @@ typedef ret_t (*widget_set_prop_t)(widget_t* widget, const char* name, const val
|
||||
typedef widget_t* (*widget_find_target_t)(widget_t* widget, xy_t x, xy_t y);
|
||||
typedef widget_t* (*widget_create_t)(widget_t* parent, xy_t x, xy_t y, wh_t w, wh_t h);
|
||||
typedef ret_t (*widget_on_destroy_t)(widget_t* widget);
|
||||
typedef ret_t (*widget_recycle_t)(widget_t* widget);
|
||||
|
||||
struct _widget_vtable_t {
|
||||
uint32_t size;
|
||||
@ -92,7 +91,7 @@ struct _widget_vtable_t {
|
||||
uint32_t is_keyboard : 1;
|
||||
|
||||
/**
|
||||
* 是否启用pool。
|
||||
* 是否启用pool(如果启用pool,控件需要对其成员全部变量初始化,不能假定成员变量为0)。
|
||||
*/
|
||||
uint32_t enable_pool : 1;
|
||||
|
||||
@ -117,7 +116,6 @@ struct _widget_vtable_t {
|
||||
widget_on_remove_child_t on_remove_child;
|
||||
widget_on_event_t on_event;
|
||||
widget_find_target_t find_target;
|
||||
widget_recycle_t recycle;
|
||||
widget_on_destroy_t on_destroy;
|
||||
};
|
||||
|
||||
|
232
src/base/widget_pool.c
Normal file
232
src/base/widget_pool.c
Normal file
@ -0,0 +1,232 @@
|
||||
/**
|
||||
* File: widget_pool.c
|
||||
* Author: AWTK Develop Team
|
||||
* Brief: widget pool
|
||||
*
|
||||
* Copyright (c) 2019 - 2019 Guangzhou ZHIYUAN Electronics Co.,Ltd.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* License file for more details.
|
||||
*
|
||||
*/
|
||||
|
||||
/**
|
||||
* History:
|
||||
* ================================================================
|
||||
* 2019-01-15 Li XianJing <xianjimli@hotmail.com> created
|
||||
*
|
||||
*/
|
||||
|
||||
#include "tkc/darray.h"
|
||||
#include "base/widget.h"
|
||||
#include "base/widget_pool.h"
|
||||
|
||||
static widget_pool_t* s_widget_pool;
|
||||
|
||||
static ret_t widget_pool_reset_widget(widget_t* widget) {
|
||||
if (widget->name != NULL) {
|
||||
widget->name[0] = '\0';
|
||||
}
|
||||
|
||||
if (widget->animation != NULL) {
|
||||
widget->animation[0] = '\0';
|
||||
}
|
||||
|
||||
if (widget->style != NULL) {
|
||||
widget->style[0] = '\0';
|
||||
}
|
||||
|
||||
if (widget->tr_text != NULL) {
|
||||
widget->tr_text[0] = '\0';
|
||||
}
|
||||
|
||||
widget->floating = FALSE;
|
||||
widget->auto_created = FALSE;
|
||||
|
||||
widget->parent = NULL;
|
||||
widget->target = NULL;
|
||||
widget->emitter = NULL;
|
||||
widget->children = NULL;
|
||||
widget->key_target = NULL;
|
||||
widget->self_layout = NULL;
|
||||
widget->grab_widget = NULL;
|
||||
widget->custom_props = NULL;
|
||||
widget->children_layout = NULL;
|
||||
|
||||
return RET_OK;
|
||||
}
|
||||
|
||||
static ret_t widget_pool_real_destroy_widget(widget_t* widget) {
|
||||
if (widget->vt->on_destroy) {
|
||||
widget->vt->on_destroy(widget);
|
||||
}
|
||||
|
||||
TKMEM_FREE(widget->name);
|
||||
TKMEM_FREE(widget->style);
|
||||
TKMEM_FREE(widget->tr_text);
|
||||
TKMEM_FREE(widget->animation);
|
||||
|
||||
memset(widget, 0x00, sizeof(widget_t));
|
||||
TKMEM_FREE(widget);
|
||||
|
||||
return RET_OK;
|
||||
}
|
||||
|
||||
static widget_t* widget_pool_real_create_widget(const widget_vtable_t* vt) {
|
||||
widget_t* widget = TKMEM_ALLOC(vt->size);
|
||||
return_value_if_fail(widget != NULL, NULL);
|
||||
|
||||
memset(widget, 0x00, vt->size);
|
||||
widget->vt = vt;
|
||||
|
||||
return widget;
|
||||
}
|
||||
|
||||
widget_pool_t* widget_pool(void) {
|
||||
return s_widget_pool;
|
||||
}
|
||||
|
||||
ret_t widget_pool_set(widget_pool_t* pool) {
|
||||
s_widget_pool = pool;
|
||||
|
||||
return RET_OK;
|
||||
}
|
||||
|
||||
widget_pool_t* widget_pool_create(uint32_t max_cache_nr) {
|
||||
widget_pool_t* pool = TKMEM_ZALLOC(widget_pool_t);
|
||||
return_value_if_fail(pool != NULL, NULL);
|
||||
|
||||
pool->max_cache_nr = max_cache_nr;
|
||||
pool->cache = object_default_create();
|
||||
|
||||
if (pool->cache == NULL) {
|
||||
TKMEM_FREE(pool);
|
||||
pool = NULL;
|
||||
}
|
||||
|
||||
return pool;
|
||||
}
|
||||
|
||||
static widget_t* widget_pool_get(widget_pool_t* pool, const char* type) {
|
||||
value_t v;
|
||||
if (object_get_prop(pool->cache, type, &v) == RET_OK) {
|
||||
darray_t* arr = (darray_t*)value_pointer(&v);
|
||||
|
||||
return (widget_t*)darray_pop(arr);
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
widget_t* widget_pool_create_widget(widget_pool_t* pool, const widget_vtable_t* vt) {
|
||||
widget_t* widget = NULL;
|
||||
return_value_if_fail(vt != NULL && vt->size >= sizeof(widget_t), NULL);
|
||||
|
||||
if (pool != NULL && vt->enable_pool) {
|
||||
widget = widget_pool_get(pool, vt->type);
|
||||
if (widget != NULL) {
|
||||
pool->cache_nr--;
|
||||
}
|
||||
}
|
||||
|
||||
if (widget == NULL) {
|
||||
widget = widget_pool_real_create_widget(vt);
|
||||
}
|
||||
|
||||
return widget;
|
||||
}
|
||||
|
||||
static ret_t widget_pool_put(widget_pool_t* pool, widget_t* widget) {
|
||||
if (pool->cache_nr < pool->max_cache_nr && widget->vt->enable_pool) {
|
||||
value_t v;
|
||||
darray_t* arr = NULL;
|
||||
const char* type = widget->vt->type;
|
||||
|
||||
if (object_get_prop(pool->cache, type, &v) == RET_OK) {
|
||||
arr = (darray_t*)value_pointer(&v);
|
||||
}
|
||||
|
||||
if (arr == NULL) {
|
||||
arr = darray_create(10, (tk_destroy_t)widget_pool_real_destroy_widget, NULL);
|
||||
return_value_if_fail(arr != NULL, RET_OOM);
|
||||
|
||||
value_set_pointer(&v, arr);
|
||||
if (object_set_prop(pool->cache, type, &v) != RET_OK) {
|
||||
darray_destroy(arr);
|
||||
arr = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
return darray_push(arr, widget);
|
||||
} else {
|
||||
return RET_FAIL;
|
||||
}
|
||||
}
|
||||
|
||||
ret_t widget_pool_destroy_widget(widget_pool_t* pool, widget_t* widget) {
|
||||
ret_t ret = RET_FAIL;
|
||||
return_value_if_fail(widget != NULL && widget->vt != NULL, RET_BAD_PARAMS);
|
||||
|
||||
if (pool != NULL) {
|
||||
ret = widget_pool_put(pool, widget);
|
||||
if (ret == RET_OK) {
|
||||
pool->cache_nr++;
|
||||
widget_pool_reset_widget(widget);
|
||||
}
|
||||
}
|
||||
|
||||
if (ret != RET_OK) {
|
||||
ret = widget_pool_real_destroy_widget(widget);
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static ret_t widget_pool_on_visit_remove_cache(void* ctx, named_value_t* nv) {
|
||||
darray_t* arr = (darray_t*)value_pointer(&(nv->value));
|
||||
|
||||
darray_destroy(arr);
|
||||
value_set_pointer(&(nv->value), NULL);
|
||||
|
||||
return RET_REMOVE;
|
||||
}
|
||||
|
||||
ret_t widget_pool_clear_cache(widget_pool_t* pool) {
|
||||
return_value_if_fail(pool != NULL, RET_BAD_PARAMS);
|
||||
|
||||
object_foreach_prop(pool->cache, (tk_visit_t)widget_pool_on_visit_remove_cache, NULL);
|
||||
pool->cache_nr = 0;
|
||||
|
||||
return RET_OK;
|
||||
}
|
||||
|
||||
static ret_t widget_pool_on_visit_count(void* ctx, named_value_t* nv) {
|
||||
int32_t* n = (int32_t*)ctx;
|
||||
|
||||
darray_t* arr = (darray_t*)value_pointer(&(nv->value));
|
||||
|
||||
*n += arr->size;
|
||||
|
||||
return RET_OK;
|
||||
}
|
||||
|
||||
int32_t widget_pool_count(widget_pool_t* pool) {
|
||||
int32_t n = 0;
|
||||
return_value_if_fail(pool != NULL, 0);
|
||||
|
||||
object_foreach_prop(pool->cache, (tk_visit_t)widget_pool_on_visit_count, &n);
|
||||
|
||||
return n;
|
||||
}
|
||||
|
||||
ret_t widget_pool_destroy(widget_pool_t* pool) {
|
||||
return_value_if_fail(pool != NULL && pool->cache != NULL, RET_BAD_PARAMS);
|
||||
|
||||
widget_pool_clear_cache(pool);
|
||||
object_unref(pool->cache);
|
||||
TKMEM_FREE(pool);
|
||||
|
||||
return RET_OK;
|
||||
}
|
127
src/base/widget_pool.h
Normal file
127
src/base/widget_pool.h
Normal file
@ -0,0 +1,127 @@
|
||||
/**
|
||||
* File: widget_pool.h
|
||||
* Author: AWTK Develop Team
|
||||
* Brief: widget pool
|
||||
*
|
||||
* Copyright (c) 2019 - 2019 Guangzhou ZHIYUAN Electronics Co.,Ltd.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* License file for more details.
|
||||
*
|
||||
*/
|
||||
|
||||
/**
|
||||
* History:
|
||||
* ================================================================
|
||||
* 2019-01-15 Li XianJing <xianjimli@hotmail.com> created
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef TK_WIDGET_POOL_H
|
||||
#define TK_WIDGET_POOL_H
|
||||
|
||||
#include "tkc/object_default.h"
|
||||
#include "base/types_def.h"
|
||||
|
||||
BEGIN_C_DECLS
|
||||
|
||||
/**
|
||||
* @class widget_pool_t
|
||||
*
|
||||
* 有时需要频繁创建和销毁控件,widget pool把销毁的控件缓存起来,再次使用时直接拿回来用。
|
||||
*
|
||||
* * 优点:速度快,内存碎片少。
|
||||
* * 缺点:占用一点内存空间。
|
||||
*
|
||||
*/
|
||||
typedef struct _widget_pool_t {
|
||||
object_t* cache;
|
||||
uint32_t cache_nr;
|
||||
uint32_t max_cache_nr;
|
||||
} widget_pool_t;
|
||||
|
||||
/**
|
||||
* @method widget_pool
|
||||
* 获取缺省widget pool对象。
|
||||
*
|
||||
* @annotation ["constructor"]
|
||||
* @return {widget_pool_t*} 返回widget pool对象。
|
||||
*/
|
||||
widget_pool_t* widget_pool(void);
|
||||
|
||||
/**
|
||||
* @method widget_pool_set
|
||||
* 设置缺省widget pool对象。
|
||||
*
|
||||
* @param {widget_pool_t*} pool widget pool对象。
|
||||
*
|
||||
* @return {ret_t} 返回RET_OK表示成功,否则表示失败。
|
||||
*/
|
||||
ret_t widget_pool_set(widget_pool_t* pool);
|
||||
|
||||
/**
|
||||
* @method widget_pool_create
|
||||
* 创建widget pool对象。
|
||||
*
|
||||
* @annotation ["constructor"]
|
||||
* @param {uint32_t} max_cache_nr 最大缓存对象个数。
|
||||
*
|
||||
* @return {widget_pool_t*} 返回widget pool对象。
|
||||
*/
|
||||
widget_pool_t* widget_pool_create(uint32_t max_cache_nr);
|
||||
|
||||
/**
|
||||
* @method widget_pool_create_widget
|
||||
* 创建widget对象。
|
||||
*
|
||||
* @param {widget_pool_t*} pool widget pool对象。
|
||||
* @param {const widget_vtable_t*} vt 控件虚表。
|
||||
*
|
||||
* @return {widget_t} 返回控件对象。
|
||||
*/
|
||||
widget_t* widget_pool_create_widget(widget_pool_t* pool, const widget_vtable_t* vt);
|
||||
|
||||
/**
|
||||
* @method widget_pool_destroy_widget
|
||||
* 销毁或回收widget对象。
|
||||
*
|
||||
* @param {widget_pool_t*} pool widget pool对象。
|
||||
* @param {widget_t*} widget 控件对象。
|
||||
*
|
||||
* @return {ret_t} 返回RET_OK表示成功,否则表示失败。
|
||||
*/
|
||||
ret_t widget_pool_destroy_widget(widget_pool_t* pool, widget_t* widget);
|
||||
|
||||
/**
|
||||
* @method widget_pool_clear_cache
|
||||
* 清除全部缓存控件。
|
||||
* @param {widget_pool_t*} pool widget pool对象。
|
||||
*
|
||||
* @return {ret_t} 返回RET_OK表示成功,否则表示失败。
|
||||
*/
|
||||
ret_t widget_pool_clear_cache(widget_pool_t* pool);
|
||||
|
||||
/**
|
||||
* @method widget_pool_count
|
||||
* 计算缓存控件个数。
|
||||
* @param {widget_pool_t*} pool widget pool对象。
|
||||
*
|
||||
* @return {int32_t} 返回缓存控件个数。
|
||||
*/
|
||||
int32_t widget_pool_count(widget_pool_t* pool);
|
||||
|
||||
/**
|
||||
* @method widget_pool_destroy
|
||||
* 清除全部缓存控件并销毁widget pool对象。
|
||||
|
||||
* @param {widget_pool_t*} pool widget pool对象。
|
||||
*
|
||||
* @return {ret_t} 返回RET_OK表示成功,否则表示失败。
|
||||
*/
|
||||
ret_t widget_pool_destroy(widget_pool_t* pool);
|
||||
|
||||
END_C_DECLS
|
||||
|
||||
#endif /*TK_WIDGET_POOL_H*/
|
@ -172,33 +172,11 @@ static ret_t button_on_destroy(widget_t* widget) {
|
||||
return button_remove_timer(widget);
|
||||
}
|
||||
|
||||
#ifdef WITH_WIDGET_POOL
|
||||
static array_t s_button_pool;
|
||||
static ret_t button_recycle(widget_t* widget) {
|
||||
button_t* button = BUTTON(widget);
|
||||
|
||||
button->repeat = 0;
|
||||
button_remove_timer(widget);
|
||||
|
||||
return array_push(&s_button_pool, widget);
|
||||
}
|
||||
|
||||
static button_t* button_alloc(void) {
|
||||
if (s_button_pool.size > 0) {
|
||||
return (button_t*)array_pop(&s_button_pool);
|
||||
} else {
|
||||
return TKMEM_ZALLOC(button_t);
|
||||
}
|
||||
}
|
||||
#else
|
||||
#define button_recycle NULL
|
||||
#define button_alloc() TKMEM_ZALLOC(button_t)
|
||||
#endif /*WITH_WIDGET_POOL*/
|
||||
|
||||
static const char* s_button_properties[] = {WIDGET_PROP_REPEAT, NULL};
|
||||
static const widget_vtable_t s_button_vtable = {
|
||||
.size = sizeof(button_t),
|
||||
.type = WIDGET_TYPE_BUTTON,
|
||||
.enable_pool = TRUE,
|
||||
.create = button_create,
|
||||
.clone_properties = s_button_properties,
|
||||
.persistent_properties = s_button_properties,
|
||||
@ -207,15 +185,16 @@ static const widget_vtable_t s_button_vtable = {
|
||||
.get_prop = button_get_prop,
|
||||
.get_prop_default_value = button_get_prop_default_value,
|
||||
.on_destroy = button_on_destroy,
|
||||
.recycle = button_recycle,
|
||||
.on_paint_self = widget_on_paint_self_default};
|
||||
|
||||
widget_t* button_create(widget_t* parent, xy_t x, xy_t y, wh_t w, wh_t h) {
|
||||
button_t* button = button_alloc();
|
||||
widget_t* widget = WIDGET(button);
|
||||
widget_t* widget = widget_create(parent, &s_button_vtable, x, y, w, h);
|
||||
button_t* button = BUTTON(widget);
|
||||
return_value_if_fail(button != NULL, NULL);
|
||||
|
||||
widget_init(widget, parent, &s_button_vtable, x, y, w, h);
|
||||
button->repeat = 0;
|
||||
button->repeat_nr = 0;
|
||||
button->pressed = FALSE;
|
||||
button->timer_id = TK_INVALID_ID;
|
||||
|
||||
return widget;
|
||||
|
@ -91,24 +91,6 @@ static ret_t image_set_prop(widget_t* widget, const char* name, const value_t* v
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef WITH_WIDGET_POOL
|
||||
static array_t s_image_pool;
|
||||
static ret_t image_recycle(widget_t* widget) {
|
||||
return array_push(&s_image_pool, widget);
|
||||
}
|
||||
|
||||
static image_t* image_alloc(void) {
|
||||
if (s_image_pool.size > 0) {
|
||||
return (image_t*)array_pop(&s_image_pool);
|
||||
} else {
|
||||
return TKMEM_ZALLOC(image_t);
|
||||
}
|
||||
}
|
||||
#else
|
||||
#define image_recycle NULL
|
||||
#define image_alloc() TKMEM_ZALLOC(image_t)
|
||||
#endif /*WITH_WIDGET_POOL*/
|
||||
|
||||
static const char* s_image_clone_properties[] = {WIDGET_PROP_IMAGE, WIDGET_PROP_DRAW_TYPE,
|
||||
WIDGET_PROP_SCALE_X, WIDGET_PROP_SCALE_Y,
|
||||
WIDGET_PROP_ANCHOR_X, WIDGET_PROP_ANCHOR_Y,
|
||||
@ -117,21 +99,20 @@ static const char* s_image_clone_properties[] = {WIDGET_PROP_IMAGE, WIDGET_
|
||||
|
||||
static const widget_vtable_t s_image_vtable = {.size = sizeof(image_t),
|
||||
.type = WIDGET_TYPE_IMAGE,
|
||||
.enable_pool = TRUE,
|
||||
.clone_properties = s_image_clone_properties,
|
||||
.create = image_create,
|
||||
.on_destroy = image_base_on_destroy,
|
||||
.recycle = image_recycle,
|
||||
.on_event = image_base_on_event,
|
||||
.on_paint_self = image_on_paint_self,
|
||||
.set_prop = image_set_prop,
|
||||
.get_prop = image_get_prop};
|
||||
|
||||
widget_t* image_create(widget_t* parent, xy_t x, xy_t y, wh_t w, wh_t h) {
|
||||
image_t* image = image_alloc();
|
||||
widget_t* widget = WIDGET(image);
|
||||
widget_t* widget = widget_create(parent, &s_image_vtable, x, y, w, h);
|
||||
image_t* image = IMAGE(widget);
|
||||
return_value_if_fail(image != NULL, NULL);
|
||||
|
||||
widget_init(widget, parent, &s_image_vtable, x, y, w, h);
|
||||
image_base_init(widget);
|
||||
image->draw_type = IMAGE_DRAW_DEFAULT;
|
||||
|
||||
|
@ -193,38 +193,19 @@ static ret_t label_set_prop(widget_t* widget, const char* name, const value_t* v
|
||||
return RET_NOT_FOUND;
|
||||
}
|
||||
|
||||
#ifdef WITH_WIDGET_POOL
|
||||
static array_t s_label_pool;
|
||||
static ret_t label_recycle(widget_t* widget) {
|
||||
return array_push(&s_label_pool, widget);
|
||||
}
|
||||
|
||||
static label_t* label_alloc(void) {
|
||||
if (s_label_pool.size > 0) {
|
||||
return (label_t*)array_pop(&s_label_pool);
|
||||
} else {
|
||||
return TKMEM_ZALLOC(label_t);
|
||||
}
|
||||
}
|
||||
#else
|
||||
#define label_recycle NULL
|
||||
#define label_alloc() TKMEM_ZALLOC(label_t)
|
||||
#endif /*WITH_WIDGET_POOL*/
|
||||
|
||||
static const widget_vtable_t s_label_vtable = {.size = sizeof(label_t),
|
||||
.type = WIDGET_TYPE_LABEL,
|
||||
.enable_pool = TRUE,
|
||||
.create = label_create,
|
||||
.set_prop = label_set_prop,
|
||||
.get_prop = label_get_prop,
|
||||
.recycle = label_recycle,
|
||||
.on_paint_self = label_on_paint_self};
|
||||
|
||||
widget_t* label_create(widget_t* parent, xy_t x, xy_t y, wh_t w, wh_t h) {
|
||||
label_t* label = label_alloc();
|
||||
widget_t* widget = WIDGET(label);
|
||||
widget_t* widget = widget_create(parent, &s_label_vtable, x, y, w, h);
|
||||
label_t* label = LABEL(widget);
|
||||
return_value_if_fail(label != NULL, NULL);
|
||||
|
||||
widget_init(widget, parent, &s_label_vtable, x, y, w, h);
|
||||
label->length = -1;
|
||||
|
||||
return widget;
|
||||
|
124
tests/widget_pool_test.cc
Normal file
124
tests/widget_pool_test.cc
Normal file
@ -0,0 +1,124 @@
|
||||
#include "gtest/gtest.h"
|
||||
#include "base/widget_pool.h"
|
||||
#include "widgets/label.h"
|
||||
|
||||
static const widget_vtable_t s_enable_vtable = {
|
||||
.size = sizeof(widget_t), .type = "enable", .enable_pool = TRUE};
|
||||
|
||||
static const widget_vtable_t s_disable_vtable = {.size = sizeof(widget_t), .type = "disable"};
|
||||
|
||||
TEST(WidgetPool, basic) {
|
||||
const widget_vtable_t* vt = &s_enable_vtable;
|
||||
const widget_vtable_t* d_vt = &s_disable_vtable;
|
||||
|
||||
widget_pool_t* pool = widget_pool_create(5);
|
||||
widget_t* e = widget_pool_create_widget(pool, vt);
|
||||
|
||||
ASSERT_EQ(widget_pool_destroy_widget(pool, e), RET_OK);
|
||||
ASSERT_EQ(pool->cache_nr, 1);
|
||||
|
||||
e = widget_pool_create_widget(pool, vt);
|
||||
ASSERT_EQ(pool->cache_nr, 0);
|
||||
|
||||
ASSERT_EQ(widget_pool_destroy_widget(pool, e), RET_OK);
|
||||
ASSERT_EQ(pool->cache_nr, 1);
|
||||
|
||||
e = widget_pool_create_widget(pool, d_vt);
|
||||
ASSERT_EQ(pool->cache_nr, 1);
|
||||
|
||||
ASSERT_EQ(widget_pool_destroy_widget(pool, e), RET_OK);
|
||||
ASSERT_EQ(pool->cache_nr, 1);
|
||||
ASSERT_EQ(pool->cache_nr, widget_pool_count(pool));
|
||||
|
||||
ASSERT_EQ(widget_pool_clear_cache(pool), RET_OK);
|
||||
ASSERT_EQ(pool->cache_nr, 0);
|
||||
ASSERT_EQ(pool->cache_nr, widget_pool_count(pool));
|
||||
|
||||
widget_pool_destroy(pool);
|
||||
}
|
||||
|
||||
TEST(WidgetPool, enable) {
|
||||
const widget_vtable_t* vt = &s_enable_vtable;
|
||||
widget_pool_t* pool = widget_pool_create(5);
|
||||
widget_t* e = widget_pool_create_widget(pool, vt);
|
||||
|
||||
ASSERT_EQ(widget_pool_destroy_widget(pool, e), RET_OK);
|
||||
ASSERT_EQ(pool->cache_nr, 1);
|
||||
|
||||
e = widget_pool_create_widget(pool, vt);
|
||||
ASSERT_EQ(pool->cache_nr, 0);
|
||||
|
||||
ASSERT_EQ(widget_pool_destroy_widget(pool, e), RET_OK);
|
||||
ASSERT_EQ(pool->cache_nr, 1);
|
||||
|
||||
widget_pool_destroy(pool);
|
||||
}
|
||||
|
||||
TEST(WidgetPool, disable) {
|
||||
const widget_vtable_t* vt = &s_disable_vtable;
|
||||
widget_pool_t* pool = widget_pool_create(5);
|
||||
widget_t* e = widget_pool_create_widget(pool, vt);
|
||||
|
||||
ASSERT_EQ(widget_pool_destroy_widget(pool, e), RET_OK);
|
||||
ASSERT_EQ(pool->cache_nr, 0);
|
||||
|
||||
widget_pool_destroy(pool);
|
||||
}
|
||||
|
||||
TEST(WidgetPool, disable_nr) {
|
||||
const widget_vtable_t* vt = &s_disable_vtable;
|
||||
widget_pool_t* pool = widget_pool_create(5);
|
||||
widget_t* widgets[100];
|
||||
|
||||
for (int32_t i = 0; i < ARRAY_SIZE(widgets); i++) {
|
||||
widgets[i] = widget_pool_create_widget(pool, vt);
|
||||
ASSERT_EQ(pool->cache_nr, 0);
|
||||
}
|
||||
|
||||
for (int32_t i = 0; i < ARRAY_SIZE(widgets); i++) {
|
||||
ASSERT_EQ(widget_pool_destroy_widget(pool, widgets[i]), RET_OK);
|
||||
ASSERT_EQ(pool->cache_nr, 0);
|
||||
}
|
||||
|
||||
widget_pool_destroy(pool);
|
||||
}
|
||||
|
||||
TEST(WidgetPool, enable_nr) {
|
||||
const widget_vtable_t* vt = &s_enable_vtable;
|
||||
widget_t* widgets[100];
|
||||
widget_pool_t* pool = widget_pool_create(ARRAY_SIZE(widgets));
|
||||
|
||||
for (int32_t i = 0; i < ARRAY_SIZE(widgets); i++) {
|
||||
widgets[i] = widget_pool_create_widget(pool, vt);
|
||||
ASSERT_EQ(pool->cache_nr, 0);
|
||||
}
|
||||
|
||||
for (int32_t i = 0; i < ARRAY_SIZE(widgets); i++) {
|
||||
ASSERT_EQ(widget_pool_destroy_widget(pool, widgets[i]), RET_OK);
|
||||
ASSERT_EQ(pool->cache_nr, i + 1);
|
||||
}
|
||||
|
||||
widget_pool_destroy(pool);
|
||||
}
|
||||
|
||||
TEST(WidgetPool, enable_nr_limit) {
|
||||
const widget_vtable_t* vt = &s_enable_vtable;
|
||||
widget_t* widgets[100];
|
||||
widget_pool_t* pool = widget_pool_create(10);
|
||||
|
||||
for (int32_t i = 0; i < ARRAY_SIZE(widgets); i++) {
|
||||
widgets[i] = widget_pool_create_widget(pool, vt);
|
||||
ASSERT_EQ(pool->cache_nr, 0);
|
||||
}
|
||||
|
||||
for (int32_t i = 0; i < ARRAY_SIZE(widgets); i++) {
|
||||
ASSERT_EQ(widget_pool_destroy_widget(pool, widgets[i]), RET_OK);
|
||||
if (i < pool->max_cache_nr) {
|
||||
ASSERT_EQ(pool->cache_nr, i + 1);
|
||||
} else {
|
||||
ASSERT_EQ(pool->cache_nr, pool->max_cache_nr);
|
||||
}
|
||||
}
|
||||
|
||||
widget_pool_destroy(pool);
|
||||
}
|
Loading…
Reference in New Issue
Block a user