[ecs] Fix parent index updates when removing sub-hierarchies

In the end, it was removal of the old entries that corrupted the parent
indices. Very nicely, most of the fixes involved removing code. Taking
advantage of the ECS to debug the hierarchies was fun, and the resulting
colorized entity names helped no end.
This commit is contained in:
Bill Currie 2022-11-06 23:04:40 +09:00
parent 5ce0f4735c
commit ddd6c958a9
2 changed files with 57 additions and 20 deletions

View file

@ -320,14 +320,7 @@ hierarchy_remove_children (hierarchy_t *hierarchy, uint32_t index)
{
uint32_t childIndex = hierarchy->childIndex[index];
uint32_t childCount = hierarchy->childCount[index];
uint32_t parentIndex = hierarchy->parentIndex[index];
uint32_t nieceIndex = nullent;
if (parentIndex != nullent) {
uint32_t siblingIndex = hierarchy->childIndex[parentIndex];
siblingIndex += hierarchy->childCount[parentIndex] - 1;
nieceIndex = hierarchy->childIndex[siblingIndex];
}
for (uint32_t i = childCount; i-- > 0; ) {
hierarchy_remove_children (hierarchy, childIndex + i);
}
@ -337,16 +330,15 @@ hierarchy_remove_children (hierarchy_t *hierarchy, uint32_t index)
if (childCount) {
hierarchy_UpdateTransformIndices (hierarchy, childIndex, -childCount);
hierarchy_UpdateChildIndices (hierarchy, index, -childCount);
if (nieceIndex != nullent) {
hierarchy_UpdateParentIndices (hierarchy, nieceIndex, -childCount);
}
}
if (childIndex < hierarchy->num_objects) {
hierarchy_UpdateParentIndices (hierarchy, childIndex, -1);
}
}
void
Hierarchy_RemoveHierarchy (hierarchy_t *hierarchy, uint32_t index)
{
uint32_t childIndex = hierarchy->childIndex[index];
uint32_t parentIndex = hierarchy->parentIndex[index];
hierarchy_remove_children (hierarchy, index);
@ -357,7 +349,6 @@ Hierarchy_RemoveHierarchy (hierarchy_t *hierarchy, uint32_t index)
hierarchy_UpdateChildIndices (hierarchy, parentIndex + 1, -1);
hierarchy->childCount[parentIndex] -= 1;
}
hierarchy_UpdateParentIndices (hierarchy, childIndex - 1, -1);
}
hierarchy_t *
@ -404,7 +395,6 @@ hierarchy_t *
Hierarchy_Copy (ecs_registry_t *dstReg, const hierarchy_t *src)
{
uint32_t href = dstReg->href_comp;
//ecs_registry_t *srcReg = src->reg;
hierarchy_t *dst = Hierarchy_New (dstReg, src->type, 0);
size_t count = src->num_objects;

View file

@ -12,6 +12,7 @@
enum {
test_href,
test_name,
test_highlight,
test_num_components
};
@ -26,6 +27,10 @@ static const component_t test_components[] = {
.size = sizeof (const char *),
.name = "name",
},
[test_highlight] = {
.size = sizeof (byte),
.name = "highlight",
},
};
ecs_registry_t *test_reg;
@ -113,6 +118,25 @@ entity_color (hierarchy_t *h, uint32_t i)
return h->ent[i] == nullent ? MAG : DFL;
}
static const char *
highlight_color (hierarchy_t *h, uint32_t i)
{
uint32_t ent = h->ent[i];
if (ECS_EntValid (ent, test_reg)
&& Ent_HasComponent (ent, test_highlight, test_reg)) {
static char color_str[] = "\e[3.;4.m";
byte *color = Ent_GetComponent (ent, test_highlight, test_reg);
if (*color) {
byte fg = *color & 0x0f;
byte bg = *color >> 4;
color_str[3] = fg < 8 ? '0' + fg : '9';
color_str[6] = bg < 8 ? '0' + bg : '9';
return color_str;
}
}
return "";
}
static void
dump_hierarchy (hierarchy_t *h)
{
@ -130,13 +154,13 @@ dump_hierarchy (hierarchy_t *h)
name = Ent_GetComponent (h->ent[i], test_name, reg);
}
}
printf ("%2d: %s%2d %s%2d %s%2d %s%2d %s%2d"DFL" %s\n", i,
printf ("%2d: %s%2d %s%2d %s%2d %s%2d %s%2d"DFL" %s%s"DFL"\n", i,
ref_index_color (i, rind), rind,
parent_index_color (h, i), h->parentIndex[i],
child_index_color (h, i), h->childIndex[i],
child_count_color (h, i), h->childCount[i],
entity_color (h, i), h->ent[i],
*name);
highlight_color (h, i), *name);
}
puts ("");
}
@ -159,12 +183,12 @@ dump_tree (hierarchy_t *h, uint32_t ind, int level)
&& Ent_HasComponent (h->ent[ind], test_name, reg)) {
name = Ent_GetComponent (h->ent[ind], test_name, reg);;
}
printf ("%2d: %s%2d %s%2d %s%2d %s%2d"DFL"|%*s%s\n", ind,
printf ("%2d: %s%2d %s%2d %s%2d %s%2d"DFL"|%*s%s%s"DFL"\n", ind,
parent_index_color (h, ind), h->parentIndex[ind],
child_index_color (h, ind), h->childIndex[ind],
child_count_color (h, ind), h->childCount[ind],
entity_color (h, ind), h->ent[ind],
level * 3, "", *name);
level * 3, "", highlight_color (h, ind), *name);
if (h->childIndex[ind] > ind) {
for (uint32_t i = 0; i < h->childCount[ind]; i++) {
@ -232,6 +256,12 @@ create_ent (uint32_t parent, const char *name)
return ent;
}
static void
highlight_ent (uint32_t ent, byte color)
{
Ent_SetComponent (ent, test_highlight, test_reg, &color);
}
static void
set_parent (uint32_t child, uint32_t parent)
{
@ -722,7 +752,7 @@ test_build_hierarchy4 (void)
uint32_t main_i_i4 = create_ent (main_i_i, "main_i_i4");
uint32_t main_i_a = create_ent (main_i, "main_i_a");
uint32_t main_i_a_w = create_ent (main_i_a, "main_i_a_w");
uint32_t main_i_a_w4 = create_ent (main_i_a_w, "main_i_a_w4");
uint32_t main_i_a_w7 = create_ent (main_i_a_w, "main_i_a_w7");
uint32_t main_i_a_ma = create_ent (main_i_a, "main_i_a_ma");
uint32_t main_i_a_ma4 = create_ent (main_i_a_ma, "main_i_a_ma4");
uint32_t main_sb = create_ent (main, "main_sb");
@ -742,6 +772,23 @@ test_build_hierarchy4 (void)
uint32_t main_S_a = create_ent (main_S, "main_S_a");
uint32_t main_S_a_n = create_ent (main_S_a, "main_S_a_n");
highlight_ent (main_i_a, 0x06);
highlight_ent (main_i_a_w, 0x05);
highlight_ent (main_i_a_ma, 0x05);
highlight_ent (main_i_a_w7, 0x02);
highlight_ent (main_i_a_ma4, 0x02);
highlight_ent (main_sb_a, 0x03);
highlight_ent (main_sb_h, 0x03);
highlight_ent (main_sb_A, 0x03);
highlight_ent (main_S_a, 0x03);
highlight_ent (main_i_f_b, 0x03);
highlight_ent (main_sb_a4, 0x01);
highlight_ent (main_sb_h3, 0x01);
highlight_ent (main_sb_A4, 0x01);
highlight_ent (main_S_a_n, 0x01);
highlight_ent (main_i_f_b4, 0x01);
hierref_t *ref = Ent_GetComponent (hud, test_href, test_reg);
dump_hierarchy (ref->hierarchy);
dump_tree (ref->hierarchy, 0, 0);
@ -783,7 +830,7 @@ test_build_hierarchy4 (void)
if (!check_indices (main_sb_A4, 32, 19, 37, 0)) { return 1; }
if (!check_indices (main_S_a_n, 33, 23, 37, 0)) { return 1; }
if (!check_indices (main_i_f_b4, 34, 25, 37, 0)) { return 1; }
if (!check_indices (main_i_a_w4, 35, 28, 37, 0)) { return 1; }
if (!check_indices (main_i_a_w7, 35, 28, 37, 0)) { return 1; }
if (!check_indices (main_i_a_ma4, 36, 29, 37, 0)) { return 1; }
set_parent (main_i_a, hud);
@ -816,7 +863,7 @@ test_build_hierarchy4 (void)
if (!check_indices (main_S_s, 23, 10, 35, 0)) { return 1; }
if (!check_indices (main_S_t, 24, 10, 35, 0)) { return 1; }
if (!check_indices (main_S_a, 25, 10, 35, 1)) { return 1; }
if (!check_indices (main_i_a_w4, 26, 11, 36, 0)) { return 1; }
if (!check_indices (main_i_a_w7, 26, 11, 36, 0)) { return 1; }
if (!check_indices (main_i_a_ma4, 27, 12, 36, 0)) { return 1; }
if (!check_indices (main_mf_b7, 28, 14, 36, 0)) { return 1; }
if (!check_indices (main_i_f_b, 29, 15, 36, 1)) { return 1; }