fix(objid): free old id before assign new one (#6697)

Signed-off-by: Neo Xu <neo.xu1990@gmail.com>
This commit is contained in:
Neo Xu
2024-08-21 16:20:37 +08:00
committed by GitHub
parent 78d29d2853
commit afcf722e6f
7 changed files with 94 additions and 31 deletions
+1
View File
@@ -33,6 +33,7 @@ Below APIs needed to be implemented and linked to lvgl.
.. code:: c
void lv_obj_set_id(lv_obj_t * obj, void * id);
void lv_obj_assign_id(const lv_obj_class_t * class_p, lv_obj_t * obj);
void lv_obj_free_id(lv_obj_t * obj);
const char * lv_obj_stringify_id(lv_obj_t * obj, char * buf, uint32_t len);
+1 -7
View File
@@ -433,19 +433,13 @@ void lv_obj_null_on_delete(lv_obj_t ** obj_ptr)
}
#if LV_USE_OBJ_ID
void lv_obj_set_id(lv_obj_t * obj, void * id)
{
LV_ASSERT_NULL(obj);
obj->id = id;
}
void * lv_obj_get_id(const lv_obj_t * obj)
{
LV_ASSERT_NULL(obj);
return obj->id;
}
lv_obj_t * lv_obj_get_child_by_id(const lv_obj_t * obj, void * id)
lv_obj_t * lv_obj_get_child_by_id(const lv_obj_t * obj, const void * id)
{
if(obj == NULL) obj = lv_display_get_screen_active(NULL);
if(obj == NULL) return NULL;
+5 -5
View File
@@ -407,14 +407,14 @@ void * lv_obj_get_id(const lv_obj_t * obj);
* @param id the id of the child object
* @return pointer to the child object or NULL if not found
*/
lv_obj_t * lv_obj_get_child_by_id(const lv_obj_t * obj, void * id);
lv_obj_t * lv_obj_get_child_by_id(const lv_obj_t * obj, const void * id);
/**
* Assign id to object if not previously assigned.
* This function gets called automatically when LV_OBJ_ID_AUTO_ASSIGN is enabled.
*
* Set `LV_USE_OBJ_ID_BUILTIN` to use the builtin method to generate object ID.
* Otherwise, these functions including `lv_obj_[assign|free|stringify]_id` and
* Otherwise, these functions including `lv_obj_[set|assign|free|stringify]_id` and
* `lv_obj_id_compare`should be implemented externally.
*
* @param class_p the class this obj belongs to. Note obj->class_p is the class currently being constructed.
@@ -423,8 +423,8 @@ lv_obj_t * lv_obj_get_child_by_id(const lv_obj_t * obj, void * id);
void lv_obj_assign_id(const lv_obj_class_t * class_p, lv_obj_t * obj);
/**
* Free resources allocated by `lv_obj_assign_id`.
* This function gets called automatically when object is deleted.
* Free resources allocated by `lv_obj_assign_id` or `lv_obj_set_id`.
* This function is also called automatically when object is deleted.
* @param obj pointer to an object
*/
void lv_obj_free_id(lv_obj_t * obj);
@@ -439,7 +439,7 @@ void lv_obj_free_id(lv_obj_t * obj);
* @param id2: the second id
* @return 0 if they are equal, non-zero otherwise.
*/
int lv_obj_id_compare(void * id1, void * id2);
int lv_obj_id_compare(const void * id1, const void * id2);
/**
* Format an object's id into a string.
+9 -1
View File
@@ -79,9 +79,17 @@ void lv_obj_assign_id(const lv_obj_class_t * class_p, lv_obj_t * obj)
obj->id = (void *)(lv_uintptr_t)id;
}
void lv_obj_set_id(lv_obj_t * obj, void * id)
{
LV_ASSERT_NULL(obj);
if(obj->id) lv_obj_free_id(obj);
obj->id = id;
}
void lv_obj_free_id(lv_obj_t * obj)
{
LV_UNUSED(obj);
obj->id = NULL;
}
const char * lv_obj_stringify_id(lv_obj_t * obj, char * buf, uint32_t len)
@@ -106,7 +114,7 @@ void lv_objid_builtin_destroy(void)
global->objid_count = 0;
}
int lv_obj_id_compare(void * id1, void * id2)
int lv_obj_id_compare(const void * id1, const void * id2)
{
return id1 == id2 ? 0 : 1;
}
+43 -15
View File
@@ -133,28 +133,56 @@ lv_property_t lv_obj_get_style_property(lv_obj_t * obj, lv_prop_id_t id, uint32_
return value;
}
lv_prop_id_t lv_obj_property_get_id(const lv_obj_t * obj, const char * name)
lv_prop_id_t lv_style_property_get_id(const char * name)
{
#if LV_USE_OBJ_PROPERTY_NAME
const lv_obj_class_t * clz;
const lv_property_name_t * names;
lv_property_name_t * found;
for(clz = obj->class_p; clz; clz = clz->base_class) {
names = clz->property_names;
if(names == NULL) {
/* try base class*/
continue;
}
found = lv_utils_bsearch(name, names, clz->names_count, sizeof(lv_property_name_t), property_name_compare);
if(found) return found->id;
}
/*Check style property*/
found = lv_utils_bsearch(name, lv_style_property_names, sizeof(lv_style_property_names) / sizeof(lv_property_name_t),
sizeof(lv_property_name_t), property_name_compare);
if(found) return found->id;
#else
LV_UNUSED(name);
#endif
return LV_PROPERTY_ID_INVALID;
}
lv_prop_id_t lv_obj_class_property_get_id(const lv_obj_class_t * clz, const char * name)
{
#if LV_USE_OBJ_PROPERTY_NAME
const lv_property_name_t * names;
lv_property_name_t * found;
names = clz->property_names;
if(names == NULL) {
/* try base class*/
return LV_PROPERTY_ID_INVALID;
}
found = lv_utils_bsearch(name, names, clz->names_count, sizeof(lv_property_name_t), property_name_compare);
if(found) return found->id;
#else
LV_UNUSED(obj);
LV_UNUSED(name);
LV_UNUSED(property_name_compare);
#endif
return LV_PROPERTY_ID_INVALID;
}
lv_prop_id_t lv_obj_property_get_id(const lv_obj_t * obj, const char * name)
{
#if LV_USE_OBJ_PROPERTY_NAME
const lv_obj_class_t * clz;
lv_prop_id_t id;
for(clz = obj->class_p; clz; clz = clz->base_class) {
id = lv_obj_class_property_get_id(clz, name);
if(id != LV_PROPERTY_ID_INVALID) return id;
}
/*Check style property*/
id = lv_style_property_get_id(name);
if(id != LV_PROPERTY_ID_INVALID) return id;
#else
LV_UNUSED(obj);
LV_UNUSED(name);
+18 -3
View File
@@ -98,14 +98,14 @@ typedef struct {
* E.g.
*
* static const lv_property_t obj_pos_x = {
* .id = LV_STYLE_X,
* .id = LV_PROPERTY_STYLE_X,
* .num = 123,
* .selector = LV_STATE_PRESSED,
* }
*
* instead of:
* static const lv_property_t obj_pos_x = {
* .id = LV_STYLE_X,
* .id = LV_PROPERTY_STYLE_X,
* .style.num = 123, // note this line.
* .selector = LV_STATE_PRESSED,
* }
@@ -171,13 +171,28 @@ lv_property_t lv_obj_get_property(lv_obj_t * obj, lv_prop_id_t id);
lv_property_t lv_obj_get_style_property(lv_obj_t * obj, lv_prop_id_t id, uint32_t selector);
/**
* Get the property ID by name. Requires to enable `LV_USE_OBJ_PROPERTY_NAME`.
* Get the property ID by name recursively to base classes. Requires to enable `LV_USE_OBJ_PROPERTY_NAME`.
* @param obj pointer to an object that has specified property or base class has.
* @param name property name
* @return property ID found or `LV_PROPERTY_ID_INVALID` if not found.
*/
lv_prop_id_t lv_obj_property_get_id(const lv_obj_t * obj, const char * name);
/**
* Get the property ID by name without check base class recursively. Requires to enable `LV_USE_OBJ_PROPERTY_NAME`.
* @param clz pointer to an object class that has specified property or base class has.
* @param name property name
* @return property ID found or `LV_PROPERTY_ID_INVALID` if not found.
*/
lv_prop_id_t lv_obj_class_property_get_id(const lv_obj_class_t * clz, const char * name);
/**
* Get the style property ID by name. Requires to enable `LV_USE_OBJ_PROPERTY_NAME`.
* @param name property name
* @return property ID found or `LV_PROPERTY_ID_INVALID` if not found.
*/
lv_prop_id_t lv_style_property_get_id(const char * name);
/**********************
* MACROS
**********************/
@@ -272,6 +272,23 @@ void test_obj_property_name(void)
#endif
}
void test_obj_class_property(void)
{
#if LV_USE_OBJ_PROPERTY && LV_USE_OBJ_PROPERTY_NAME
/* An image obj has align property */
lv_obj_t * img = lv_image_create(lv_screen_active());
TEST_ASSERT_EQUAL_UINT32(LV_PROPERTY_OBJ_ALIGN, lv_obj_property_get_id(img, "align"));
/* obj class has align property but image doesn't. */
TEST_ASSERT_EQUAL_UINT32(LV_PROPERTY_OBJ_ALIGN, lv_obj_class_property_get_id(&lv_obj_class, "align"));
TEST_ASSERT_EQUAL_UINT32(LV_PROPERTY_ID_INVALID, lv_obj_class_property_get_id(&lv_image_class, "align"));
/* style can also have property name that conflicts with obj */
TEST_ASSERT_EQUAL_UINT32(LV_PROPERTY_STYLE_X, lv_style_property_get_id("x"));
TEST_ASSERT_EQUAL_UINT32(LV_PROPERTY_OBJ_X, lv_obj_property_get_id(img, "x"));
#endif
}
void test_label_properties(void)
{
#if LV_USE_OBJ_PROPERTY