mirror of
https://git.code.sf.net/p/quake/quakeforge
synced 2025-02-24 12:42:32 +00:00
[ecs] Make hierarchy ownership of entities optional
I'm not sure this is what I want.
This commit is contained in:
parent
292e4ca132
commit
60c22e8fda
9 changed files with 63 additions and 20 deletions
|
@ -54,6 +54,7 @@ typedef struct hierarchy_s {
|
|||
uint32_t num_objects;
|
||||
uint32_t max_objects;
|
||||
uint32_t *ent;
|
||||
uint8_t *own;
|
||||
uint32_t *childCount;
|
||||
uint32_t *childIndex;
|
||||
uint32_t *parentIndex;
|
||||
|
|
|
@ -140,7 +140,8 @@ typedef void (*view_move_f) (view_t view, view_pos_t abs);
|
|||
|
||||
VIEWINLINE view_t View_FromEntity (ecs_system_t viewsys, uint32_t ent);
|
||||
view_t View_New (ecs_system_t viewsys, view_t parent);
|
||||
view_t View_AddToEntity (uint32_t ent, ecs_system_t viewsys, view_t parent);
|
||||
view_t View_AddToEntity (uint32_t ent, ecs_system_t viewsys, view_t parent,
|
||||
bool own);
|
||||
VIEWINLINE void View_Delete (view_t view);
|
||||
void View_SetParent (view_t view, view_t parent);
|
||||
void View_UpdateHierarchy (view_t view);
|
||||
|
|
|
@ -40,6 +40,7 @@
|
|||
#include "QF/ecs.h"
|
||||
|
||||
static component_t ent_component = { .size = sizeof (uint32_t) };
|
||||
static component_t own_component = { .size = sizeof (uint8_t) };
|
||||
static component_t childCount_component = { .size = sizeof (uint32_t) };
|
||||
static component_t childIndex_component = { .size = sizeof (uint32_t) };
|
||||
static component_t parentIndex_component = { .size = sizeof (uint32_t) };
|
||||
|
@ -77,6 +78,20 @@ hierarchy_InvalidateReferences (hierarchy_t *hierarchy, uint32_t start,
|
|||
}
|
||||
}
|
||||
|
||||
static void
|
||||
hierarchy_remove_reference (hierarchy_t *hierarchy, uint32_t index)
|
||||
{
|
||||
uint32_t ent = hierarchy->ent[index];
|
||||
uint32_t href = hierarchy->href_comp;
|
||||
auto reg = hierarchy->reg;
|
||||
if (ECS_EntValid (ent, reg) && Ent_HasComponent (ent, href, reg)) {
|
||||
hierref_t *ref = Ent_GetComponent (ent, href, reg);
|
||||
ref->id = nullent;
|
||||
ref->index = nullindex;
|
||||
Ent_RemoveComponent (ent, href, reg);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
hierarchy_UpdateChildIndices (hierarchy_t *hierarchy, uint32_t start,
|
||||
int offset)
|
||||
|
@ -105,6 +120,8 @@ Hierarchy_Reserve (hierarchy_t *hierarchy, uint32_t count)
|
|||
|
||||
Component_ResizeArray (&ent_component,
|
||||
(void **) &hierarchy->ent, new_max);
|
||||
Component_ResizeArray (&own_component,
|
||||
(void **) &hierarchy->own, new_max);
|
||||
Component_ResizeArray (&childCount_component,
|
||||
(void **) &hierarchy->childCount, new_max);
|
||||
Component_ResizeArray (&childIndex_component,
|
||||
|
@ -139,6 +156,8 @@ hierarchy_open (hierarchy_t *hierarchy, uint32_t index, uint32_t count)
|
|||
}
|
||||
Component_MoveElements (&ent_component,
|
||||
hierarchy->ent, dstIndex, index, count);
|
||||
Component_MoveElements (&own_component,
|
||||
hierarchy->own, dstIndex, index, count);
|
||||
Component_MoveElements (&childCount_component,
|
||||
hierarchy->childCount, dstIndex, index, count);
|
||||
Component_MoveElements (&childIndex_component,
|
||||
|
@ -169,6 +188,8 @@ hierarchy_close (hierarchy_t *hierarchy, uint32_t index, uint32_t count)
|
|||
count = hierarchy->num_objects - index;
|
||||
Component_MoveElements (&ent_component,
|
||||
hierarchy->ent, index, srcIndex, count);
|
||||
Component_MoveElements (&own_component,
|
||||
hierarchy->own, index, srcIndex, count);
|
||||
Component_MoveElements (&childCount_component,
|
||||
hierarchy->childCount, index, srcIndex, count);
|
||||
Component_MoveElements (&childIndex_component,
|
||||
|
@ -197,10 +218,14 @@ hierarchy_move (hierarchy_t *dst, uint32_t dstid, const hierarchy_t *src,
|
|||
Component_CopyElements (&ent_component,
|
||||
dst->ent, dstIndex,
|
||||
src->ent, srcIndex, count);
|
||||
Component_CopyElements (&own_component,
|
||||
dst->own, dstIndex,
|
||||
src->own, srcIndex, count);
|
||||
// Actually move (as in C++ move semantics) source hierarchy object
|
||||
// references so that their indices do not get updated when the objects
|
||||
// are removed from the source hierarchy
|
||||
memset (&src->ent[srcIndex], nullent, count * sizeof(dst->ent[0]));
|
||||
memset (&src->own[srcIndex], false, count * sizeof(dst->own[0]));
|
||||
|
||||
for (uint32_t i = 0; i < count; i++) {
|
||||
if (dst->ent[dstIndex + i] != nullent) {
|
||||
|
@ -223,7 +248,8 @@ static void
|
|||
hierarchy_init (hierarchy_t *dst, uint32_t index,
|
||||
uint32_t parentIndex, uint32_t childIndex, uint32_t count)
|
||||
{
|
||||
memset (&dst->ent[index], nullent, count * sizeof(uint32_t));
|
||||
memset (&dst->ent[index], nullent, count * sizeof(dst->ent[0]));
|
||||
memset (&dst->own[index], false, count * sizeof(dst->own[0]));
|
||||
|
||||
for (uint32_t i = 0; i < count; i++) {
|
||||
dst->parentIndex[index + i] = parentIndex;
|
||||
|
@ -428,7 +454,11 @@ hierarchy_remove_children (hierarchy_t *hierarchy, uint32_t index,
|
|||
if (delEntities) {
|
||||
hierarchy_InvalidateReferences (hierarchy, childIndex, childCount);
|
||||
for (uint32_t i = 0; i < childCount; i++) {
|
||||
ECS_DelEntity (hierarchy->reg, hierarchy->ent[childIndex + i]);
|
||||
if (hierarchy->own[childIndex + i]) {
|
||||
ECS_DelEntity (hierarchy->reg, hierarchy->ent[childIndex + i]);
|
||||
} else {
|
||||
hierarchy_remove_reference (hierarchy, childIndex + i);
|
||||
}
|
||||
}
|
||||
}
|
||||
hierarchy_close (hierarchy, childIndex, childCount);
|
||||
|
@ -455,7 +485,11 @@ Hierarchy_RemoveHierarchy (hierarchy_t *hierarchy, uint32_t index,
|
|||
hierarchy_remove_children (hierarchy, index, delEntities);
|
||||
if (delEntities) {
|
||||
hierarchy_InvalidateReferences (hierarchy, index, 1);
|
||||
ECS_DelEntity (hierarchy->reg, hierarchy->ent[index]);
|
||||
if (hierarchy->own[index]) {
|
||||
ECS_DelEntity (hierarchy->reg, hierarchy->ent[index]);
|
||||
} else {
|
||||
hierarchy_remove_reference (hierarchy, index);
|
||||
}
|
||||
}
|
||||
hierarchy_close (hierarchy, index, 1);
|
||||
|
||||
|
@ -477,11 +511,8 @@ Hierarchy_Create (hierarchy_t *hierarchy)
|
|||
static void
|
||||
hierarchy_destroy (hierarchy_t *hierarchy)
|
||||
{
|
||||
hierarchy_InvalidateReferences (hierarchy, 0, hierarchy->num_objects);
|
||||
for (uint32_t i = 0; i < hierarchy->num_objects; i++) {
|
||||
ECS_DelEntity (hierarchy->reg, hierarchy->ent[i]);
|
||||
}
|
||||
free (hierarchy->ent);
|
||||
free (hierarchy->own);
|
||||
free (hierarchy->childCount);
|
||||
free (hierarchy->childIndex);
|
||||
free (hierarchy->parentIndex);
|
||||
|
@ -544,6 +575,7 @@ copy_one_node (hierarchy_t *dst, const hierarchy_t *src,
|
|||
dst->childIndex[dstIndex] = childIndex;
|
||||
dst->childCount[dstIndex] = childCount;
|
||||
dst->ent[dstIndex] = src->ent[srcIndex];
|
||||
dst->own[dstIndex] = src->own[srcIndex];
|
||||
if (dst->type) {
|
||||
for (uint32_t i = 0; i < dst->type->num_components; i++) {
|
||||
Component_CopyElements (&dst->type->components[i],
|
||||
|
@ -645,6 +677,7 @@ Hierarchy_SetTreeMode (hierarchy_t *hierarchy, bool tree_mode)
|
|||
}
|
||||
|
||||
swap_pointers (&tmp.ent, &src->ent);
|
||||
swap_pointers (&tmp.own, &src->own);
|
||||
swap_pointers (&tmp.childCount, &src->childCount);
|
||||
swap_pointers (&tmp.childIndex, &src->childIndex);
|
||||
swap_pointers (&tmp.parentIndex, &src->parentIndex);
|
||||
|
@ -678,6 +711,7 @@ Hierarchy_Copy (ecs_registry_t *dstReg, uint32_t href_comp,
|
|||
.index = i,
|
||||
};
|
||||
Ent_SetComponent (dst->ent[i], href_comp, dstReg, &ref);
|
||||
dst->own[i] = true;
|
||||
}
|
||||
|
||||
Component_CopyElements (&childCount_component,
|
||||
|
|
|
@ -157,7 +157,7 @@ dump_hierarchy (hierref_t href)
|
|||
{
|
||||
hierarchy_t *h = Ent_GetComponent (href.id, ecs_hierarchy, test_reg);
|
||||
ecs_registry_t *reg = h->reg;
|
||||
puts ("in: ri pa ci cc en name");
|
||||
puts ("in: ri pa ci cc en ow name");
|
||||
for (uint32_t i = 0; i < h->num_objects; i++) {
|
||||
uint32_t rind = nullent;
|
||||
static char fake_name[] = ONG "null" DFL;
|
||||
|
@ -170,12 +170,13 @@ dump_hierarchy (hierref_t href)
|
|||
name = Ent_GetComponent (h->ent[i], t_name, reg);
|
||||
}
|
||||
}
|
||||
printf ("%2d: %s%2d %s%2d %s%2d %s%2d %s%2d"DFL" %s%s"DFL"\n", i,
|
||||
printf ("%2d: %s%2d %s%2d %s%2d %s%2d %s%2d"DFL" %2d %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],
|
||||
h->own[i],
|
||||
highlight_color (h, i), *name);
|
||||
}
|
||||
puts ("");
|
||||
|
@ -191,7 +192,7 @@ dump_tree (hierref_t href, int level)
|
|||
return;
|
||||
}
|
||||
if (!level) {
|
||||
puts ("in: pa ci cc en|name");
|
||||
puts ("in: pa ci cc en ow|name");
|
||||
}
|
||||
static char fake_name[] = ONG "null" DFL;
|
||||
static char *fake_nameptr = fake_name;
|
||||
|
@ -201,11 +202,12 @@ dump_tree (hierref_t href, int level)
|
|||
&& Ent_HasComponent (h->ent[ind], t_name, reg)) {
|
||||
name = Ent_GetComponent (h->ent[ind], t_name, reg);;
|
||||
}
|
||||
printf ("%2d: %s%2d %s%2d %s%2d %s%2d"DFL"|%*s%s%s"DFL"\n", ind,
|
||||
printf ("%2d: %s%2d %s%2d %s%2d %s%2d"DFL" %2d|%*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],
|
||||
h->own[ind],
|
||||
level * 3, "", highlight_color (h, ind), *name);
|
||||
|
||||
if (h->childIndex[ind] > ind) {
|
||||
|
@ -274,6 +276,7 @@ create_ent (uint32_t parent, const char *name)
|
|||
}
|
||||
hierarchy_t *h = Ent_GetComponent (ref->id, ecs_hierarchy, test_reg);
|
||||
h->ent[ref->index] = ent;
|
||||
h->own[ref->index] = true;
|
||||
return ent;
|
||||
}
|
||||
|
||||
|
|
|
@ -415,6 +415,7 @@ create_ent (uint32_t parent, const char *name)
|
|||
static void
|
||||
set_tree_mode (hierref_t href, bool tree_mode)
|
||||
{
|
||||
printf ("set_tree_mode: %s\n", tree_mode ? "true" : "false");
|
||||
hierarchy_t *h = Ent_GetComponent (href.id, ecs_hierarchy, test_reg);
|
||||
Hierarchy_SetTreeMode (h, tree_mode);
|
||||
}
|
||||
|
@ -608,8 +609,9 @@ test_build_hierarchy2 (void)
|
|||
if (!check_next_last_indices (*ref)) { return 1; }
|
||||
if (!check_for_loops (*ref)) { return 1; }
|
||||
|
||||
ECS_PrintEntity (test_reg, root);
|
||||
set_tree_mode (*ref, false);
|
||||
puts("set_tree_mode");
|
||||
ECS_PrintEntity (test_reg, root);
|
||||
dump_hierarchy (*ref);
|
||||
dump_tree (*ref, 0);
|
||||
|
||||
|
|
|
@ -556,7 +556,7 @@ Canvas_AddToEntity (canvas_system_t canvas_sys, uint32_t ent)
|
|||
canvas_sys.reg)) {
|
||||
View_AddToEntity (ent, (ecs_system_t) { canvas_sys.reg,
|
||||
canvas_sys.view_base },
|
||||
nullview);
|
||||
nullview, true);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -407,7 +407,7 @@ IMUI_BeginFrame (imui_ctx_t *ctx)
|
|||
|
||||
// delete and recreate the root view (but not the root entity)
|
||||
Ent_RemoveComponent (root_ent, ctx->root_view.comp, ctx->root_view.reg);
|
||||
ctx->root_view = View_AddToEntity (root_ent, ctx->vsys, nullview);
|
||||
ctx->root_view = View_AddToEntity (root_ent, ctx->vsys, nullview, true);
|
||||
set_hierarchy_tree_mode (ctx, View_GetRef (ctx->root_view), true);
|
||||
View_SetLen (ctx->root_view, root_size.x, root_size.y);
|
||||
|
||||
|
|
|
@ -274,7 +274,8 @@ Text_PassageView (text_system_t textsys, view_t parent,
|
|||
}
|
||||
}
|
||||
ecs_system_t viewsys = { reg, textsys.view_base };
|
||||
view_t passage_view = View_AddToEntity (h->ent[0], viewsys, parent);
|
||||
view_t passage_view = View_AddToEntity (h->ent[0], viewsys, parent,
|
||||
false);
|
||||
glyphref_t passage_ref = {};
|
||||
glyphobj_t *glyphs = malloc (glyph_count * sizeof (glyphobj_t));
|
||||
glyphnode_t *g = glyph_nodes;
|
||||
|
@ -283,12 +284,12 @@ Text_PassageView (text_system_t textsys, view_t parent,
|
|||
for (uint32_t i = 0; i < h->childCount[0]; i++) {
|
||||
uint32_t paragraph = h->childIndex[0] + i;
|
||||
view_t paraview = View_AddToEntity (h->ent[paragraph], viewsys,
|
||||
passage_view);
|
||||
passage_view, false);
|
||||
glyphref_t pararef = { .start = passage_ref.count };
|
||||
for (uint32_t j = 0; j < h->childCount[paragraph]; j++, g = g->next) {
|
||||
uint32_t to = h->childIndex[paragraph] + j;
|
||||
view_t textview = View_AddToEntity (h->ent[to], viewsys,
|
||||
paraview);
|
||||
paraview, false);
|
||||
configure_textview (textview, glyphs, g, passage_ref.count,
|
||||
c_glyphs);
|
||||
View_SetGravity (textview, grav_flow);
|
||||
|
|
|
@ -144,7 +144,7 @@ static const hierarchy_type_t view_type = {
|
|||
};
|
||||
|
||||
view_t
|
||||
View_AddToEntity (uint32_t ent, ecs_system_t viewsys, view_t parent)
|
||||
View_AddToEntity (uint32_t ent, ecs_system_t viewsys, view_t parent, bool own)
|
||||
{
|
||||
uint32_t href_comp = viewsys.base + view_href;
|
||||
hierref_t *ref = Ent_AddComponent (ent, href_comp, viewsys.reg);
|
||||
|
@ -158,6 +158,7 @@ View_AddToEntity (uint32_t ent, ecs_system_t viewsys, view_t parent)
|
|||
}
|
||||
hierarchy_t *h = Ent_GetComponent (ref->id, ecs_hierarchy, viewsys.reg);
|
||||
h->ent[ref->index] = ent;
|
||||
h->own[ref->index] = own;
|
||||
return (view_t) { .reg = viewsys.reg, .id = ent, .comp = href_comp };
|
||||
}
|
||||
|
||||
|
@ -165,7 +166,7 @@ view_t
|
|||
View_New (ecs_system_t viewsys, view_t parent)
|
||||
{
|
||||
uint32_t view = ECS_NewEntity (viewsys.reg);
|
||||
return View_AddToEntity (view, viewsys, parent);
|
||||
return View_AddToEntity (view, viewsys, parent, true);
|
||||
}
|
||||
|
||||
void
|
||||
|
|
Loading…
Reference in a new issue