mirror of
https://git.code.sf.net/p/quake/quakeforge
synced 2025-02-20 10:43:29 +00:00
[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:
parent
5ce0f4735c
commit
ddd6c958a9
2 changed files with 57 additions and 20 deletions
|
@ -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;
|
||||
|
||||
|
|
|
@ -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; }
|
||||
|
|
Loading…
Reference in a new issue