diff --git a/docs/changes.md b/docs/changes.md index d4f5aa818..b1d935c28 100644 --- a/docs/changes.md +++ b/docs/changes.md @@ -3,6 +3,7 @@ 2024/11/18 * 完善 atomic(感谢兆坤提供补丁) * 修复拼写错误(感谢兆坤提供补丁) + * fix memory error whene change theme. 2024/11/17 * 完善 TK_STRINGIZE(感谢兆坤提供补丁) diff --git a/src/awtk_global.c b/src/awtk_global.c index 0ad29fbcb..2b1946710 100644 --- a/src/awtk_global.c +++ b/src/awtk_global.c @@ -145,7 +145,7 @@ ret_t tk_init_assets(void) { theme_t* t = theme(); const char* iter_name = asset_info_get_name(iter); if ((t == NULL || t->data == NULL) && tk_str_eq(iter_name, TK_DEFAULT_STYLE)) { - theme_set(theme_load_from_data(iter_name, iter->data, iter->size)); + theme_set(theme_load_from_asset((asset_info_t*)iter)); } break; } diff --git a/src/base/theme.c b/src/base/theme.c index d6150d1f5..9b2575939 100644 --- a/src/base/theme.c +++ b/src/base/theme.c @@ -79,6 +79,11 @@ ret_t theme_destroy(theme_t* theme) { TKMEM_FREE(theme->data); } + if (theme->info != NULL) { + asset_info_unref(theme->info); + theme->info = NULL; + } + if (theme->theme_destroy != NULL) { theme->theme_destroy(theme); } else { @@ -129,6 +134,21 @@ theme_t* theme_load_from_data(const char* name, const uint8_t* data, uint32_t si } } +theme_t* theme_load_from_asset(asset_info_t* info) { + theme_t* theme = NULL; + const char* name = NULL; + return_value_if_fail(info != NULL, NULL); + + name = asset_info_get_name(info); + theme = theme_load_from_data(name, info->data, info->size); + return_value_if_fail(theme != NULL, NULL); + + theme->info = info; + asset_info_ref(info); + + return theme; +} + #ifndef WITHOUT_XML_STYLE #include "theme_xml.inc" #endif /*WITHOUT_XML_STYLE*/ diff --git a/src/base/theme.h b/src/base/theme.h index 2d267360d..390e0c173 100644 --- a/src/base/theme.h +++ b/src/base/theme.h @@ -22,6 +22,7 @@ #ifndef TK_THEME_H #define TK_THEME_H +#include "tkc/asset_info.h" #include "base/theme_data.h" BEGIN_C_DECLS @@ -48,6 +49,7 @@ typedef ret_t (*theme_destroy_t)(theme_t* theme); struct _theme_t { const uint8_t* data; bool_t need_free_data; + asset_info_t* info; theme_foreach_t foreach; theme_find_style_t find_style; @@ -138,6 +140,16 @@ ret_t theme_destroy(theme_t* theme); */ theme_t* theme_load_from_data(const char* name, const uint8_t* data, uint32_t size); +/** + * @method theme_load_from_asset + * 加载窗体样式对象。 + * @annotation ["constructor"] + * @param {asset_info_t*} info 资源对象。 + * + * @return {theme_t*} 返回窗体样式对象。 + */ +theme_t* theme_load_from_asset(asset_info_t* info); + #define TK_DEFAULT_STYLE "default" #define THEME_DEFAULT_STYLE_TYPE "style_const" diff --git a/src/base/widget.c b/src/base/widget.c index dec4bde10..1a542899d 100644 --- a/src/base/widget.c +++ b/src/base/widget.c @@ -672,7 +672,7 @@ ret_t widget_set_theme(widget_t* widget, const char* name) { info = assets_manager_ref(am, ASSET_TYPE_STYLE, "default"); if (info != NULL) { - theme_set(theme_load_from_data(asset_info_get_name(info), info->data, info->size)); + theme_set(theme_load_from_asset((asset_info_t*)info)); assets_manager_unref(assets_manager(), info); } diff --git a/src/base/window_base.c b/src/base/window_base.c index dfdf49d7c..4cbb870ea 100644 --- a/src/base/window_base.c +++ b/src/base/window_base.c @@ -118,8 +118,7 @@ static ret_t window_base_load_default_theme_obj_impl(widget_t* widget, bool_t* u if (window_base->default_res_theme != NULL) { asset_info_t* res = (asset_info_t*)window_base->default_res_theme; - window_base->default_theme_obj = - theme_load_from_data(asset_info_get_name(res), res->data, res->size); + window_base->default_theme_obj = theme_load_from_asset(res); } if (window_base->default_theme_obj != NULL) { @@ -152,7 +151,7 @@ static ret_t window_base_load_theme_obj_impl(widget_t* widget, bool_t* update_st if (window_base->res_theme != NULL) { asset_info_t* res = (asset_info_t*)window_base->res_theme; - window_base->theme_obj = theme_load_from_data(asset_info_get_name(res), res->data, res->size); + window_base->theme_obj = theme_load_from_asset(res); } if (window_base->theme_obj != NULL) {