Skip to content

Commit

Permalink
stageobjects: add type-based macros for acquiring from/releasing into…
Browse files Browse the repository at this point in the history
… the correct pool
  • Loading branch information
Akaricchi committed Jun 5, 2024
1 parent 13ace0e commit b81f338
Show file tree
Hide file tree
Showing 9 changed files with 71 additions and 54 deletions.
4 changes: 2 additions & 2 deletions src/boss.c
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -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) {
Expand Down
4 changes: 2 additions & 2 deletions src/enemy.c
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -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;
}
Expand Down
6 changes: 2 additions & 4 deletions src/item.c
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand All @@ -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) {
Expand Down
6 changes: 2 additions & 4 deletions src/lasers/laser.c
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -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;
}

Expand Down
4 changes: 2 additions & 2 deletions src/projectile.c
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -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) {
Expand Down
10 changes: 5 additions & 5 deletions src/stagedraw.c
Original file line number Diff line number Diff line change
Expand Up @@ -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");

Expand Down Expand Up @@ -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));
Expand Down
22 changes: 9 additions & 13 deletions src/stageobjects.c
Original file line number Diff line number Diff line change
Expand Up @@ -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);
}
58 changes: 42 additions & 16 deletions src/stageobjects.h
Original file line number Diff line number Diff line change
Expand Up @@ -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))
11 changes: 5 additions & 6 deletions src/stagetext.c
Original file line number Diff line number Diff line change
Expand Up @@ -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));
Expand All @@ -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;
}

Expand Down

0 comments on commit b81f338

Please sign in to comment.