mirror of
https://github.com/lvgl/lvgl.git
synced 2025-01-28 07:03:00 +08:00
fix(msg): able to create/delete msgs during notify (#3847)
Co-authored-by: wrgallo <28547933+wrgallo@users.noreply.github.com>
This commit is contained in:
parent
889634398a
commit
5cdf242a21
5
Kconfig
5
Kconfig
@ -338,6 +338,11 @@ menu "LVGL configuration"
|
|||||||
bool "Enable/Disable LV_LOG_TRACE in anim module"
|
bool "Enable/Disable LV_LOG_TRACE in anim module"
|
||||||
default y
|
default y
|
||||||
depends on LV_USE_LOG
|
depends on LV_USE_LOG
|
||||||
|
|
||||||
|
config LV_LOG_TRACE_MSG
|
||||||
|
bool "Enable/Disable LV_LOG_TRACE in msg module"
|
||||||
|
default y
|
||||||
|
depends on LV_USE_LOG
|
||||||
endmenu
|
endmenu
|
||||||
|
|
||||||
menu "Asserts"
|
menu "Asserts"
|
||||||
|
@ -242,6 +242,7 @@
|
|||||||
#define LV_LOG_TRACE_OBJ_CREATE 1
|
#define LV_LOG_TRACE_OBJ_CREATE 1
|
||||||
#define LV_LOG_TRACE_LAYOUT 1
|
#define LV_LOG_TRACE_LAYOUT 1
|
||||||
#define LV_LOG_TRACE_ANIM 1
|
#define LV_LOG_TRACE_ANIM 1
|
||||||
|
#define LV_LOG_TRACE_MSG 1
|
||||||
|
|
||||||
#endif /*LV_USE_LOG*/
|
#endif /*LV_USE_LOG*/
|
||||||
|
|
||||||
|
@ -724,6 +724,17 @@
|
|||||||
#define LV_LOG_TRACE_ANIM 1
|
#define LV_LOG_TRACE_ANIM 1
|
||||||
#endif
|
#endif
|
||||||
#endif
|
#endif
|
||||||
|
#ifndef LV_LOG_TRACE_MSG
|
||||||
|
#ifdef _LV_KCONFIG_PRESENT
|
||||||
|
#ifdef CONFIG_LV_LOG_TRACE_MSG
|
||||||
|
#define LV_LOG_TRACE_MSG CONFIG_LV_LOG_TRACE_MSG
|
||||||
|
#else
|
||||||
|
#define LV_LOG_TRACE_MSG 0
|
||||||
|
#endif
|
||||||
|
#else
|
||||||
|
#define LV_LOG_TRACE_MSG 1
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
|
||||||
#endif /*LV_USE_LOG*/
|
#endif /*LV_USE_LOG*/
|
||||||
|
|
||||||
|
@ -26,6 +26,7 @@ typedef struct {
|
|||||||
lv_msg_subscribe_cb_t callback;
|
lv_msg_subscribe_cb_t callback;
|
||||||
void * user_data;
|
void * user_data;
|
||||||
void * _priv_data; /*Internal: used only store 'obj' in lv_obj_subscribe*/
|
void * _priv_data; /*Internal: used only store 'obj' in lv_obj_subscribe*/
|
||||||
|
uint8_t _checked : 1; /*Internal: used to prevent multiple notifications*/
|
||||||
} sub_dsc_t;
|
} sub_dsc_t;
|
||||||
|
|
||||||
/**********************
|
/**********************
|
||||||
@ -39,6 +40,7 @@ static void obj_delete_event_cb(lv_event_t * e);
|
|||||||
/**********************
|
/**********************
|
||||||
* STATIC VARIABLES
|
* STATIC VARIABLES
|
||||||
**********************/
|
**********************/
|
||||||
|
static bool restart_notify;
|
||||||
|
|
||||||
/**********************
|
/**********************
|
||||||
* GLOBAL VARIABLES
|
* GLOBAL VARIABLES
|
||||||
@ -47,6 +49,11 @@ static void obj_delete_event_cb(lv_event_t * e);
|
|||||||
/**********************
|
/**********************
|
||||||
* MACROS
|
* MACROS
|
||||||
**********************/
|
**********************/
|
||||||
|
#if LV_LOG_TRACE_MSG
|
||||||
|
#define MSG_TRACE(...) LV_LOG_TRACE(__VA_ARGS__)
|
||||||
|
#else
|
||||||
|
#define MSG_TRACE(...)
|
||||||
|
#endif
|
||||||
|
|
||||||
/**********************
|
/**********************
|
||||||
* GLOBAL FUNCTIONS
|
* GLOBAL FUNCTIONS
|
||||||
@ -68,6 +75,8 @@ void * lv_msg_subscribe(lv_msg_id_t msg_id, lv_msg_subscribe_cb_t cb, void * use
|
|||||||
s->msg_id = msg_id;
|
s->msg_id = msg_id;
|
||||||
s->callback = cb;
|
s->callback = cb;
|
||||||
s->user_data = user_data;
|
s->user_data = user_data;
|
||||||
|
s->_checked = 1; // if subsribed during `notify`, it won't be notified immediately
|
||||||
|
restart_notify = true;
|
||||||
return s;
|
return s;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -89,6 +98,7 @@ void lv_msg_unsubscribe(void * s)
|
|||||||
{
|
{
|
||||||
LV_ASSERT_NULL(s);
|
LV_ASSERT_NULL(s);
|
||||||
_lv_ll_remove(&LV_GC_ROOT(_subs_ll), s);
|
_lv_ll_remove(&LV_GC_ROOT(_subs_ll), s);
|
||||||
|
restart_notify = true;
|
||||||
lv_free(s);
|
lv_free(s);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -138,14 +148,48 @@ lv_msg_t * lv_event_get_msg(lv_event_t * e)
|
|||||||
|
|
||||||
static void notify(lv_msg_t * m)
|
static void notify(lv_msg_t * m)
|
||||||
{
|
{
|
||||||
|
static unsigned int _recursion_counter = 0;
|
||||||
|
_recursion_counter++;
|
||||||
|
|
||||||
|
/*First clear all _checked flags*/
|
||||||
sub_dsc_t * s;
|
sub_dsc_t * s;
|
||||||
|
if(_recursion_counter == 1) {
|
||||||
_LV_LL_READ(&LV_GC_ROOT(_subs_ll), s) {
|
_LV_LL_READ(&LV_GC_ROOT(_subs_ll), s) {
|
||||||
|
s->_checked = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*Run all sub_dsc_t from the list*/
|
||||||
|
do {
|
||||||
|
restart_notify = false;
|
||||||
|
s = _lv_ll_get_head(&LV_GC_ROOT(_subs_ll));
|
||||||
|
while(s) {
|
||||||
|
/*get next element while current is surely valid*/
|
||||||
|
sub_dsc_t * next = _lv_ll_get_next(&LV_GC_ROOT(_subs_ll), s);
|
||||||
|
|
||||||
|
/*Notify only once*/
|
||||||
|
if(!s->_checked) {
|
||||||
|
/*Check if this sub_dsc_t is about this msg_id*/
|
||||||
if(s->msg_id == m->id && s->callback) {
|
if(s->msg_id == m->id && s->callback) {
|
||||||
|
// Set this flag and notify
|
||||||
|
s->_checked = 1;
|
||||||
m->user_data = s->user_data;
|
m->user_data = s->user_data;
|
||||||
m->_priv_data = s->_priv_data;
|
m->_priv_data = s->_priv_data;
|
||||||
s->callback(m);
|
s->callback(m);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*restart or load next*/
|
||||||
|
if(restart_notify) {
|
||||||
|
MSG_TRACE("Start from the first sub_dsc_t again because _subs_ll may have changed");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
s = next;
|
||||||
|
}
|
||||||
|
} while(s);
|
||||||
|
|
||||||
|
_recursion_counter--;
|
||||||
|
restart_notify = (_recursion_counter > 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void obj_notify_cb(lv_msg_t * m)
|
static void obj_notify_cb(lv_msg_t * m)
|
||||||
|
Loading…
x
Reference in New Issue
Block a user