Merge pull request #11187 from schellingb/gfx_animation_rbuf

Simplify gfx_animation by switching from dynarray to rbuf
This commit is contained in:
Autechre 2020-08-13 17:23:16 +02:00 committed by GitHub
commit 15b6a6ede4
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 35 additions and 61 deletions

View File

@ -24,12 +24,7 @@
#include <string/stdstring.h> #include <string/stdstring.h>
#include <features/features_cpu.h> #include <features/features_cpu.h>
#include <lists/string_list.h> #include <lists/string_list.h>
#include <array/rbuf.h>
#define DG_DYNARR_IMPLEMENTATION
#include <retro_assert.h>
#define DG_DYNARR_ASSERT(cond, msg) (void)0
#include <array/dynarray.h>
#undef DG_DYNARR_IMPLEMENTATION
#include "gfx_animation.h" #include "gfx_animation.h"
#include "../performance_counters.h" #include "../performance_counters.h"
@ -50,11 +45,8 @@ struct tween
bool deleted; bool deleted;
}; };
DA_TYPEDEF(struct tween, tween_array_t)
struct gfx_animation struct gfx_animation
{ {
bool initialized;
bool pending_deletes; bool pending_deletes;
bool in_update; bool in_update;
bool animation_is_active; bool animation_is_active;
@ -69,8 +61,8 @@ struct gfx_animation
float delta_time; float delta_time;
tween_array_t list; struct tween* list;
tween_array_t pending; struct tween* pending;
}; };
typedef struct gfx_animation gfx_animation_t; typedef struct gfx_animation gfx_animation_t;
@ -1191,17 +1183,10 @@ bool gfx_animation_push(gfx_animation_ctx_entry_t *entry)
if (!t.easing || t.duration == 0 || t.initial_value == t.target_value) if (!t.easing || t.duration == 0 || t.initial_value == t.target_value)
return false; return false;
if (!p_anim->initialized)
{
da_init(p_anim->list);
da_init(p_anim->pending);
p_anim->initialized = true;
}
if (p_anim->in_update) if (p_anim->in_update)
da_push(p_anim->pending, t); RBUF_PUSH(p_anim->pending, t);
else else
da_push(p_anim->list, t); RBUF_PUSH(p_anim->list, t);
return true; return true;
} }
@ -1347,11 +1332,11 @@ bool gfx_animation_update(
p_anim->in_update = true; p_anim->in_update = true;
p_anim->pending_deletes = false; p_anim->pending_deletes = false;
for (i = 0; i < da_count(p_anim->list); i++) for (i = 0; i < RBUF_LEN(p_anim->list); i++)
{ {
struct tween *tween = da_getptr(p_anim->list, i); struct tween *tween = &p_anim->list[i];
if (!tween || tween->deleted) if (tween->deleted)
continue; continue;
tween->running_since += p_anim->delta_time; tween->running_since += p_anim->delta_time;
@ -1369,35 +1354,37 @@ bool gfx_animation_update(
if (tween->cb) if (tween->cb)
tween->cb(tween->userdata); tween->cb(tween->userdata);
da_delete(p_anim->list, i); RBUF_REMOVE(p_anim->list, i);
i--; i--;
} }
} }
if (p_anim->pending_deletes) if (p_anim->pending_deletes)
{ {
for (i = 0; i < da_count(p_anim->list); i++) for (i = 0; i < RBUF_LEN(p_anim->list); i++)
{ {
struct tween *tween = da_getptr(p_anim->list, i); struct tween *tween = &p_anim->list[i];
if (!tween)
continue;
if (tween->deleted) if (tween->deleted)
{ {
da_delete(p_anim->list, i); RBUF_REMOVE(p_anim->list, i);
i--; i--;
} }
} }
p_anim->pending_deletes = false; p_anim->pending_deletes = false;
} }
if (da_count(p_anim->pending) > 0) if (RBUF_LEN(p_anim->pending) > 0)
{ {
da_addn(p_anim->list, p_anim->pending.p, da_count(p_anim->pending)); size_t list_len = RBUF_LEN(p_anim->list);
da_clear(p_anim->pending); size_t pending_len = RBUF_LEN(p_anim->pending);
RBUF_RESIZE(p_anim->list, list_len + pending_len);
memcpy(p_anim->list + list_len, p_anim->pending,
sizeof(*p_anim->pending) * pending_len);
RBUF_CLEAR(p_anim->pending);
} }
p_anim->in_update = false; p_anim->in_update = false;
p_anim->animation_is_active = da_count(p_anim->list) > 0; p_anim->animation_is_active = RBUF_LEN(p_anim->list) > 0;
return p_anim->animation_is_active; return p_anim->animation_is_active;
} }
@ -2240,11 +2227,11 @@ bool gfx_animation_kill_by_tag(uintptr_t *tag)
return false; return false;
/* Scan animation list */ /* Scan animation list */
for (i = 0; i < da_count(p_anim->list); ++i) for (i = 0; i < RBUF_LEN(p_anim->list); ++i)
{ {
struct tween *t = da_getptr(p_anim->list, i); struct tween *t = &p_anim->list[i];
if (!t || t->tag != *tag) if (t->tag != *tag)
continue; continue;
/* If we are currently inside gfx_animation_update(), /* If we are currently inside gfx_animation_update(),
@ -2259,7 +2246,7 @@ bool gfx_animation_kill_by_tag(uintptr_t *tag)
} }
else else
{ {
da_delete(p_anim->list, i); RBUF_REMOVE(p_anim->list, i);
--i; --i;
} }
} }
@ -2271,14 +2258,14 @@ bool gfx_animation_kill_by_tag(uintptr_t *tag)
* deleted at all, producing utter chaos) */ * deleted at all, producing utter chaos) */
if (p_anim->in_update) if (p_anim->in_update)
{ {
for (i = 0; i < da_count(p_anim->pending); ++i) for (i = 0; i < RBUF_LEN(p_anim->pending); ++i)
{ {
struct tween *t = da_getptr(p_anim->pending, i); struct tween *t = &p_anim->pending[i];
if (!t || t->tag != *tag) if (t->tag != *tag)
continue; continue;
da_delete(p_anim->pending, i); RBUF_REMOVE(p_anim->pending, i);
--i; --i;
} }
} }
@ -2299,26 +2286,9 @@ bool gfx_animation_ctl(enum gfx_animation_ctl_state state, void *data)
switch (state) switch (state)
{ {
case MENU_ANIMATION_CTL_DEINIT: case MENU_ANIMATION_CTL_DEINIT:
{ RBUF_FREE(p_anim->list);
size_t i; RBUF_FREE(p_anim->pending);
memset(p_anim, 0, sizeof(*p_anim));
for (i = 0; i < da_count(p_anim->list); i++)
{
struct tween *t = da_getptr(p_anim->list, i);
if (!t)
continue;
if (t->subject)
t->subject = NULL;
}
da_free(p_anim->list);
da_free(p_anim->pending);
}
p_anim->cur_time = 0;
p_anim->old_time = 0;
p_anim->delta_time = 0.0f;
memset(&p_anim, 0, sizeof(p_anim));
break; break;
case MENU_ANIMATION_CTL_CLEAR_ACTIVE: case MENU_ANIMATION_CTL_CLEAR_ACTIVE:
p_anim->animation_is_active = false; p_anim->animation_is_active = false;

View File

@ -33,6 +33,9 @@
* The first time an element is added, memory for 16 elements are allocated. * The first time an element is added, memory for 16 elements are allocated.
* Then every time length is about to exceed capacity, capacity is doubled. * Then every time length is about to exceed capacity, capacity is doubled.
* *
* Be careful not to supply modifying statements to the macro arguments.
* Something like RBUF_REMOVE(buf, i--); would have unintended results.
*
* Sample usage: * Sample usage:
* *
* mytype_t* buf = NULL; * mytype_t* buf = NULL;
@ -74,6 +77,7 @@
#define RBUF_RESIZE(b, sz) (RBUF_FIT((b), (sz)), ((b) ? RBUF__HDR(b)->len = (sz) : 0)) #define RBUF_RESIZE(b, sz) (RBUF_FIT((b), (sz)), ((b) ? RBUF__HDR(b)->len = (sz) : 0))
#define RBUF_CLEAR(b) ((b) ? RBUF__HDR(b)->len = 0 : 0) #define RBUF_CLEAR(b) ((b) ? RBUF__HDR(b)->len = 0 : 0)
#define RBUF_TRYFIT(b, n) (RBUF_FIT((b), (n)), (((b) && RBUF_CAP(b) >= (size_t)(n)) || !(n))) #define RBUF_TRYFIT(b, n) (RBUF_FIT((b), (n)), (((b) && RBUF_CAP(b) >= (size_t)(n)) || !(n)))
#define RBUF_REMOVE(b, idx) memmove((b) + (idx), (b) + (idx) + 1, (--RBUF__HDR(b)->len - (idx)) * sizeof(*(b)))
struct rbuf__hdr struct rbuf__hdr
{ {