quakeforge/libs/ecs/test/test-components.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

133 lines
3 KiB
C

#ifdef HAVE_CONFIG_H
# include "config.h"
#endif
#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include "QF/simd/types.h"
#include "QF/mathlib.h"
#include "QF/scene/component.h"
enum test_components {
test_position,
test_scale,
test_rotation,
test_num_components
};
static void
create_position (void *data)
{
vec4f_t *pos = data;
*pos = (vec4f_t) { 0, 0, 0, 1 };
}
static void
create_scale (void *data)
{
vec_t *scale = data;
VectorSet (1, 1, 1, scale);
}
static void
create_rotation (void *data)
{
vec4f_t *rot = data;
*rot = (vec4f_t) { 0, 0, 0, 1 };
}
static const component_t test_components[] = {
[test_position] = {
.size = sizeof (vec4f_t),
.create = create_position,
.name = "position",
},
[test_scale] = {
.size = sizeof (vec3_t),
.create = create_scale,
.name = "scale",
},
[test_rotation] = {
.size = sizeof (vec4f_t),
.create = create_rotation,
.name = "rotation",
},
};
static int
check_ent_components (const uint32_t *ents, uint32_t count, uint32_t comp,
ecs_registry_t *reg)
{
ecs_pool_t *pool = &reg->comp_pools[comp];
const component_t *component = &reg->components[comp];
if (pool->count != count) {
printf ("%s pool has wrong object count: %d %d\n", component->name,
pool->count, count);
return 0;
}
uint32_t num_entities = 0;
for (uint32_t i = 0; i < reg->max_entities; i++) {
if (pool->sparse[i] == nullent) {
continue;
}
if (pool->sparse[i] < pool->count) {
num_entities++;
continue;
}
printf ("invalid index in sparse array of %s: %d %d\n", component->name,
pool->sparse[i], pool->count);
return 0;
}
if (num_entities != count) {
printf ("%s sparse has wrong entity count: %d %d\n", component->name,
num_entities, count);
return 0;
}
for (uint32_t i = 0; i < count; i++) {
if (pool->sparse[Ent_Index (ents[i])] == nullent) {
printf ("ent not in %s sparse: %x\n", component->name, ents[i]);
return 0;
}
if (pool->dense[pool->sparse[Ent_Index (ents[i])]] != ents[i]) {
printf ("indexed %s dense does have ent: %x %x\n", component->name,
pool->dense[pool->sparse[Ent_Index (ents[i])]], ents[i]);
return 0;
}
}
return 1;
}
int
main (void)
{
ecs_registry_t *reg = ECS_NewRegistry ();
ECS_RegisterComponents (reg, test_components, test_num_components);
uint32_t enta = ECS_NewEntity (reg);
uint32_t entb = ECS_NewEntity (reg);
uint32_t entc = ECS_NewEntity (reg);
Ent_AddComponent (enta, test_position, reg);
Ent_AddComponent (entb, test_position, reg);
Ent_AddComponent (entc, test_position, reg);
Ent_AddComponent (enta, test_rotation, reg);
Ent_AddComponent (entb, test_rotation, reg);
Ent_AddComponent (enta, test_scale, reg);
if (!check_ent_components ((uint32_t[]){enta, entb, entc}, 3,
test_position, reg)) {
return 1;
}
if (!check_ent_components ((uint32_t[]){enta, entb}, 2,
test_rotation, reg)) {
return 1;
}
if (!check_ent_components ((uint32_t[]){enta}, 1, test_scale, reg)) {
return 1;
}
ECS_DelRegistry (reg);
return 0;
}