#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); }