I’ve made a GUI consisting of several different screens. These screens have shared objects as well as some objects that stay the same across all screens. I’ve made a light and dark mode for all screens and the approach I took used lv_obj_is_valid(). I’ve also made a “stress test” (based off of the lv_demo_music autoplay feature) for my GUI that will interact with each screen and toggle the light/dark mode multiple times before switching to the next screen and looping. What happens is that after a while (sometimes over an hour) lv_obj_is_valid() will return true to an object that does not exist on a screen and cause a crash. I’m unsure if this is known or not, as lv_obj_is_valid() works 99% of the time, has anyone else run into something similar?
Below I’ll outline my approach to the GUI with multiple screens and how the light/dark mode toggle would execute.
The parent of all objects in the GUI is called main_screen, main_screen has children that are the objects that are persistent on all screens and then an invisible container that is the holder for children of a particular screen.
Say main_screen has children main_obj1, main_obj2, screen_cont1, and screen_cont1 has the children obj1, obj2, obj3. And say we want to switch to a different screen. I would call lv_obj_del(screen_cont1), and then setup (create) screen_cont2. screen_cont2 has the children obj2, obj3, obj4. Because screen_cont1 and screen_cont2 share many objects I didn’t want to make a toggle light/dark mode function for every screen using only the objects that exist on that screen. Instead I made a single function to toggle all the objects and just check if they are valid or not, like so:
void adjust_styles(void)
{
// don't check if these objects are valid or not because they are persistent across all screens...
lv_obj_set_style_bg_color(main_obj1, color[screen_mode], LV_PART_MAIN | LV_STATE_DEFAULT);
lv_obj_invalidate(main_obj1);
lv_obj_set_style_bg_color(main_obj2, color[screen_mode], LV_PART_MAIN | LV_STATE_DEFAULT);
lv_obj_invalidate(main_obj2);
// check if these objects are valid
if (lv_obj_is_valid(obj1))
{
lv_obj_set_style_bg_color(obj1, color[screen_mode], LV_PART_MAIN | LV_STATE_DEFAULT);
lv_obj_invalidate(obj1);
}
if (lv_obj_is_valid(obj2))
{
lv_obj_set_style_bg_color(obj2, color[screen_mode], LV_PART_MAIN | LV_STATE_DEFAULT);
lv_obj_invalidate(obj2);
}
if (lv_obj_is_valid(obj3))
{
lv_obj_set_style_bg_color(obj3, color[screen_mode], LV_PART_MAIN | LV_STATE_DEFAULT);
lv_obj_invalidate(obj3);
}
if (lv_obj_is_valid(obj4))
{
lv_obj_set_style_bg_color(obj4, color[screen_mode], LV_PART_MAIN | LV_STATE_DEFAULT);
lv_obj_invalidate(obj4);
}
}
Now what would happen is that this would work for a while, but eventually if adjust_styles() was called while screen_cont2 was the active screen container, somehow lv_obj_is_valid(obj1) would return true even though it doesn’t exist on that screen.
My current workaround is after I delete a screen I then set the object pointers to NULL and check if an object points to NULL or not inside adjust_styles(). It ran for over 16 hours before I was satisfied and closed the debug session. What I’m getting at is I think something may be wrong with lv_obj_is_valid()?