stageobjects: add type-based macros for acquiring from/releasing into the correct pool
This commit is contained in:
parent
13ace0e5c0
commit
b81f338d2d
9 changed files with 71 additions and 54 deletions
|
@ -54,7 +54,7 @@ TASK(boss_damage_to_power, { BoxedBoss boss; }) {
|
|||
}
|
||||
|
||||
Boss *create_boss(const char *name, char *ani, cmplx pos) {
|
||||
Boss *boss = mempool_acquire(&stage_object_pools.bosses);
|
||||
auto boss = STAGE_ACQUIRE_OBJ(Boss);
|
||||
|
||||
boss->name = name;
|
||||
boss->pos = pos;
|
||||
|
@ -1364,7 +1364,7 @@ void free_boss(Boss *boss) {
|
|||
ent_unregister(&boss->ent);
|
||||
boss_set_portrait(boss, NULL, NULL, NULL);
|
||||
aniplayer_free(&boss->ani);
|
||||
mempool_release(&stage_object_pools.bosses, boss);
|
||||
STAGE_RELEASE_OBJ(boss);
|
||||
}
|
||||
|
||||
static void boss_schedule_next_attack(Boss *b, Attack *a) {
|
||||
|
|
|
@ -87,7 +87,7 @@ Enemy *create_enemy_p(EnemyList *enemies, cmplx pos, float hp, EnemyVisual visua
|
|||
log_fatal("Tried to spawn an enemy while in drawing code");
|
||||
}
|
||||
|
||||
Enemy *e = alist_append(enemies, (Enemy*)mempool_acquire(&stage_object_pools.enemies));
|
||||
auto e = alist_append(enemies, STAGE_ACQUIRE_OBJ(Enemy));
|
||||
e->moving = false;
|
||||
e->dir = 0;
|
||||
e->birthtime = global.frames;
|
||||
|
@ -165,7 +165,7 @@ static void *_delete_enemy(ListAnchor *enemies, List* enemy, void *arg) {
|
|||
|
||||
COEVENT_CANCEL_ARRAY(e->events);
|
||||
ent_unregister(&e->ent);
|
||||
mempool_release(&stage_object_pools.enemies, alist_unlink(enemies, e));
|
||||
STAGE_RELEASE_OBJ(alist_unlink(enemies, e));
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
|
|
@ -130,9 +130,7 @@ Item *create_item(cmplx pos, cmplx v, ItemType type) {
|
|||
type = ITEM_SURGE;
|
||||
}
|
||||
|
||||
Item *i = mempool_acquire(&stage_object_pools.items);
|
||||
alist_append(&global.items, i);
|
||||
|
||||
auto i = alist_append(&global.items, STAGE_ACQUIRE_OBJ(Item));
|
||||
i->pos = pos;
|
||||
i->pos0 = pos;
|
||||
i->v = v;
|
||||
|
@ -150,7 +148,7 @@ Item *create_item(cmplx pos, cmplx v, ItemType type) {
|
|||
|
||||
void delete_item(Item *item) {
|
||||
ent_unregister(&item->ent);
|
||||
mempool_release(&stage_object_pools.items, alist_unlink(&global.items, item));
|
||||
STAGE_RELEASE_OBJ(alist_unlink(&global.items, item));
|
||||
}
|
||||
|
||||
Item *create_clear_item(cmplx pos, uint clear_flags) {
|
||||
|
|
|
@ -55,9 +55,7 @@ void lasers_shutdown(void) {
|
|||
}
|
||||
|
||||
Laser *create_laser(cmplx pos, float time, float deathtime, const Color *color, LaserRule rule) {
|
||||
Laser *l = mempool_acquire(&stage_object_pools.lasers);
|
||||
alist_push(&global.lasers, l);
|
||||
|
||||
auto l = alist_push(&global.lasers, STAGE_ACQUIRE_OBJ(Laser));
|
||||
l->birthtime = global.frames;
|
||||
l->timespan = time;
|
||||
l->deathtime = deathtime;
|
||||
|
@ -113,7 +111,7 @@ void laserline_set_posdir(Laser *l, cmplx pos, cmplx dir) {
|
|||
static void *_delete_laser(ListAnchor *lasers, List *laser, void *arg) {
|
||||
Laser *l = (Laser*)laser;
|
||||
ent_unregister(&l->ent);
|
||||
mempool_release(&stage_object_pools.lasers, alist_unlink(lasers, l));
|
||||
STAGE_RELEASE_OBJ(alist_unlink(lasers, l));
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
|
|
@ -245,7 +245,7 @@ static Projectile* _create_projectile(ProjArgs *args) {
|
|||
log_fatal("Tried to spawn a projectile while in drawing code");
|
||||
}
|
||||
|
||||
Projectile *p = mempool_acquire(&stage_object_pools.projectiles);
|
||||
auto p = STAGE_ACQUIRE_OBJ(Projectile);
|
||||
|
||||
p->birthtime = global.frames;
|
||||
p->pos = p->pos0 = p->prevpos = args->pos;
|
||||
|
@ -326,7 +326,7 @@ static void delete_projectile(ProjectileList *projlist, Projectile *p, ProjColli
|
|||
signal_event_with_collision_result(p, &p->events.killed, col);
|
||||
COEVENT_CANCEL_ARRAY(p->events);
|
||||
ent_unregister(&p->ent);
|
||||
mempool_release(&stage_object_pools.projectiles, alist_unlink(projlist, p));
|
||||
STAGE_RELEASE_OBJ(alist_unlink(projlist, p));
|
||||
}
|
||||
|
||||
static void *foreach_delete_projectile(ListAnchor *projlist, List *proj, void *arg) {
|
||||
|
|
|
@ -1167,8 +1167,8 @@ static void stage_draw_hud_scores(float ypos_hiscore, float ypos_score, char *bu
|
|||
|
||||
static void stage_draw_hud_objpool_stats(float x, float y, float width) {
|
||||
char buf[128];
|
||||
auto objpools = STAGE_OBJPOOLS_AS_ARRAYPTR;
|
||||
MemArena *arena = (*objpools)[0].arena;
|
||||
auto objpools = &stage_objects.pools.as_array;
|
||||
MemArena *arena = &stage_objects.arena;
|
||||
|
||||
Font *font = res_font("monotiny");
|
||||
|
||||
|
@ -1198,9 +1198,9 @@ static void stage_draw_hud_objpool_stats(float x, float y, float width) {
|
|||
y += lineskip * 1.5;
|
||||
|
||||
const char *const names[] = {
|
||||
#define OBJECT_POOL(t, n) #t,
|
||||
OBJECT_POOLS
|
||||
#undef OBJECT_POOL
|
||||
#define GET_POOL_NAME(t, n) #t,
|
||||
OBJECT_POOLS(GET_POOL_NAME)
|
||||
#undef GET_POOL_NAME
|
||||
};
|
||||
|
||||
static_assert(ARRAY_SIZE(*objpools) == ARRAY_SIZE(names));
|
||||
|
|
|
@ -10,26 +10,22 @@
|
|||
|
||||
#define INIT_ARENA_SIZE (8 << 20)
|
||||
|
||||
StageObjectPools stage_object_pools;
|
||||
|
||||
static struct {
|
||||
MemArena arena;
|
||||
} stgobjs;
|
||||
StageObjects stage_objects;
|
||||
|
||||
void stage_objpools_init(void) {
|
||||
if(!stgobjs.arena.pages.first) {
|
||||
marena_init(&stgobjs.arena, INIT_ARENA_SIZE - sizeof(MemArenaPage));
|
||||
if(!stage_objects.arena.pages.first) {
|
||||
marena_init(&stage_objects.arena, INIT_ARENA_SIZE - sizeof(MemArenaPage));
|
||||
} else {
|
||||
marena_reset(&stgobjs.arena);
|
||||
marena_reset(&stage_objects.arena);
|
||||
}
|
||||
|
||||
#define OBJECT_POOL(type, field) \
|
||||
mempool_init(&stage_object_pools.field, &stgobjs.arena);
|
||||
#define INIT_POOL(type, field) \
|
||||
mempool_init(&stage_objects.pools.field, &stage_objects.arena);
|
||||
|
||||
OBJECT_POOLS
|
||||
#undef OBJECT_POOL
|
||||
OBJECT_POOLS(INIT_POOL)
|
||||
#undef INIT_POOL
|
||||
}
|
||||
|
||||
void stage_objpools_shutdown(void) {
|
||||
marena_deinit(&stgobjs.arena);
|
||||
marena_deinit(&stage_objects.arena);
|
||||
}
|
||||
|
|
|
@ -18,29 +18,55 @@
|
|||
#include "stagetext.h" // IWYU pragma: export
|
||||
#include "boss.h" // IWYU pragma: export
|
||||
|
||||
#define OBJECT_POOLS \
|
||||
OBJECT_POOL(Projectile, projectiles) \
|
||||
OBJECT_POOL(Item, items) \
|
||||
OBJECT_POOL(Enemy, enemies) \
|
||||
OBJECT_POOL(Laser, lasers) \
|
||||
OBJECT_POOL(StageText, stagetext) \
|
||||
OBJECT_POOL(Boss, bosses) \
|
||||
#define OBJECT_POOLS(X) \
|
||||
X(Projectile, projectiles) \
|
||||
X(Item, items) \
|
||||
X(Enemy, enemies) \
|
||||
X(Laser, lasers) \
|
||||
X(StageText, stagetext) \
|
||||
X(Boss, bosses) \
|
||||
|
||||
typedef struct StageObjectPools {
|
||||
#define OBJECT_POOL(type, field) \
|
||||
MEMPOOL(type) field;
|
||||
enum {
|
||||
#define COUNT_POOL(...) 1 +
|
||||
NUM_STAGE_OBJECT_POOLS = OBJECT_POOLS(COUNT_POOL) 0,
|
||||
#undef COUNT_POOL
|
||||
};
|
||||
|
||||
OBJECT_POOLS
|
||||
#undef OBJECT_POOL
|
||||
} StageObjectPools;
|
||||
typedef struct StageObjects {
|
||||
MemArena arena;
|
||||
union {
|
||||
struct {
|
||||
#define DECLARE_POOL(type, field) \
|
||||
MEMPOOL(type) field;
|
||||
|
||||
extern StageObjectPools stage_object_pools;
|
||||
OBJECT_POOLS(DECLARE_POOL)
|
||||
#undef DECLARE_POOL
|
||||
};
|
||||
MemPool as_array[NUM_STAGE_OBJECT_POOLS];
|
||||
} pools;
|
||||
} StageObjects;
|
||||
|
||||
#define STAGE_OBJPOOLS_AS_ARRAYPTR \
|
||||
(MemPool (*)[sizeof(stage_object_pools) / sizeof(MemPool)])&stage_object_pools
|
||||
extern StageObjects stage_objects;
|
||||
|
||||
#define STAGE_OBJPOOL_GENERIC_DISPATCH(_type, _field) \
|
||||
_type*: &stage_objects.pools._field,
|
||||
|
||||
#define STAGE_OBJPOOL_BY_VARTYPE(_p_obj) \
|
||||
_Generic((_p_obj), \
|
||||
OBJECT_POOLS(STAGE_OBJPOOL_GENERIC_DISPATCH) \
|
||||
struct {}: abort())
|
||||
|
||||
#define STAGE_OBJPOOL_BY_TYPE(type) \
|
||||
STAGE_OBJPOOL_BY_VARTYPE(&(type) {})
|
||||
|
||||
// Can be called many times to reinitialize the pools while reusing allocated arena memory.
|
||||
void stage_objpools_init(void);
|
||||
|
||||
// Frees the arena
|
||||
void stage_objpools_shutdown(void);
|
||||
|
||||
#define STAGE_ACQUIRE_OBJ(_type) \
|
||||
mempool_acquire(STAGE_OBJPOOL_BY_TYPE(_type))
|
||||
|
||||
#define STAGE_RELEASE_OBJ(_p_obj) \
|
||||
mempool_release(STAGE_OBJPOOL_BY_VARTYPE(_p_obj), (_p_obj))
|
||||
|
|
|
@ -13,9 +13,8 @@
|
|||
|
||||
static StageText *textlist = NULL;
|
||||
|
||||
StageText* stagetext_add(const char *text, cmplx pos, Alignment align, Font *font, const Color *clr, int delay, int lifetime, int fadeintime, int fadeouttime) {
|
||||
StageText *t = mempool_acquire(&stage_object_pools.stagetext);
|
||||
list_append(&textlist, t);
|
||||
StageText *stagetext_add(const char *text, cmplx pos, Alignment align, Font *font, const Color *clr, int delay, int lifetime, int fadeintime, int fadeouttime) {
|
||||
auto t = list_append(&textlist, STAGE_ACQUIRE_OBJ(StageText));
|
||||
|
||||
if(text != NULL) {
|
||||
assert(strlen(text) < sizeof(t->text));
|
||||
|
@ -39,15 +38,15 @@ static void stagetext_numeric_update(StageText *txt, int t, float a) {
|
|||
format_huge_num(0, (uintptr_t)txt->custom.data1 * pow(a, 5), sizeof(txt->text), txt->text);
|
||||
}
|
||||
|
||||
StageText* stagetext_add_numeric(int n, cmplx pos, Alignment align, Font *font, const Color *clr, int delay, int lifetime, int fadeintime, int fadeouttime) {
|
||||
StageText *t = stagetext_add(NULL, pos, align, font, clr, delay, lifetime, fadeintime, fadeouttime);
|
||||
StageText *stagetext_add_numeric(int n, cmplx pos, Alignment align, Font *font, const Color *clr, int delay, int lifetime, int fadeintime, int fadeouttime) {
|
||||
auto t = stagetext_add(NULL, pos, align, font, clr, delay, lifetime, fadeintime, fadeouttime);
|
||||
t->custom.data1 = (void*)(intptr_t)n;
|
||||
t->custom.update = stagetext_numeric_update;
|
||||
return t;
|
||||
}
|
||||
|
||||
static void *stagetext_delete(List **dest, List *txt, void *arg) {
|
||||
mempool_release(&stage_object_pools.stagetext, list_unlink(dest, (StageText*)txt));
|
||||
STAGE_RELEASE_OBJ(list_unlink(dest, (StageText*)txt));
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in a new issue