Refactor into more modular architecture
This commit is contained in:
88
entity.c
Normal file
88
entity.c
Normal file
@@ -0,0 +1,88 @@
|
||||
#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;
|
||||
}
|
||||
Reference in New Issue
Block a user