quakeforge/libs/ecs/test/test-registry.c
Bill Currie db7f8a461e [ecs] Move ECS core into its own library
While the libraries are probably getting a little out of hand, the
separation into its own directory is probably a good thing as an ECS
should not be tied to scenes. This should make the ECS more generally
useful.
2022-10-26 17:24:03 +09:00

151 lines
3.7 KiB
C

#ifdef HAVE_CONFIG_H
# include "config.h"
#endif
#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include "QF/scene/component.h"
static int
test_new_del (void)
{
ecs_registry_t *reg = ECS_NewRegistry ();
if (!reg) {
printf ("could not create registry\n");
return 0;
}
if (reg->max_entities && !reg->entities) {
printf ("Non-zero max_entities with null entities pointer\n");
return 0;
}
if (!reg->max_entities && reg->entities) {
printf ("Zero max_entities with non-null entities pointer\n");
return 0;
}
if (reg->num_entities > reg->max_entities) {
printf ("num_entities > max_entities\n");
return 0;
}
if (reg->num_entities) {
printf ("Fresh registry has entities\n");
return 0;
}
if (reg->available) {
printf ("Fresh registry has recycled entities\n");
return 0;
}
ECS_DelRegistry (reg);
return 1;
}
#define NUM_ENTS 5
static int
test_entities (void)
{
ecs_registry_t *reg = ECS_NewRegistry ();
uint32_t entities[NUM_ENTS];
for (int i = 0; i < NUM_ENTS; i++) {
entities[i] = ECS_NewEntity (reg);
}
if (!reg->max_entities || !reg->entities) {
printf ("Zero max_entities or non-null entities pointer\n");
return 0;
}
if (reg->available) {
printf ("unexpected recycled entities\n");
return 0;
}
if (reg->num_entities != NUM_ENTS) {
printf ("wrong number of entities in registry: %d vs %d\n", NUM_ENTS,
reg->num_entities);
return 0;
}
for (int i = 0; i < NUM_ENTS; i++) {
if (Ent_Index (entities[i]) > reg->num_entities) {
printf ("bad entity returned: %d > %d\n", Ent_Index (entities[i]),
reg->num_entities);
return 0;
}
if (Ent_Generation (entities[i])) {
printf ("fresh entity not generation 0\n");
return 0;
}
for (int j = 0; j < i; j++) {
if (Ent_Index (entities[j]) == Ent_Index (entities[i])) {
printf ("duplicate entity id\n");
return 0;
}
}
if (reg->entities[Ent_Index (entities[i])] != entities[i]) {
printf ("wrong entity in entities array: %d %d\n",
entities[i], reg->entities[Ent_Index (entities[i])]);
return 0;
}
}
ECS_DelEntity (reg, entities[2]);
ECS_DelEntity (reg, entities[0]);
if (reg->entities[Ent_Index (entities[2])] == entities[2]) {
printf ("deleted entity not deleted: %d %d\n",
entities[2], reg->entities[Ent_Index (entities[2])]);
return 0;
}
if (reg->entities[Ent_Index (entities[0])] == entities[0]) {
printf ("deleted entity not deleted: %d %d\n",
entities[0], reg->entities[Ent_Index (entities[0])]);
return 0;
}
if (reg->available != 2) {
printf ("not 2 available entity for recycling\n");
return 0;
}
for (uint32_t i = reg->next, c = 0; i != Ent_Index (nullent);
i = Ent_Index (reg->entities[i]), c++) {
if (c >= reg->available || i >= reg->num_entities) {
printf ("invalid deleted entity chain\n");
return 0;
}
if (Ent_Index (reg->entities[i]) == i) {
printf ("deleted entity points to itself\n");
return 0;
}
//printf ("%x\n", reg->entities[i]);
}
entities[2] = ECS_NewEntity (reg);
if (reg->available != 1) {
printf ("not 1 available entity for recycling\n");
return 0;
}
entities[0] = ECS_NewEntity (reg);
if (reg->available != 0) {
printf ("not 0 available entities for recycling\n");
return 0;
}
if (reg->num_entities != NUM_ENTS) {
printf ("wrong number of entities in registry: %d vs %d\n", NUM_ENTS,
reg->num_entities);
return 0;
}
if (!Ent_Generation (entities[2]) || !Ent_Generation (entities[0])) {
printf ("recycled entity generations not updated\n");
return 0;
}
//for (int i = 0; i < NUM_ENTS; i++) {
// printf ("%x\n", entities[i]);
//}
ECS_DelRegistry (reg);
return 1;
}
int
main (void)
{
if (!test_new_del ()) { return 1; }
if (!test_entities ()) { return 1; }
return 0;
}