[ecs] Add hierarchy-only tests

The hierarchy-specific tests from the transform tests have been moved
into the ecs tests and the transform tests renamed appropriately. As
part of the process, hierarchies can now have a null type (ie, no
additional components maintained by the hierarchy). This should make
sorting out the issues highlighted by sbar a bit easier.
This commit is contained in:
Bill Currie 2022-11-05 21:26:47 +09:00
parent 57cd30fca3
commit 10037927ea
5 changed files with 534 additions and 279 deletions

View File

@ -94,9 +94,11 @@ Hierarchy_Reserve (hierarchy_t *hierarchy, uint32_t count)
Component_ResizeArray (&parentIndex_component,
(void **) &hierarchy->parentIndex, new_max);
for (uint32_t i = 0; i < hierarchy->type->num_components; i++) {
Component_ResizeArray (&hierarchy->type->components[i],
&hierarchy->components[i], new_max);
if (hierarchy->type) {
for (uint32_t i = 0; i < hierarchy->type->num_components; i++) {
Component_ResizeArray (&hierarchy->type->components[i],
&hierarchy->components[i], new_max);
}
}
hierarchy->max_objects = new_max;
}
@ -118,10 +120,12 @@ hierarchy_open (hierarchy_t *hierarchy, uint32_t index, uint32_t count)
hierarchy->childIndex, dstIndex, index, count);
Component_MoveElements (&parentIndex_component,
hierarchy->parentIndex, dstIndex, index, count);
for (uint32_t i = 0; i < hierarchy->type->num_components; i++) {
Component_MoveElements (&hierarchy->type->components[i],
hierarchy->components[i],
dstIndex, index, count);
if (hierarchy->type) {
for (uint32_t i = 0; i < hierarchy->type->num_components; i++) {
Component_MoveElements (&hierarchy->type->components[i],
hierarchy->components[i],
dstIndex, index, count);
}
}
}
@ -142,10 +146,12 @@ hierarchy_close (hierarchy_t *hierarchy, uint32_t index, uint32_t count)
hierarchy->childIndex, index, srcIndex, count);
Component_MoveElements (&parentIndex_component,
hierarchy->parentIndex, index, srcIndex, count);
for (uint32_t i = 0; i < hierarchy->type->num_components; i++) {
Component_MoveElements (&hierarchy->type->components[i],
hierarchy->components[i],
index, srcIndex, count);
if (hierarchy->type) {
for (uint32_t i = 0; i < hierarchy->type->num_components; i++) {
Component_MoveElements (&hierarchy->type->components[i],
hierarchy->components[i],
index, srcIndex, count);
}
}
}
@ -169,10 +175,12 @@ hierarchy_move (hierarchy_t *dst, const hierarchy_t *src,
ref->hierarchy = dst;
ref->index = dstIndex + i;
}
for (uint32_t i = 0; i < dst->type->num_components; i++) {
Component_CopyElements (&dst->type->components[i],
dst->components[i], dstIndex,
src->components[i], srcIndex, count);
if (dst->type) {
for (uint32_t i = 0; i < dst->type->num_components; i++) {
Component_CopyElements (&dst->type->components[i],
dst->components[i], dstIndex,
src->components[i], srcIndex, count);
}
}
}
@ -187,9 +195,11 @@ hierarchy_init (hierarchy_t *dst, uint32_t index,
dst->childCount[index + i] = 0;
dst->childIndex[index + i] = childIndex;
}
for (uint32_t i = 0; i < dst->type->num_components; i++) {
Component_CreateElements (&dst->type->components[i],
dst->components[i], index, count);
if (dst->type) {
for (uint32_t i = 0; i < dst->type->num_components; i++) {
Component_CreateElements (&dst->type->components[i],
dst->components[i], index, count);
}
}
}
@ -344,9 +354,12 @@ Hierarchy_New (ecs_registry_t *reg, const hierarchy_type_t *type,
hierarchy_t *hierarchy = PR_RESNEW (reg->hierarchies);
hierarchy->reg = reg;
hierarchy->components = 0;
hierarchy->type = type;
hierarchy->components = calloc (hierarchy->type->num_components,
sizeof (void *));
if (type) {
hierarchy->components = calloc (hierarchy->type->num_components,
sizeof (void *));
}
if (createRoot) {
hierarchy_open (hierarchy, 0, 1);
@ -363,10 +376,12 @@ Hierarchy_Delete (hierarchy_t *hierarchy)
free (hierarchy->childCount);
free (hierarchy->childIndex);
free (hierarchy->parentIndex);
for (uint32_t i = 0; i < hierarchy->type->num_components; i++) {
free (hierarchy->components[i]);
if (hierarchy->type) {
for (uint32_t i = 0; i < hierarchy->type->num_components; i++) {
free (hierarchy->components[i]);
}
free (hierarchy->components);
}
free (hierarchy->components);
ecs_registry_t *reg = hierarchy->reg;
PR_RESFREE (reg->hierarchies, hierarchy);
@ -395,10 +410,12 @@ Hierarchy_Copy (ecs_registry_t *dstReg, const hierarchy_t *src)
dst->childIndex, 0, src->childIndex, 0, count);
Component_CopyElements (&parentIndex_component,
dst->parentIndex, 0, src->parentIndex, 0, count);
for (uint32_t i = 0; i < dst->type->num_components; i++) {
Component_CopyElements (&dst->type->components[i],
dst->components[i], 0,
src->components[i], 0, count);
if (dst->type) {
for (uint32_t i = 0; i < dst->type->num_components; i++) {
Component_CopyElements (&dst->type->components[i],
dst->components[i], 0,
src->components[i], 0, count);
}
}
return dst;
}

View File

@ -1,5 +1,6 @@
libs_ecs_tests = \
libs/ecs/test/test-components \
libs/ecs/test/test-hierarchy \
libs/ecs/test/test-registry
TESTS += $(libs_ecs_tests)
@ -17,6 +18,13 @@ libs_ecs_test_test_components_LDADD= \
libs_ecs_test_test_components_DEPENDENCIES= \
$(libs_ecs_test_libs)
libs_ecs_test_test_hierarchy_SOURCES= \
libs/ecs/test/test-hierarchy.c
libs_ecs_test_test_hierarchy_LDADD= \
$(libs_ecs_test_libs)
libs_ecs_test_test_hierarchy_DEPENDENCIES= \
$(libs_ecs_test_libs)
libs_ecs_test_test_registry_SOURCES= \
libs/ecs/test/test-registry.c
libs_ecs_test_test_registry_LDADD= \

View File

@ -0,0 +1,477 @@
#ifdef HAVE_CONFIG_H
# include "config.h"
#endif
#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include "QF/ecs/component.h"
#include "QF/ecs/hierarchy.h"
enum {
test_href,
test_name,
test_num_components
};
static const component_t test_components[] = {
[test_href] = {
.size = sizeof (hierref_t),
.create = 0,//create_href,
.name = "href",
},
[test_name] = {
.size = sizeof (const char *),
.name = "name",
},
};
ecs_registry_t *test_reg;
static int
check_hierarchy_size (hierarchy_t *h, uint32_t size)
{
if (h->num_objects != size) {
printf ("hierarchy does not have exactly %u transform\n", size);
return 0;
}
ecs_registry_t *reg = h->reg;
for (uint32_t i = 0; i < h->num_objects; i++) {
hierref_t *ref = Ent_GetComponent (h->ent[i], test_href, reg);
char **name = Ent_GetComponent (h->ent[i], test_name, reg);;
if (ref->hierarchy != h) {
printf ("transform %d (%s) does not point to hierarchy\n",
i, *name);
}
}
return 1;
}
static void
dump_hierarchy (hierarchy_t *h)
{
ecs_registry_t *reg = h->reg;
for (uint32_t i = 0; i < h->num_objects; i++) {
hierref_t *ref = Ent_GetComponent (h->ent[i], test_href, reg);
char **name = Ent_GetComponent (h->ent[i], test_name, reg);;
printf ("%2d: %5s %2u %2u %2u %2u %2u\n", i, *name, h->ent[i],
ref->index, h->parentIndex[i],
h->childIndex[i], h->childCount[i]);
}
puts ("");
}
static int
check_indices (uint32_t ent, uint32_t index, uint32_t parentIndex,
uint32_t childIndex, uint32_t childCount)
{
ecs_registry_t *reg = test_reg;
char **entname = Ent_GetComponent (ent, test_name, reg);;
hierref_t *ref = Ent_GetComponent (ent, test_href, reg);
hierarchy_t *h = ref->hierarchy;
if (ref->index != index) {
char **name = Ent_GetComponent (h->ent[index], test_name, reg);;
printf ("%s/%s index incorrect: expect %u got %u\n",
*entname, *name,
index, ref->index);
return 0;
}
if (h->parentIndex[index] != parentIndex) {
printf ("%s parent index incorrect: expect %u got %u\n",
*entname, parentIndex, h->parentIndex[index]);
return 0;
}
if (h->childIndex[index] != childIndex) {
printf ("%s child index incorrect: expect %u got %u\n",
*entname, childIndex, h->childIndex[index]);
return 0;
}
if (h->childCount[index] != childCount) {
printf ("%s child count incorrect: expect %u got %u\n",
*entname, childCount, h->childCount[index]);
return 0;
}
return 1;
}
static uint32_t
create_ent (uint32_t parent, const char *name)
{
uint32_t ent = ECS_NewEntity (test_reg);
Ent_SetComponent (ent, test_name, test_reg, &name);
hierref_t *ref = Ent_AddComponent (ent, test_href, test_reg);
if (parent != nullent) {
hierref_t *pref = Ent_GetComponent (parent, test_href, test_reg);
ref->hierarchy = pref->hierarchy;
ref->index = Hierarchy_InsertHierarchy (pref->hierarchy, 0,
pref->index, 0);
} else {
ref->hierarchy = Hierarchy_New (test_reg, 0, 1);
ref->index = 0;
}
ref->hierarchy->ent[ref->index] = ent;
return ent;
}
static void
set_parent (uint32_t child, uint32_t parent)
{
if (parent != nullent) {
hierref_t *pref = Ent_GetComponent (parent, test_href, test_reg);
hierref_t *cref = Ent_GetComponent (child, test_href, test_reg);
Hierarchy_SetParent (pref->hierarchy, pref->index,
cref->hierarchy, cref->index);
} else {
hierref_t *cref = Ent_GetComponent (child, test_href, test_reg);
Hierarchy_SetParent (0, nullent, cref->hierarchy, cref->index);
}
}
static int
test_single_transform (void)
{
uint32_t ent = create_ent (nullent, "test");
hierarchy_t *h;
if (ent == nullent) {
printf ("create_ent returned null\n");
return 1;
}
hierref_t *ref = Ent_GetComponent (ent, test_href, test_reg);
if (!ref) {
printf ("Ent_GetComponent(test_href) returned null\n");
return 1;
}
if (!(h = ref->hierarchy)) {
printf ("New entity has no hierarchy\n");
return 1;
}
if (!check_hierarchy_size (h, 1)) { return 1; }
if (!check_indices (ent, 0, nullent, 1, 0)) { return 1; }
// Delete the hierarchy directly as setparent isn't fully tested
Hierarchy_Delete (h);
return 0;
}
static int
test_parent_child_init (void)
{
uint32_t parent = create_ent (nullent, "parent");
uint32_t child = create_ent (parent, "child");
hierref_t *pref = Ent_GetComponent (parent, test_href, test_reg);
hierref_t *cref = Ent_GetComponent (child, test_href, test_reg);
if (pref->hierarchy != cref->hierarchy) {
printf ("parent and child transforms have separate hierarchies\n");
return 1;
}
hierarchy_t *h = pref->hierarchy;
if (!check_hierarchy_size (h, 2)) { return 1; }
if (!check_indices (parent, 0, nullent, 1, 1)) { return 1; }
if (!check_indices (child, 1, 0, 2, 0)) { return 1; }
// Delete the hierarchy directly as setparent isn't fully tested
Hierarchy_Delete (h);
return 0;
}
static int
test_parent_child_setparent (void)
{
uint32_t parent = create_ent (nullent, "parent");
uint32_t child = create_ent (nullent, "child");
if (!check_indices (parent, 0, nullent, 1, 0)) { return 1; }
if (!check_indices (child, 0, nullent, 1, 0)) { return 1; }
hierref_t *pref = Ent_GetComponent (parent, test_href, test_reg);
hierref_t *cref = Ent_GetComponent (child, test_href, test_reg);
if (pref->hierarchy == cref->hierarchy) {
printf ("parent and child entities have same hierarchy before"
" set paret\n");
return 1;
}
set_parent (child, parent);
if (pref->hierarchy != cref->hierarchy) {
printf ("parent and child transforms have separate hierarchies\n");
return 1;
}
hierarchy_t *h = pref->hierarchy;
if (!check_hierarchy_size (h, 2)) { return 1; }
if (!check_indices (parent, 0, nullent, 1, 1)) { return 1; }
if (!check_indices (child, 1, 0, 2, 0)) { return 1; }
// Delete the hierarchy directly as setparent isn't fully tested
Hierarchy_Delete (h);
return 0;
}
static int
test_build_hierarchy (void)
{
printf ("test_build_hierarchy\n");
uint32_t root = create_ent (nullent, "root");
uint32_t A = create_ent (root, "A");
uint32_t B = create_ent (root, "B");
uint32_t C = create_ent (root, "C");
hierref_t *ref = Ent_GetComponent (root, test_href, test_reg);
if (!check_indices (root, 0, nullent, 1, 3)) { return 1; }
if (!check_indices (A, 1, 0, 4, 0)) { return 1; }
if (!check_indices (B, 2, 0, 4, 0)) { return 1; }
if (!check_indices (C, 3, 0, 4, 0)) { return 1; }
uint32_t B1 = create_ent (B, "B1");
if (!check_indices (root, 0, nullent, 1, 3)) { return 1; }
if (!check_indices ( A, 1, 0, 4, 0)) { return 1; }
if (!check_indices ( B, 2, 0, 4, 1)) { return 1; }
if (!check_indices ( C, 3, 0, 5, 0)) { return 1; }
if (!check_indices (B1, 4, 2, 5, 0)) { return 1; }
uint32_t A1 = create_ent (A, "A1");
if (!check_indices (root, 0, nullent, 1, 3)) { return 1; }
if (!check_indices ( A, 1, 0, 4, 1)) { return 1; }
if (!check_indices ( B, 2, 0, 5, 1)) { return 1; }
if (!check_indices ( C, 3, 0, 6, 0)) { return 1; }
if (!check_indices (A1, 4, 1, 6, 0)) { return 1; }
if (!check_indices (B1, 5, 2, 6, 0)) { return 1; }
uint32_t A1a = create_ent (A1, "A1a");
uint32_t B2 = create_ent (B, "B2");
uint32_t A2 = create_ent (A, "A2");
uint32_t B3 = create_ent (B, "B3");
uint32_t B2a = create_ent (B2, "B2a");
if (!check_hierarchy_size (ref->hierarchy, 11)) { return 1; }
if (!check_indices (root, 0, nullent, 1, 3)) { return 1; }
if (!check_indices ( A, 1, 0, 4, 2)) { return 1; }
if (!check_indices ( B, 2, 0, 6, 3)) { return 1; }
if (!check_indices ( C, 3, 0, 9, 0)) { return 1; }
if (!check_indices ( A1, 4, 1, 9, 1)) { return 1; }
if (!check_indices ( A2, 5, 1, 10, 0)) { return 1; }
if (!check_indices ( B1, 6, 2, 10, 0)) { return 1; }
if (!check_indices ( B2, 7, 2, 10, 1)) { return 1; }
if (!check_indices ( B3, 8, 2, 11, 0)) { return 1; }
if (!check_indices (A1a, 9, 4, 11, 0)) { return 1; }
if (!check_indices (B2a, 10, 7, 11, 0)) { return 1; }
uint32_t D = create_ent (root, "D");
if (!check_hierarchy_size (ref->hierarchy, 12)) { return 1; }
if (!check_indices (root, 0, nullent, 1, 4)) { return 1; }
if (!check_indices ( A, 1, 0, 5, 2)) { return 1; }
if (!check_indices ( B, 2, 0, 7, 3)) { return 1; }
if (!check_indices ( C, 3, 0, 10, 0)) { return 1; }
if (!check_indices ( D, 4, 0, 10, 0)) { return 1; }
if (!check_indices ( A1, 5, 1, 10, 1)) { return 1; }
if (!check_indices ( A2, 6, 1, 11, 0)) { return 1; }
if (!check_indices ( B1, 7, 2, 11, 0)) { return 1; }
if (!check_indices ( B2, 8, 2, 11, 1)) { return 1; }
if (!check_indices ( B3, 9, 2, 12, 0)) { return 1; }
if (!check_indices (A1a, 10, 5, 12, 0)) { return 1; }
if (!check_indices (B2a, 11, 8, 12, 0)) { return 1; }
dump_hierarchy (ref->hierarchy);
uint32_t C1 = create_ent (C, "C1");
dump_hierarchy (ref->hierarchy);
if (!check_hierarchy_size (ref->hierarchy, 13)) { return 1; }
if (!check_indices (root, 0, nullent, 1, 4)) { return 1; }
if (!check_indices ( A, 1, 0, 5, 2)) { return 1; }
if (!check_indices ( B, 2, 0, 7, 3)) { return 1; }
if (!check_indices ( C, 3, 0, 10, 1)) { return 1; }
if (!check_indices ( D, 4, 0, 11, 0)) { return 1; }
if (!check_indices ( A1, 5, 1, 11, 1)) { return 1; }
if (!check_indices ( A2, 6, 1, 12, 0)) { return 1; }
if (!check_indices ( B1, 7, 2, 12, 0)) { return 1; }
if (!check_indices ( B2, 8, 2, 12, 1)) { return 1; }
if (!check_indices ( B3, 9, 2, 13, 0)) { return 1; }
if (!check_indices ( C1, 10, 3, 13, 0)) { return 1; }
if (!check_indices (A1a, 11, 5, 13, 0)) { return 1; }
if (!check_indices (B2a, 12, 8, 13, 0)) { return 1; }
// Delete the hierarchy directly as setparent isn't fully tested
Hierarchy_Delete (ref->hierarchy);
return 0;
}
static int
test_build_hierarchy2 (void)
{
printf ("test_build_hierarchy2\n");
uint32_t root = create_ent (nullent, "root");
uint32_t A = create_ent (root, "A");
uint32_t B = create_ent (root, "B");
uint32_t C = create_ent (root, "C");
uint32_t B1 = create_ent (B, "B1");
uint32_t A1 = create_ent (A, "A1");
uint32_t A1a = create_ent (A1, "A1a");
uint32_t B2 = create_ent (B, "B2");
uint32_t A2 = create_ent (A, "A2");
uint32_t B3 = create_ent (B, "B3");
uint32_t B2a = create_ent (B2, "B2a");
uint32_t D = create_ent (root, "D");
uint32_t C1 = create_ent (C, "C1");
hierref_t *ref = Ent_GetComponent (root, test_href, test_reg);
if (!check_hierarchy_size (ref->hierarchy, 13)) { return 1; }
if (!check_indices (root, 0, nullent, 1, 4)) { return 1; }
if (!check_indices ( A, 1, 0, 5, 2)) { return 1; }
if (!check_indices ( B, 2, 0, 7, 3)) { return 1; }
if (!check_indices ( C, 3, 0, 10, 1)) { return 1; }
if (!check_indices ( D, 4, 0, 11, 0)) { return 1; }
if (!check_indices ( A1, 5, 1, 11, 1)) { return 1; }
if (!check_indices ( A2, 6, 1, 12, 0)) { return 1; }
if (!check_indices ( B1, 7, 2, 12, 0)) { return 1; }
if (!check_indices ( B2, 8, 2, 12, 1)) { return 1; }
if (!check_indices ( B3, 9, 2, 13, 0)) { return 1; }
if (!check_indices ( C1, 10, 3, 13, 0)) { return 1; }
if (!check_indices (A1a, 11, 5, 13, 0)) { return 1; }
if (!check_indices (B2a, 12, 8, 13, 0)) { return 1; }
uint32_t T = create_ent (nullent, "T");
uint32_t X = create_ent (T, "X");
uint32_t Y = create_ent (T, "Y");
uint32_t Z = create_ent (T, "Z");
uint32_t Y1 = create_ent (Y, "Y1");
uint32_t X1 = create_ent (X, "X1");
uint32_t X1a = create_ent (X1, "X1a");
uint32_t Y2 = create_ent (Y, "Y2");
uint32_t X2 = create_ent (X, "X2");
uint32_t Y3 = create_ent (Y, "Y3");
uint32_t Y2a = create_ent (Y2, "Y2a");
uint32_t Z1 = create_ent (Z, "Z1");
hierref_t *Tref = Ent_GetComponent (T, test_href, test_reg);
dump_hierarchy (Tref->hierarchy);
if (!check_hierarchy_size (Tref->hierarchy, 12)) { return 1; }
if (!check_indices ( T, 0, nullent, 1, 3)) { return 1; }
if (!check_indices ( X, 1, 0, 4, 2)) { return 1; }
if (!check_indices ( Y, 2, 0, 6, 3)) { return 1; }
if (!check_indices ( Z, 3, 0, 9, 1)) { return 1; }
if (!check_indices ( X1, 4, 1, 10, 1)) { return 1; }
if (!check_indices ( X2, 5, 1, 11, 0)) { return 1; }
if (!check_indices ( Y1, 6, 2, 11, 0)) { return 1; }
if (!check_indices ( Y2, 7, 2, 11, 1)) { return 1; }
if (!check_indices ( Y3, 8, 2, 12, 0)) { return 1; }
if (!check_indices ( Z1, 9, 3, 12, 0)) { return 1; }
if (!check_indices (X1a, 10, 4, 12, 0)) { return 1; }
if (!check_indices (Y2a, 11, 7, 12, 0)) { return 1; }
set_parent (T, B);
dump_hierarchy (ref->hierarchy);
if (!check_hierarchy_size (ref->hierarchy, 25)) { return 1; }
if (!check_indices (root, 0, nullent, 1, 4)) { return 1; }
if (!check_indices ( A, 1, 0, 5, 2)) { return 1; }
if (!check_indices ( B, 2, 0, 7, 4)) { return 1; }
if (!check_indices ( C, 3, 0, 11, 1)) { return 1; }
if (!check_indices ( D, 4, 0, 12, 0)) { return 1; }
if (!check_indices ( A1, 5, 1, 12, 1)) { return 1; }
if (!check_indices ( A2, 6, 1, 13, 0)) { return 1; }
if (!check_indices ( B1, 7, 2, 13, 0)) { return 1; }
if (!check_indices ( B2, 8, 2, 13, 1)) { return 1; }
if (!check_indices ( B3, 9, 2, 14, 0)) { return 1; }
if (!check_indices ( T, 10, 2, 14, 3)) { return 1; }
if (!check_indices ( C1, 11, 3, 17, 0)) { return 1; }
if (!check_indices (A1a, 12, 5, 17, 0)) { return 1; }
if (!check_indices (B2a, 13, 8, 17, 0)) { return 1; }
if (!check_indices ( X, 14, 10, 17, 2)) { return 1; }
if (!check_indices ( Y, 15, 10, 19, 3)) { return 1; }
if (!check_indices ( Z, 16, 10, 22, 1)) { return 1; }
if (!check_indices ( X1, 17, 14, 23, 1)) { return 1; }
if (!check_indices ( X2, 18, 14, 24, 0)) { return 1; }
if (!check_indices ( Y1, 19, 15, 24, 0)) { return 1; }
if (!check_indices ( Y2, 20, 15, 24, 1)) { return 1; }
if (!check_indices ( Y3, 21, 15, 25, 0)) { return 1; }
if (!check_indices ( Z1, 22, 16, 25, 0)) { return 1; }
if (!check_indices (X1a, 23, 17, 25, 0)) { return 1; }
if (!check_indices (Y2a, 24, 20, 25, 0)) { return 1; }
set_parent (Y, nullent);
dump_hierarchy (ref->hierarchy);
hierref_t *Yref = Ent_GetComponent (Y, test_href, test_reg);
dump_hierarchy (Yref->hierarchy);
if (!check_hierarchy_size (ref->hierarchy, 20)) { return 1; }
if (!check_hierarchy_size (Yref->hierarchy, 5)) { return 1; }
if (!check_indices (root, 0, nullent, 1, 4)) { return 1; }
if (!check_indices ( A, 1, 0, 5, 2)) { return 1; }
if (!check_indices ( B, 2, 0, 7, 4)) { return 1; }
if (!check_indices ( C, 3, 0, 11, 1)) { return 1; }
if (!check_indices ( D, 4, 0, 12, 0)) { return 1; }
if (!check_indices ( A1, 5, 1, 12, 1)) { return 1; }
if (!check_indices ( A2, 6, 1, 13, 0)) { return 1; }
if (!check_indices ( B1, 7, 2, 13, 0)) { return 1; }
if (!check_indices ( B2, 8, 2, 13, 1)) { return 1; }
if (!check_indices ( B3, 9, 2, 14, 0)) { return 1; }
if (!check_indices ( T, 10, 2, 14, 3)) { return 1; }
if (!check_indices ( C1, 11, 3, 17, 0)) { return 1; }
if (!check_indices (A1a, 12, 5, 17, 0)) { return 1; }
if (!check_indices (B2a, 13, 8, 17, 0)) { return 1; }
if (!check_indices ( X, 14, 10, 16, 2)) { return 1; }
if (!check_indices ( Z, 15, 10, 18, 1)) { return 1; }
if (!check_indices ( X1, 16, 14, 19, 1)) { return 1; }
if (!check_indices ( X2, 17, 14, 20, 0)) { return 1; }
if (!check_indices ( Z1, 18, 15, 20, 0)) { return 1; }
if (!check_indices (X1a, 19, 16, 20, 0)) { return 1; }
if (!check_indices ( Y, 0, nullent, 1, 3)) { return 1; }
if (!check_indices ( Y1, 1, 0, 4, 0)) { return 1; }
if (!check_indices ( Y2, 2, 0, 4, 1)) { return 1; }
if (!check_indices ( Y3, 3, 0, 5, 0)) { return 1; }
if (!check_indices (Y2a, 4, 2, 5, 0)) { return 1; }
// Delete the hierarchy directly as setparent isn't fully tested
Hierarchy_Delete (ref->hierarchy);
Hierarchy_Delete (Yref->hierarchy);
return 0;
}
int
main (void)
{
test_reg = ECS_NewRegistry ();
ECS_RegisterComponents (test_reg, test_components, test_num_components);
test_reg->href_comp = test_href;
if (test_single_transform ()) { return 1; }
if (test_parent_child_init ()) { return 1; }
if (test_parent_child_setparent ()) { return 1; }
if (test_build_hierarchy ()) { return 1; }
if (test_build_hierarchy2 ()) { return 1; }
ECS_DelRegistry (test_reg);
return 0;
}

View File

@ -1,5 +1,5 @@
libs_scene_tests = \
libs/scene/test/test-hierarchy
libs/scene/test/test-transform
TESTS += $(libs_scene_tests)
@ -10,9 +10,9 @@ libs_scene_test_libs= \
libs/ecs/libQFecs.la \
libs/util/libQFutil.la
libs_scene_test_test_hierarchy_SOURCES= \
libs/scene/test/test-hierarchy.c
libs_scene_test_test_hierarchy_LDADD= \
libs_scene_test_test_transform_SOURCES= \
libs/scene/test/test-transform.c
libs_scene_test_test_transform_LDADD= \
$(libs_scene_test_libs)
libs_scene_test_test_hierarchy_DEPENDENCIES= \
libs_scene_test_test_transform_DEPENDENCIES= \
$(libs_scene_test_libs)

View File

@ -61,21 +61,6 @@ check_hierarchy_size (transform_t t, uint32_t size)
return 1;
}
static void
dump_hierarchy (transform_t t)
{
hierarchy_t *h = Transform_GetRef (t)->hierarchy;
char **name = h->components[transform_type_name];
ecs_registry_t *reg = h->reg;
for (uint32_t i = 0; i < h->num_objects; i++) {
hierref_t *ref = Ent_GetComponent (h->ent[i], scene_href, reg);
printf ("%2d: %5s %2u %2u %2u %2u %2u\n", i, name[i], h->ent[i],
ref->index, h->parentIndex[i],
h->childIndex[i], h->childCount[i]);
}
puts ("");
}
static int
check_indices (transform_t transform, uint32_t index, uint32_t parentIndex,
uint32_t childIndex, uint32_t childCount)
@ -285,236 +270,6 @@ test_parent_child_setparent (void)
return 0;
}
static int
test_build_hierarchy (void)
{
printf ("test_build_hierarchy\n");
transform_t root = Transform_NewNamed (reg, (transform_t) {}, "root");
transform_t A = Transform_NewNamed (reg, root, "A");
transform_t B = Transform_NewNamed (reg, root, "B");
transform_t C = Transform_NewNamed (reg, root, "C");
if (!check_indices (root, 0, nullent, 1, 3)) { return 1; }
if (!check_indices (A, 1, 0, 4, 0)) { return 1; }
if (!check_indices (B, 2, 0, 4, 0)) { return 1; }
if (!check_indices (C, 3, 0, 4, 0)) { return 1; }
transform_t B1 = Transform_NewNamed (reg, B, "B1");
if (!check_indices (root, 0, nullent, 1, 3)) { return 1; }
if (!check_indices ( A, 1, 0, 4, 0)) { return 1; }
if (!check_indices ( B, 2, 0, 4, 1)) { return 1; }
if (!check_indices ( C, 3, 0, 5, 0)) { return 1; }
if (!check_indices (B1, 4, 2, 5, 0)) { return 1; }
transform_t A1 = Transform_NewNamed (reg, A, "A1");
if (!check_indices (root, 0, nullent, 1, 3)) { return 1; }
if (!check_indices ( A, 1, 0, 4, 1)) { return 1; }
if (!check_indices ( B, 2, 0, 5, 1)) { return 1; }
if (!check_indices ( C, 3, 0, 6, 0)) { return 1; }
if (!check_indices (A1, 4, 1, 6, 0)) { return 1; }
if (!check_indices (B1, 5, 2, 6, 0)) { return 1; }
transform_t A1a = Transform_NewNamed (reg, A1, "A1a");
transform_t B2 = Transform_NewNamed (reg, B, "B2");
transform_t A2 = Transform_NewNamed (reg, A, "A2");
transform_t B3 = Transform_NewNamed (reg, B, "B3");
transform_t B2a = Transform_NewNamed (reg, B2, "B2a");
if (!check_hierarchy_size (root, 11)) { return 1; }
if (!check_indices (root, 0, nullent, 1, 3)) { return 1; }
if (!check_indices ( A, 1, 0, 4, 2)) { return 1; }
if (!check_indices ( B, 2, 0, 6, 3)) { return 1; }
if (!check_indices ( C, 3, 0, 9, 0)) { return 1; }
if (!check_indices ( A1, 4, 1, 9, 1)) { return 1; }
if (!check_indices ( A2, 5, 1, 10, 0)) { return 1; }
if (!check_indices ( B1, 6, 2, 10, 0)) { return 1; }
if (!check_indices ( B2, 7, 2, 10, 1)) { return 1; }
if (!check_indices ( B3, 8, 2, 11, 0)) { return 1; }
if (!check_indices (A1a, 9, 4, 11, 0)) { return 1; }
if (!check_indices (B2a, 10, 7, 11, 0)) { return 1; }
transform_t D = Transform_NewNamed (reg, root, "D");
if (!check_hierarchy_size (root, 12)) { return 1; }
if (!check_indices (root, 0, nullent, 1, 4)) { return 1; }
if (!check_indices ( A, 1, 0, 5, 2)) { return 1; }
if (!check_indices ( B, 2, 0, 7, 3)) { return 1; }
if (!check_indices ( C, 3, 0, 10, 0)) { return 1; }
if (!check_indices ( D, 4, 0, 10, 0)) { return 1; }
if (!check_indices ( A1, 5, 1, 10, 1)) { return 1; }
if (!check_indices ( A2, 6, 1, 11, 0)) { return 1; }
if (!check_indices ( B1, 7, 2, 11, 0)) { return 1; }
if (!check_indices ( B2, 8, 2, 11, 1)) { return 1; }
if (!check_indices ( B3, 9, 2, 12, 0)) { return 1; }
if (!check_indices (A1a, 10, 5, 12, 0)) { return 1; }
if (!check_indices (B2a, 11, 8, 12, 0)) { return 1; }
dump_hierarchy (root);
transform_t C1 = Transform_NewNamed (reg, C, "C1");
dump_hierarchy (root);
if (!check_hierarchy_size (root, 13)) { return 1; }
if (!check_indices (root, 0, nullent, 1, 4)) { return 1; }
if (!check_indices ( A, 1, 0, 5, 2)) { return 1; }
if (!check_indices ( B, 2, 0, 7, 3)) { return 1; }
if (!check_indices ( C, 3, 0, 10, 1)) { return 1; }
if (!check_indices ( D, 4, 0, 11, 0)) { return 1; }
if (!check_indices ( A1, 5, 1, 11, 1)) { return 1; }
if (!check_indices ( A2, 6, 1, 12, 0)) { return 1; }
if (!check_indices ( B1, 7, 2, 12, 0)) { return 1; }
if (!check_indices ( B2, 8, 2, 12, 1)) { return 1; }
if (!check_indices ( B3, 9, 2, 13, 0)) { return 1; }
if (!check_indices ( C1, 10, 3, 13, 0)) { return 1; }
if (!check_indices (A1a, 11, 5, 13, 0)) { return 1; }
if (!check_indices (B2a, 12, 8, 13, 0)) { return 1; }
// Delete the hierarchy directly as setparent isn't fully tested
Hierarchy_Delete (Transform_GetRef (root)->hierarchy);
return 0;
}
static int
test_build_hierarchy2 (void)
{
printf ("test_build_hierarchy2\n");
transform_t root = Transform_NewNamed (reg, (transform_t) {}, "root");
transform_t A = Transform_NewNamed (reg, root, "A");
transform_t B = Transform_NewNamed (reg, root, "B");
transform_t C = Transform_NewNamed (reg, root, "C");
transform_t B1 = Transform_NewNamed (reg, B, "B1");
transform_t A1 = Transform_NewNamed (reg, A, "A1");
transform_t A1a = Transform_NewNamed (reg, A1, "A1a");
transform_t B2 = Transform_NewNamed (reg, B, "B2");
transform_t A2 = Transform_NewNamed (reg, A, "A2");
transform_t B3 = Transform_NewNamed (reg, B, "B3");
transform_t B2a = Transform_NewNamed (reg, B2, "B2a");
transform_t D = Transform_NewNamed (reg, root, "D");
transform_t C1 = Transform_NewNamed (reg, C, "C1");
if (!check_hierarchy_size (root, 13)) { return 1; }
if (!check_indices (root, 0, nullent, 1, 4)) { return 1; }
if (!check_indices ( A, 1, 0, 5, 2)) { return 1; }
if (!check_indices ( B, 2, 0, 7, 3)) { return 1; }
if (!check_indices ( C, 3, 0, 10, 1)) { return 1; }
if (!check_indices ( D, 4, 0, 11, 0)) { return 1; }
if (!check_indices ( A1, 5, 1, 11, 1)) { return 1; }
if (!check_indices ( A2, 6, 1, 12, 0)) { return 1; }
if (!check_indices ( B1, 7, 2, 12, 0)) { return 1; }
if (!check_indices ( B2, 8, 2, 12, 1)) { return 1; }
if (!check_indices ( B3, 9, 2, 13, 0)) { return 1; }
if (!check_indices ( C1, 10, 3, 13, 0)) { return 1; }
if (!check_indices (A1a, 11, 5, 13, 0)) { return 1; }
if (!check_indices (B2a, 12, 8, 13, 0)) { return 1; }
transform_t T = Transform_NewNamed (reg, (transform_t) {}, "T");
transform_t X = Transform_NewNamed (reg, T, "X");
transform_t Y = Transform_NewNamed (reg, T, "Y");
transform_t Z = Transform_NewNamed (reg, T, "Z");
transform_t Y1 = Transform_NewNamed (reg, Y, "Y1");
transform_t X1 = Transform_NewNamed (reg, X, "X1");
transform_t X1a = Transform_NewNamed (reg, X1, "X1a");
transform_t Y2 = Transform_NewNamed (reg, Y, "Y2");
transform_t X2 = Transform_NewNamed (reg, X, "X2");
transform_t Y3 = Transform_NewNamed (reg, Y, "Y3");
transform_t Y2a = Transform_NewNamed (reg, Y2, "Y2a");
transform_t Z1 = Transform_NewNamed (reg, Z, "Z1");
dump_hierarchy (T);
if (!check_hierarchy_size (T, 12)) { return 1; }
if (!check_indices ( T, 0, nullent, 1, 3)) { return 1; }
if (!check_indices ( X, 1, 0, 4, 2)) { return 1; }
if (!check_indices ( Y, 2, 0, 6, 3)) { return 1; }
if (!check_indices ( Z, 3, 0, 9, 1)) { return 1; }
if (!check_indices ( X1, 4, 1, 10, 1)) { return 1; }
if (!check_indices ( X2, 5, 1, 11, 0)) { return 1; }
if (!check_indices ( Y1, 6, 2, 11, 0)) { return 1; }
if (!check_indices ( Y2, 7, 2, 11, 1)) { return 1; }
if (!check_indices ( Y3, 8, 2, 12, 0)) { return 1; }
if (!check_indices ( Z1, 9, 3, 12, 0)) { return 1; }
if (!check_indices (X1a, 10, 4, 12, 0)) { return 1; }
if (!check_indices (Y2a, 11, 7, 12, 0)) { return 1; }
Transform_SetParent (T, B);
dump_hierarchy (root);
if (!check_hierarchy_size (root, 25)) { return 1; }
if (!check_indices (root, 0, nullent, 1, 4)) { return 1; }
if (!check_indices ( A, 1, 0, 5, 2)) { return 1; }
if (!check_indices ( B, 2, 0, 7, 4)) { return 1; }
if (!check_indices ( C, 3, 0, 11, 1)) { return 1; }
if (!check_indices ( D, 4, 0, 12, 0)) { return 1; }
if (!check_indices ( A1, 5, 1, 12, 1)) { return 1; }
if (!check_indices ( A2, 6, 1, 13, 0)) { return 1; }
if (!check_indices ( B1, 7, 2, 13, 0)) { return 1; }
if (!check_indices ( B2, 8, 2, 13, 1)) { return 1; }
if (!check_indices ( B3, 9, 2, 14, 0)) { return 1; }
if (!check_indices ( T, 10, 2, 14, 3)) { return 1; }
if (!check_indices ( C1, 11, 3, 17, 0)) { return 1; }
if (!check_indices (A1a, 12, 5, 17, 0)) { return 1; }
if (!check_indices (B2a, 13, 8, 17, 0)) { return 1; }
if (!check_indices ( X, 14, 10, 17, 2)) { return 1; }
if (!check_indices ( Y, 15, 10, 19, 3)) { return 1; }
if (!check_indices ( Z, 16, 10, 22, 1)) { return 1; }
if (!check_indices ( X1, 17, 14, 23, 1)) { return 1; }
if (!check_indices ( X2, 18, 14, 24, 0)) { return 1; }
if (!check_indices ( Y1, 19, 15, 24, 0)) { return 1; }
if (!check_indices ( Y2, 20, 15, 24, 1)) { return 1; }
if (!check_indices ( Y3, 21, 15, 25, 0)) { return 1; }
if (!check_indices ( Z1, 22, 16, 25, 0)) { return 1; }
if (!check_indices (X1a, 23, 17, 25, 0)) { return 1; }
if (!check_indices (Y2a, 24, 20, 25, 0)) { return 1; }
Transform_SetParent (Y, (transform_t) {});
dump_hierarchy (root);
dump_hierarchy (Y);
if (!check_hierarchy_size (root, 20)) { return 1; }
if (!check_hierarchy_size (Y, 5)) { return 1; }
if (!check_indices (root, 0, nullent, 1, 4)) { return 1; }
if (!check_indices ( A, 1, 0, 5, 2)) { return 1; }
if (!check_indices ( B, 2, 0, 7, 4)) { return 1; }
if (!check_indices ( C, 3, 0, 11, 1)) { return 1; }
if (!check_indices ( D, 4, 0, 12, 0)) { return 1; }
if (!check_indices ( A1, 5, 1, 12, 1)) { return 1; }
if (!check_indices ( A2, 6, 1, 13, 0)) { return 1; }
if (!check_indices ( B1, 7, 2, 13, 0)) { return 1; }
if (!check_indices ( B2, 8, 2, 13, 1)) { return 1; }
if (!check_indices ( B3, 9, 2, 14, 0)) { return 1; }
if (!check_indices ( T, 10, 2, 14, 3)) { return 1; }
if (!check_indices ( C1, 11, 3, 17, 0)) { return 1; }
if (!check_indices (A1a, 12, 5, 17, 0)) { return 1; }
if (!check_indices (B2a, 13, 8, 17, 0)) { return 1; }
if (!check_indices ( X, 14, 10, 16, 2)) { return 1; }
if (!check_indices ( Z, 15, 10, 18, 1)) { return 1; }
if (!check_indices ( X1, 16, 14, 19, 1)) { return 1; }
if (!check_indices ( X2, 17, 14, 20, 0)) { return 1; }
if (!check_indices ( Z1, 18, 15, 20, 0)) { return 1; }
if (!check_indices (X1a, 19, 16, 20, 0)) { return 1; }
if (!check_indices ( Y, 0, nullent, 1, 3)) { return 1; }
if (!check_indices ( Y1, 1, 0, 4, 0)) { return 1; }
if (!check_indices ( Y2, 2, 0, 4, 1)) { return 1; }
if (!check_indices ( Y3, 3, 0, 5, 0)) { return 1; }
if (!check_indices (Y2a, 4, 2, 5, 0)) { return 1; }
// Delete the hierarchy directly as setparent isn't fully tested
Hierarchy_Delete (Transform_GetRef (root)->hierarchy);
Hierarchy_Delete (Transform_GetRef (Y)->hierarchy);
return 0;
}
static int
check_vector (transform_t transform,
vec4f_t (*func) (transform_t t),
@ -733,8 +488,6 @@ main (void)
if (test_single_transform ()) { return 1; }
if (test_parent_child_init ()) { return 1; }
if (test_parent_child_setparent ()) { return 1; }
if (test_build_hierarchy ()) { return 1; }
if (test_build_hierarchy2 ()) { return 1; }
if (test_frames ()) { return 1; }
Scene_DeleteScene (scene);