mirror of
https://git.code.sf.net/p/quake/quakeforge
synced 2025-02-24 20:51:35 +00:00
[ui] Add a canvas reference component
It's used for finding the entity that has the actual canvas component attached. Useful for sharing a single canvas between multiple view hierarchies, and worked as a proof of concept for doing similar with hierarchy references, and might work for properly destroying canvas items (fills etc) when a view entity is deleted (if attached to every view).
This commit is contained in:
parent
9a74fb0a14
commit
6b2bd02b14
2 changed files with 53 additions and 21 deletions
|
@ -52,9 +52,11 @@ enum {
|
||||||
|
|
||||||
// last so deleting an entity removes the grouped components first
|
// last so deleting an entity removes the grouped components first
|
||||||
// also, does not have a subpool
|
// also, does not have a subpool
|
||||||
canvas_canvas,
|
canvas_canvasref, // reference to entity with canvas
|
||||||
|
canvas_canvas, // actual canvas object
|
||||||
|
|
||||||
canvas_comp_count
|
canvas_comp_count,
|
||||||
|
canvas_subpool_count = canvas_canvasref
|
||||||
};
|
};
|
||||||
|
|
||||||
typedef struct canvas_s {
|
typedef struct canvas_s {
|
||||||
|
@ -99,6 +101,9 @@ void Canvas_SortComponentPool (canvas_system_t canvas_sys, uint32_t ent,
|
||||||
void Canvas_SetLen (canvas_system_t canvas_sys, uint32_t ent, view_pos_t len);
|
void Canvas_SetLen (canvas_system_t canvas_sys, uint32_t ent, view_pos_t len);
|
||||||
CANVASINLINE view_t Canvas_GetRootView (canvas_system_t canvas_sys,
|
CANVASINLINE view_t Canvas_GetRootView (canvas_system_t canvas_sys,
|
||||||
uint32_t ent);
|
uint32_t ent);
|
||||||
|
CANVASINLINE uint32_t Canvas_Entity (canvas_system_t canvas_sys, uint32_t ent);
|
||||||
|
CANVASINLINE void Canvas_SetReference (canvas_system_t canvas_sys,
|
||||||
|
uint32_t ent, uint32_t ref);
|
||||||
CANVASINLINE bool *Canvas_Visible (canvas_system_t canvas_sys, uint32_t ent);
|
CANVASINLINE bool *Canvas_Visible (canvas_system_t canvas_sys, uint32_t ent);
|
||||||
CANVASINLINE int32_t *Canvas_DrawGroup (canvas_system_t canvas_sys,
|
CANVASINLINE int32_t *Canvas_DrawGroup (canvas_system_t canvas_sys,
|
||||||
uint32_t ent);
|
uint32_t ent);
|
||||||
|
@ -121,6 +126,23 @@ Canvas_GetRootView (canvas_system_t canvas_sys, uint32_t ent)
|
||||||
return View_FromEntity (viewsys, ent);
|
return View_FromEntity (viewsys, ent);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
CANVASINLINE
|
||||||
|
uint32_t
|
||||||
|
Canvas_Entity (canvas_system_t canvas_sys, uint32_t ent)
|
||||||
|
{
|
||||||
|
uint32_t rcomp = canvas_sys.base + canvas_canvasref;
|
||||||
|
return *(uint32_t *) Ent_GetComponent (ent, rcomp, canvas_sys.reg);
|
||||||
|
}
|
||||||
|
|
||||||
|
CANVASINLINE
|
||||||
|
void
|
||||||
|
Canvas_SetReference (canvas_system_t canvas_sys, uint32_t ent, uint32_t ref)
|
||||||
|
{
|
||||||
|
uint32_t rcomp = canvas_sys.base + canvas_canvasref;
|
||||||
|
Ent_SetComponent (ent, rcomp, canvas_sys.reg, &ref);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
CANVASINLINE
|
CANVASINLINE
|
||||||
bool *
|
bool *
|
||||||
Canvas_Visible (canvas_system_t canvas_sys, uint32_t ent)
|
Canvas_Visible (canvas_system_t canvas_sys, uint32_t ent)
|
||||||
|
|
|
@ -42,13 +42,15 @@
|
||||||
static uint32_t
|
static uint32_t
|
||||||
_canvas_rangeid (ecs_registry_t *reg, uint32_t ent, uint32_t comp, uint32_t c)
|
_canvas_rangeid (ecs_registry_t *reg, uint32_t ent, uint32_t comp, uint32_t c)
|
||||||
{
|
{
|
||||||
comp += canvas_canvas - c;
|
uint32_t rcomp = comp - c + canvas_canvasref;
|
||||||
|
uint32_t ccomp = comp - c + canvas_canvas;
|
||||||
// view components come immediately after canvas components
|
// view components come immediately after canvas components
|
||||||
uint32_t vcomp = view_href + comp + canvas_comp_count - canvas_canvas;
|
uint32_t vcomp = view_href + canvas_comp_count + comp - c;
|
||||||
hierref_t *href = Ent_GetComponent (ent, vcomp, reg);
|
hierref_t *href = Ent_GetComponent (ent, vcomp, reg);
|
||||||
// the root entity of the hierarchy has the canvas component
|
// the root entity of the hierarchy has the canvasref or canvas component
|
||||||
uint32_t cent = href->hierarchy->ent[0];
|
uint32_t cent = href->hierarchy->ent[0];
|
||||||
canvas_t *canvas = Ent_GetComponent (cent, comp, reg);
|
cent = *(uint32_t *) Ent_GetComponent (cent, rcomp, reg);
|
||||||
|
canvas_t *canvas = Ent_GetComponent (cent, ccomp, reg);
|
||||||
return canvas->range[c];
|
return canvas->range[c];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -79,7 +81,7 @@ canvas_canvas_destroy (void *_canvas)
|
||||||
{
|
{
|
||||||
canvas_t *canvas = _canvas;
|
canvas_t *canvas = _canvas;
|
||||||
auto reg = canvas->reg;
|
auto reg = canvas->reg;
|
||||||
for (uint32_t i = 0; i < canvas_canvas; i++) {
|
for (uint32_t i = 0; i < canvas_subpool_count; i++) {
|
||||||
ECS_DelSubpoolRange (reg, canvas->base + i, canvas->range[i]);
|
ECS_DelSubpoolRange (reg, canvas->base + i, canvas->range[i]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -155,6 +157,11 @@ const component_t canvas_components[canvas_comp_count] = {
|
||||||
.name = "outline",
|
.name = "outline",
|
||||||
.rangeid = canvas_outline_rangeid,
|
.rangeid = canvas_outline_rangeid,
|
||||||
},
|
},
|
||||||
|
|
||||||
|
[canvas_canvasref] = {
|
||||||
|
.size = sizeof (uint32_t),
|
||||||
|
.name = "canvasref",
|
||||||
|
},
|
||||||
[canvas_canvas] = {
|
[canvas_canvas] = {
|
||||||
.size = sizeof (canvas_t),
|
.size = sizeof (canvas_t),
|
||||||
.name = "canvas",
|
.name = "canvas",
|
||||||
|
@ -162,6 +169,9 @@ const component_t canvas_components[canvas_comp_count] = {
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
|
#define c_canvasref (canvas_sys.base + canvas_canvasref)
|
||||||
|
#define c_canvas (canvas_sys.base + canvas_canvas)
|
||||||
|
|
||||||
typedef void (*canvas_sysfunc_f) (canvas_system_t *canvas_sys,
|
typedef void (*canvas_sysfunc_f) (canvas_system_t *canvas_sys,
|
||||||
ecs_pool_t *pool, ecs_range_t range);
|
ecs_pool_t *pool, ecs_range_t range);
|
||||||
static void
|
static void
|
||||||
|
@ -471,8 +481,7 @@ Canvas_Draw (canvas_system_t canvas_sys)
|
||||||
};
|
};
|
||||||
|
|
||||||
auto reg = canvas_sys.reg;
|
auto reg = canvas_sys.reg;
|
||||||
uint32_t comp = canvas_sys.base + canvas_canvas;
|
ecs_pool_t *canvas_pool = ®->comp_pools[c_canvas];
|
||||||
ecs_pool_t *canvas_pool = ®->comp_pools[comp];
|
|
||||||
uint32_t count = canvas_pool->count;
|
uint32_t count = canvas_pool->count;
|
||||||
uint32_t *entities = canvas_pool->dense;
|
uint32_t *entities = canvas_pool->dense;
|
||||||
__auto_type canvases = (canvas_t *) canvas_pool->data;
|
__auto_type canvases = (canvas_t *) canvas_pool->data;
|
||||||
|
@ -535,15 +544,19 @@ Canvas_AddToEntity (canvas_system_t canvas_sys, uint32_t ent)
|
||||||
.base = canvas_sys.base,
|
.base = canvas_sys.base,
|
||||||
.visible = true
|
.visible = true
|
||||||
};
|
};
|
||||||
for (uint32_t i = 0; i < canvas_canvas; i++) {
|
for (uint32_t i = 0; i < canvas_subpool_count; i++) {
|
||||||
canvas.range[i] = ECS_NewSubpoolRange (canvas_sys.reg,
|
canvas.range[i] = ECS_NewSubpoolRange (canvas_sys.reg,
|
||||||
canvas_sys.base + i);
|
canvas_sys.base + i);
|
||||||
}
|
}
|
||||||
Ent_SetComponent (ent, canvas_sys.base + canvas_canvas, canvas_sys.reg,
|
// add a self reference to keep _canvas_rangeid and Canvas_Entity simple
|
||||||
&canvas);
|
Ent_SetComponent (ent, c_canvasref, canvas_sys.reg, &ent);
|
||||||
View_AddToEntity (ent,
|
Ent_SetComponent (ent, c_canvas, canvas_sys.reg, &canvas);
|
||||||
(ecs_system_t) { canvas_sys.reg, canvas_sys.view_base },
|
if (!Ent_HasComponent (ent, canvas_sys.view_base + view_href,
|
||||||
nullview);
|
canvas_sys.reg)) {
|
||||||
|
View_AddToEntity (ent, (ecs_system_t) { canvas_sys.reg,
|
||||||
|
canvas_sys.view_base },
|
||||||
|
nullview);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
uint32_t
|
uint32_t
|
||||||
|
@ -575,8 +588,7 @@ void
|
||||||
Canvas_SortComponentPool (canvas_system_t canvas_sys, uint32_t ent,
|
Canvas_SortComponentPool (canvas_system_t canvas_sys, uint32_t ent,
|
||||||
uint32_t component)
|
uint32_t component)
|
||||||
{
|
{
|
||||||
canvas_t *canvas = Ent_GetComponent (ent, canvas_sys.base + canvas_canvas,
|
canvas_t *canvas = Ent_GetComponent (ent, c_canvas, canvas_sys.reg);
|
||||||
canvas_sys.reg);
|
|
||||||
uint32_t rid = canvas->range[component];
|
uint32_t rid = canvas->range[component];
|
||||||
uint32_t c = component + canvas_sys.base;
|
uint32_t c = component + canvas_sys.base;
|
||||||
ecs_range_t range = ECS_GetSubpoolRange (canvas_sys.reg, c, rid);
|
ecs_range_t range = ECS_GetSubpoolRange (canvas_sys.reg, c, rid);
|
||||||
|
@ -597,9 +609,8 @@ canvas_draw_cmp (const void *_a, const void *_b, void *arg)
|
||||||
{
|
{
|
||||||
uint32_t enta = *(const uint32_t *)_a;
|
uint32_t enta = *(const uint32_t *)_a;
|
||||||
uint32_t entb = *(const uint32_t *)_b;
|
uint32_t entb = *(const uint32_t *)_b;
|
||||||
canvas_system_t *canvas_sys = arg;
|
auto canvas_sys = *(canvas_system_t *)arg;
|
||||||
auto reg = canvas_sys->reg;
|
auto reg = canvas_sys.reg;
|
||||||
uint32_t c_canvas = canvas_sys->base + canvas_canvas;
|
|
||||||
auto canvasa = (canvas_t *) Ent_GetComponent (enta, c_canvas, reg);
|
auto canvasa = (canvas_t *) Ent_GetComponent (enta, c_canvas, reg);
|
||||||
auto canvasb = (canvas_t *) Ent_GetComponent (entb, c_canvas, reg);
|
auto canvasb = (canvas_t *) Ent_GetComponent (entb, c_canvas, reg);
|
||||||
int diff = canvasa->draw_group - canvasb->draw_group;
|
int diff = canvasa->draw_group - canvasb->draw_group;
|
||||||
|
@ -618,6 +629,5 @@ void
|
||||||
Canvas_DrawSort (canvas_system_t canvas_sys)
|
Canvas_DrawSort (canvas_system_t canvas_sys)
|
||||||
{
|
{
|
||||||
auto reg = canvas_sys.reg;
|
auto reg = canvas_sys.reg;
|
||||||
uint32_t c_canvas = canvas_sys.base + canvas_canvas;
|
|
||||||
ECS_SortComponentPool (reg, c_canvas, canvas_draw_cmp, &canvas_sys);
|
ECS_SortComponentPool (reg, c_canvas, canvas_draw_cmp, &canvas_sys);
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue