89 lines
1.7 KiB
C
89 lines
1.7 KiB
C
#include "entity.h"
|
|
|
|
#include <assert.h>
|
|
#include <string.h>
|
|
|
|
#define MAX_COMPONENTS_PER_ENTITY 4U
|
|
|
|
typedef struct {
|
|
update_cb_t update;
|
|
remove_cb_t remove;
|
|
void *ref;
|
|
} component_t;
|
|
|
|
typedef struct {
|
|
bool marked;
|
|
unsigned count;
|
|
component_t components[MAX_COMPONENTS_PER_ENTITY];
|
|
} entity_t;
|
|
|
|
static unsigned count;
|
|
static entity_t entities[MAX_ENTITIES];
|
|
|
|
void entities_clear()
|
|
{
|
|
count = 0;
|
|
}
|
|
|
|
void entities_purge()
|
|
{
|
|
for (unsigned id = count - 1; id < count; --id) {
|
|
entity_t *e = entities + id;
|
|
if (!e->marked)
|
|
continue;
|
|
|
|
for (unsigned i = 0; i < e->count; ++i)
|
|
e->components[i].remove(e->components[i].ref);
|
|
|
|
const unsigned last = count - 1;
|
|
if (id != last) {
|
|
memcpy(e, entities + last, sizeof(entity_t));
|
|
for (unsigned i = 0; i < e->count; ++i)
|
|
e->components[i].update(id, e->components[i].ref);
|
|
}
|
|
|
|
--count;
|
|
}
|
|
}
|
|
|
|
unsigned entity_add()
|
|
{
|
|
assert(count < MAX_ENTITIES);
|
|
const unsigned id = count++;
|
|
memset(entities + id, 0, sizeof(entity_t));
|
|
return id;
|
|
}
|
|
|
|
void entity_mark(unsigned id)
|
|
{
|
|
assert(id < count);
|
|
entities[id].marked = true;
|
|
}
|
|
|
|
unsigned entity_add_component(
|
|
unsigned id, update_cb_t update, remove_cb_t remove, void *ref)
|
|
{
|
|
assert(id < count);
|
|
entity_t *e = entities + id;
|
|
|
|
assert(e->count < MAX_COMPONENTS_PER_ENTITY);
|
|
const unsigned component_id = e->count++;
|
|
e->components[component_id] = (component_t) {
|
|
.update = update,
|
|
.remove = remove,
|
|
.ref = ref,
|
|
};
|
|
|
|
return component_id;
|
|
}
|
|
|
|
void entity_update_component(
|
|
unsigned entity_id, unsigned component_id, void *new_ref)
|
|
{
|
|
assert(entity_id < count);
|
|
entity_t *e = entities + entity_id;
|
|
|
|
assert(component_id < e->count);
|
|
e->components[component_id].ref = new_ref;
|
|
}
|