gui: fix wrong logic on update/render/deinit

The older implementation caused some elements to be
update/rendered/deinitialized more than once per call. For example,
considering the following tree of GUI elements:

A
    B
    C
        D
    E

The older implementation would update/render/deinitialize C and E more
than once, as shown below:

Update A
Update B
Update C
Update D
Update E
Update C

This was because a GUI element was acting on its siblings, but the
siblings would also act on theirs, causing the extra calls.

OTOH, as an additional improvement, no nested call is now required for
siblings.
This commit is contained in:
Xavier Del Campo Romero 2022-09-21 18:14:44 +02:00
parent 3eef29c327
commit 85d4af0266
1 changed files with 15 additions and 11 deletions

View File

@ -155,14 +155,13 @@ void gui_add_child(struct gui_common *const p,
int gui_update(struct gui_common *const g, const union peripheral *const p,
const struct camera *const c, struct input *const in)
{
if (g->child && gui_update(g->child, p, c, in))
return -1;
if (g->cb && g->cb->update && g->cb->update(g, p, c, in))
if ((g->child && gui_update(g->child, p, c, in))
|| (g->cb && g->cb->update && g->cb->update(g, p, c, in)))
return -1;
for (struct gui_common *s = g->sibling; s; s = s->sibling)
if (gui_update(s, p, c, in))
if ((s->child && gui_update(s->child, p, c, in))
|| (s->cb && s->cb->update && s->cb->update(s, p, c, in)))
return -1;
return 0;
@ -170,14 +169,13 @@ int gui_update(struct gui_common *const g, const union peripheral *const p,
int gui_render(const struct gui_common *const g)
{
if (g->cb && g->cb->render && g->cb->render(g))
return -1;
if (g->child && gui_render(g->child))
if ((g->cb && g->cb->render && g->cb->render(g))
|| (g->child && gui_render(g->child)))
return -1;
for (struct gui_common *s = g->sibling; s; s = s->sibling)
if (gui_render(s))
if ((s->cb && s->cb->render && s->cb->render(s))
|| (s->child && gui_render(s->child)))
return -1;
return 0;
@ -192,5 +190,11 @@ void gui_deinit(struct gui_common *const g, struct input *const in)
gui_deinit(g->child, in);
for (struct gui_common *s = g->sibling; s; s = s->sibling)
gui_deinit(s, in);
{
if (s->cb && s->cb->deinit)
s->cb->deinit(s, in);
if (s->child)
gui_deinit(s->child, in);
}
}