From 10037927eaa892276dbae10c96d0b78452461c35 Mon Sep 17 00:00:00 2001 From: Bill Currie Date: Sat, 5 Nov 2022 21:26:47 +0900 Subject: [PATCH] [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. --- libs/ecs/hierarchy.c | 71 ++- libs/ecs/test/Makemodule.am | 8 + libs/ecs/test/test-hierarchy.c | 477 ++++++++++++++++++ libs/scene/test/Makemodule.am | 10 +- .../{test-hierarchy.c => test-transform.c} | 247 --------- 5 files changed, 534 insertions(+), 279 deletions(-) create mode 100644 libs/ecs/test/test-hierarchy.c rename libs/scene/test/{test-hierarchy.c => test-transform.c} (59%) diff --git a/libs/ecs/hierarchy.c b/libs/ecs/hierarchy.c index cc5f0705e..dd35aed04 100644 --- a/libs/ecs/hierarchy.c +++ b/libs/ecs/hierarchy.c @@ -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; } diff --git a/libs/ecs/test/Makemodule.am b/libs/ecs/test/Makemodule.am index 6c3e6bd8f..9d3479561 100644 --- a/libs/ecs/test/Makemodule.am +++ b/libs/ecs/test/Makemodule.am @@ -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= \ diff --git a/libs/ecs/test/test-hierarchy.c b/libs/ecs/test/test-hierarchy.c new file mode 100644 index 000000000..7ceb1cb7c --- /dev/null +++ b/libs/ecs/test/test-hierarchy.c @@ -0,0 +1,477 @@ +#ifdef HAVE_CONFIG_H +# include "config.h" +#endif + +#include +#include +#include + +#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; +} diff --git a/libs/scene/test/Makemodule.am b/libs/scene/test/Makemodule.am index 4f5e71533..d1074ed13 100644 --- a/libs/scene/test/Makemodule.am +++ b/libs/scene/test/Makemodule.am @@ -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) diff --git a/libs/scene/test/test-hierarchy.c b/libs/scene/test/test-transform.c similarity index 59% rename from libs/scene/test/test-hierarchy.c rename to libs/scene/test/test-transform.c index 026a8394d..6311bb4a8 100644 --- a/libs/scene/test/test-hierarchy.c +++ b/libs/scene/test/test-transform.c @@ -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);