Merge pull request #7771 from libretro/sgc-menu-animation

Animations deleted whilst in update loop may cause crash
This commit is contained in:
Twinaphex 2018-12-19 17:45:58 +01:00 committed by GitHub
commit a7bb1e60aa
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

View File

@ -44,6 +44,7 @@ struct tween
easing_cb easing; easing_cb easing;
tween_cb cb; tween_cb cb;
void *userdata; void *userdata;
bool deleted;
}; };
DA_TYPEDEF(struct tween, tween_array_t) DA_TYPEDEF(struct tween, tween_array_t)
@ -52,6 +53,7 @@ struct menu_animation
{ {
tween_array_t list; tween_array_t list;
tween_array_t pending; tween_array_t pending;
bool pending_deletes;
bool in_update; bool in_update;
}; };
@ -341,6 +343,7 @@ bool menu_animation_push(menu_animation_ctx_entry_t *entry)
t.cb = entry->cb; t.cb = entry->cb;
t.userdata = entry->userdata; t.userdata = entry->userdata;
t.easing = NULL; t.easing = NULL;
t.deleted = false;
switch (entry->easing_enum) switch (entry->easing_enum)
{ {
@ -471,7 +474,8 @@ bool menu_animation_update(float delta_time)
{ {
unsigned i; unsigned i;
anim.in_update = true; anim.in_update = true;
anim.pending_deletes = false;
for(i = 0; i < da_count(anim.list); i++) for(i = 0; i < da_count(anim.list); i++)
{ {
@ -496,6 +500,20 @@ bool menu_animation_update(float delta_time)
} }
} }
if (anim.pending_deletes)
{
for(i = 0; i < da_count(anim.list); i++)
{
struct tween *tween = da_getptr(anim.list, i);
if (tween->deleted)
{
da_delete(anim.list, i);
i--;
}
}
anim.pending_deletes = false;
}
if (da_count(anim.pending) > 0) if (da_count(anim.pending) > 0)
{ {
da_addn(anim.list, anim.pending.p, da_count(anim.pending)); da_addn(anim.list, anim.pending.p, da_count(anim.pending));
@ -594,9 +612,17 @@ bool menu_animation_kill_by_tag(menu_animation_ctx_tag *tag)
struct tween *t = da_getptr(anim.list, i); struct tween *t = da_getptr(anim.list, i);
if (t->tag != *tag) if (t->tag != *tag)
continue; continue;
da_delete(anim.list, i); if (anim.in_update)
--i; {
t->deleted = true;
anim.pending_deletes = true;
}
else
{
da_delete(anim.list, i);
--i;
}
} }
return true; return true;
@ -615,9 +641,17 @@ void menu_animation_kill_by_subject(menu_animation_ctx_subject_t *subject)
{ {
if (t->subject != sub[j]) if (t->subject != sub[j])
continue; continue;
da_delete(anim.list, i); if (anim.in_update)
--i; {
t->deleted = true;
anim.pending_deletes = true;
}
else
{
da_delete(anim.list, i);
--i;
}
killed++; killed++;
break; break;