JacksEscape/entity.c

148 lines
3.4 KiB
C
Raw Normal View History

2024-03-05 11:40:42 +08:00
#include "entity.h"
#include "app.h"
2024-03-08 14:51:29 +08:00
#include "camera.h"
2024-03-30 21:25:39 +08:00
#include "mapper_misc.h"
2024-03-05 11:40:42 +08:00
#include "physics.h"
2024-04-14 15:22:55 +08:00
#include "render_component.h"
#include "util/assert.h"
#include "util/tree.h"
#include "util/vector.h"
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
2024-03-30 21:25:39 +08:00
// Frees every member if they exists.
static void _entity_FreeMembers(Entity *e) {
if (e->position)
free(e->position);
if (e->hitbox)
free(e->hitbox);
if (e->player)
free(e->player);
if (e->name)
free(e->name);
if (e->render)
render_DeleteComponent(e->render);
if (e->misc)
misc_DeleteComponent(e->misc);
}
System_Entity *entity_NewSystem(App *super) {
System_Entity *sys = malloc(sizeof(System_Entity));
sys->entities = tree_Create(sizeof(Entity));
sys->maxID = 0;
sys->super = super;
sys->flaggedDelete = vector_Create(sizeof(uintptr_t));
return sys;
}
void entity_DeleteSystem(System_Entity *sys) {
for (tree_Node *i = tree_FirstNode(sys->entities);
i != NULL;
i = tree_Node_Next(i)) {
Entity *e = (Entity *)(i->data);
physics_DeleteEntity(sys->super->physics, e->id);
player_DeleteEntity(sys->super->player, e->id);
2024-03-08 14:51:29 +08:00
camera_DeleteEntity(sys->super->camera, e->id);
2024-03-30 21:25:39 +08:00
_entity_FreeMembers(e);
}
tree_Destroy(sys->entities);
vector_Destroy(sys->flaggedDelete);
}
Entity *entity_Create(System_Entity *sys, const char *name) {
uintptr_t id = ++sys->maxID;
bool added = false;
Entity *e = (Entity *)(tree_Insert(sys->entities, id, &added));
ASSERT(added && "entity ID conflict in entity_Create");
memset(e, 0, sizeof(Entity));
e->id = id;
size_t len;
if (name && (len = strlen(name)) > 0) {
e->name = malloc(len + 1);
memcpy(e->name, name, len + 1);
}
return e;
}
2024-03-04 16:13:43 +08:00
void entity_Commit(System_Entity *sys, Entity *e) {
physics_AddEntity(sys->super->physics, e);
player_AddEntity(sys->super->player, e);
2024-03-08 14:51:29 +08:00
camera_AddEntity(sys->super->camera, e);
2024-03-04 16:13:43 +08:00
}
static inline void _entity_Delete(System_Entity *sys, uintptr_t id) {
tree_Node *node = tree_FindNode(sys->entities, id);
if (!node) {
fprintf(stderr, "[entity_Delete][WARN] Missing entity ID [%d]\n", id);
return;
}
Entity *e = (Entity *)(node->data);
fprintf(stderr, "[entity_Delete] Deleting \"%s\"[%d]\n", e->name, e->id);
physics_DeleteEntity(sys->super->physics, e->id);
player_DeleteEntity(sys->super->player, e->id);
2024-03-08 14:51:29 +08:00
camera_DeleteEntity(sys->super->camera, e->id);
2024-04-14 15:22:55 +08:00
2024-03-30 21:25:39 +08:00
_entity_FreeMembers(e);
tree_Delete(sys->entities, node);
}
void entity_Delete(System_Entity *sys, uintptr_t id) {
vector_Push(sys->flaggedDelete, &id);
}
void entity_Advance(System_Entity *sys, Duration deltaTime) {
// Delete flagged entities
for (int i = 0; i < vector_Size(sys->flaggedDelete); i++) {
_entity_Delete(sys, *(uintptr_t *)(vector_At(sys->flaggedDelete, i)));
}
for (tree_Node *i = tree_FirstNode(sys->entities);
i != NULL;
i = tree_Node_Next(i)) {
Entity *e = (Entity *)(i->data);
if (e->thinker)
2024-03-30 21:25:39 +08:00
e->thinker(sys->super, e, deltaTime);
}
}
void entity_Clear(System_Entity *sys) {
// Build a list of all entity IDs
vector_Clear(sys->flaggedDelete);
for (tree_Node *i = tree_FirstNode(sys->entities);
i != NULL;
i = tree_Node_Next(i)) {
Entity *e = (Entity *)i->data;
vector_Push(sys->flaggedDelete, &e->id);
}
// _Delete all of them
for (int i = 0; i < vector_Size(sys->flaggedDelete); i++) {
_entity_Delete(sys, *(uintptr_t *)(vector_At(sys->flaggedDelete, i)));
}
vector_Clear(sys->flaggedDelete);
ASSERT(tree_Count(sys->entities) == 0);
}