feat(observer): add lv_obj_remove_from_subject (#6341)

This commit is contained in:
Gabor Kiss-Vamosi
2024-07-07 06:30:55 +02:00
committed by GitHub
parent 08c5308e08
commit f8c26ea150
4 changed files with 26 additions and 40 deletions

View File

@@ -171,13 +171,14 @@ Unsubscribe from a subject
.. code:: c
lv_observer_remove(observer)
//`observer` is the return value of `lv_subject_add_observer*`
lv_observer_remove(observer);
To unsubscribe from a subject with all widgets you can use:
To unsubscribe a widget from a given or all subject use:
.. code:: c
lv_subject_remove_obj(subject, obj)
lv_obj_remove_from_subject(obj, subject); //`subject` can be NULL to unsubcribe from all
.. _observer_subject_groups:

View File

@@ -356,6 +356,7 @@ lv_observer_t * lv_subject_add_observer_with_target(lv_subject_t * subject, lv_o
return observer;
}
void lv_observer_remove(lv_observer_t * observer)
{
LV_ASSERT_NULL(observer);
@@ -370,36 +371,19 @@ void lv_observer_remove(lv_observer_t * observer)
lv_free(observer);
}
void lv_subject_remove_all_obj(lv_subject_t * subject, lv_obj_t * obj)
void lv_obj_remove_from_subject(lv_obj_t * obj, lv_subject_t * subject)
{
LV_ASSERT_NULL(subject);
if(subject->type == LV_SUBJECT_TYPE_INVALID) {
LV_LOG_WARN("Subject not initialized yet");
return;
}
while(lv_obj_remove_event_cb(obj, unsubscribe_on_delete_cb));
while(lv_obj_remove_event_cb(obj, obj_value_changed_event_cb));
#if LV_USE_ARC
while(lv_obj_remove_event_cb(obj, arc_value_changed_event_cb));
#endif /*LV_USE_ARC*/
#if LV_USE_ROLLER
while(lv_obj_remove_event_cb(obj, roller_value_changed_event_cb));
#endif /*LV_USE_ROLLER*/
#if LV_USE_DROPDOWN
while(lv_obj_remove_event_cb(obj, dropdown_value_changed_event_cb));
#endif /*LV_USE_DROPDOWN*/
lv_observer_t * observer = _lv_ll_get_head(&subject->subs_ll);
while(observer) {
lv_observer_t * observer_next = _lv_ll_get_next(&subject->subs_ll, observer);
if(observer->target == obj) {
lv_observer_remove(observer);
int32_t i;
int32_t event_cnt = (int32_t)(obj->spec_attr ? lv_array_size(&obj->spec_attr->event_list) : 0);
for(i = event_cnt - 1; i >= 0; i--) {
lv_event_dsc_t * event_dsc = lv_obj_get_event_dsc(obj, i);
if(event_dsc->cb == unsubscribe_on_delete_cb) {
lv_observer_t * observer = event_dsc->user_data;
if(subject == NULL || subject == observer->subject) {
lv_observer_remove(observer);
lv_obj_remove_event(obj, i);
}
}
observer = observer_next;
}
}

View File

@@ -265,11 +265,12 @@ lv_observer_t * lv_subject_add_observer_with_target(lv_subject_t * subject, lv_o
void lv_observer_remove(lv_observer_t * observer);
/**
* Remove all observers from their subject related to an object
* @param observer pointer to an observer
* @param obj pointer to an object
* Remove the observers of an object from a subject or all subjects
* @param obj the object whose observers should be removed
* @param subject the subject to remove the object from, or `NULL` to remove from all subjects
* @note This function can be used e.g. when an object's subject(s) needs to be replaced by other subject(s)
*/
void lv_subject_remove_all_obj(lv_subject_t * subject, lv_obj_t * obj);
void lv_obj_remove_from_subject(lv_obj_t * obj, lv_subject_t * subject);
/**
* Get the target of an observer

View File

@@ -332,7 +332,7 @@ void test_observer_label_text_normal(void)
TEST_ASSERT_EQUAL_STRING("world", lv_label_get_text(obj));
/*Remove the label from the subject*/
lv_subject_remove_all_obj(&subject_string, obj);
lv_obj_remove_from_subject(obj, &subject_string);
lv_subject_copy_string(&subject_string, "nothing");
TEST_ASSERT_EQUAL_STRING("world", lv_label_get_text(obj));
@@ -346,7 +346,7 @@ void test_observer_label_text_normal(void)
TEST_ASSERT_EQUAL_STRING("WORLD", lv_label_get_text(obj));
/*Remove the label from the subject*/
lv_subject_remove_all_obj(&subject_pointer, obj);
lv_obj_remove_from_subject(obj, &subject_pointer);
lv_subject_copy_string(&subject_pointer, "NOTHING");
TEST_ASSERT_EQUAL_STRING("WORLD", lv_label_get_text(obj));
}
@@ -373,7 +373,7 @@ void test_observer_label_text_formatted(void)
TEST_ASSERT_EQUAL_STRING("value: -20", lv_label_get_text(obj));
/*Remove the label from the subject*/
lv_subject_remove_all_obj(&subject_int, obj);
lv_obj_remove_from_subject(obj, &subject_int);
lv_subject_set_int(&subject_int, 100);
TEST_ASSERT_EQUAL_STRING("value: -20", lv_label_get_text(obj));
@@ -388,7 +388,7 @@ void test_observer_label_text_formatted(void)
TEST_ASSERT_EQUAL_STRING("text: world", lv_label_get_text(obj));
/*Remove the label from the subject*/
lv_subject_remove_all_obj(&subject_string, obj);
lv_obj_remove_from_subject(obj, &subject_string);
lv_subject_copy_string(&subject_string, "nothing");
TEST_ASSERT_EQUAL_STRING("text: world", lv_label_get_text(obj));
@@ -402,7 +402,7 @@ void test_observer_label_text_formatted(void)
TEST_ASSERT_EQUAL_STRING("pointer: WORLD", lv_label_get_text(obj));
/*Remove the label from the subject*/
lv_subject_remove_all_obj(&subject_pointer, obj);
lv_obj_remove_from_subject(obj, &subject_pointer);
lv_subject_copy_string(&subject_pointer, "NOTHING");
TEST_ASSERT_EQUAL_STRING("pointer: WORLD", lv_label_get_text(obj));
}