RogueLife/src/comp/entity.c

78 lines
1.9 KiB
C

#include "comp/entity.h"
#include "comp/physical.h"
#include "comp/visible.h"
#include "comp/mechanical.h"
#include "comp/fighter.h"
#include "comp/particle.h"
#include "aoe.h"
/* Align up to native pointer size */
#define ALIGN(expr) ((((expr) - 1) | (sizeof(void *) - 1)) + 1)
entity_t *(entity_make)(uint32_t comps)
{
/* Determine full size of entity; also store offsets of components (we
explicitly 4-align them so we don't want to compute it several times) */
int offsets[ENTITY_COMP_CAPACITY] = { 0 };
size_t size = 0;
int n = 0;
if(comps & ENTITY_COMP_physical) {
offsets[n++] = size;
size = ALIGN(size + sizeof(physical_t));
}
if(comps & ENTITY_COMP_visible) {
offsets[n++] = size;
size = ALIGN(size + sizeof(visible_t));
}
if(comps & ENTITY_COMP_mechanical) {
offsets[n++] = size;
size = ALIGN(size + sizeof(mechanical_t));
}
if(comps & ENTITY_COMP_fighter) {
offsets[n++] = size;
size = ALIGN(size + sizeof(fighter_t));
}
if(comps & ENTITY_COMP_aoe) {
offsets[n++] = size;
size = ALIGN(size + sizeof(aoe_t));
}
if(comps & ENTITY_COMP_particle) {
offsets[n++] = size;
size = ALIGN(size + sizeof(particle_t));
}
/* Allocate all components together */
entity_t *e;
size_t base_size = sizeof(*e) + n * sizeof(e->data[0]);
e = calloc(1, base_size + size);
if(e == NULL)
return NULL;
/* Initialize component addresses */
e->comps = comps;
for(int i = 0; i < n; i++)
e->data[i] = (void *)e + base_size + offsets[i];
return e;
}
void entity_mark_to_delete(entity_t *e)
{
e->deleted = 1;
}
void entity_destroy(entity_t *e)
{
if(e->comps & ENTITY_COMP_aoe) {
aoe_destroy(e);
}
if(e->comps & ENTITY_COMP_fighter) {
fighter_destroy(e);
}
/* Since there's only one allocation for all components, this is easy */
free(e);
}