[ui] Attach text views to passage entities

Instead of creating new entities for the text views. This approximately
halves the number of entities required to display flowed text, but also
tests the ability to have an entity in multiple hierarchies (the goal of
the ECS component and system changes).
This commit is contained in:
Bill Currie 2022-12-14 22:38:37 +09:00
parent fdc0dba58b
commit 41d25df0d2
17 changed files with 232 additions and 148 deletions

View file

@ -72,15 +72,8 @@ typedef struct glyphset_s {
uint32_t count;
} glyphset_t;
typedef struct text_s {
const char *text;
const char *language;
hb_script_t script;
hb_direction_t direction;
} text_t;
enum {
// covers both view and passage text object hierarcies
// passage text object hierarcies
text_href,
// all the glyphs in a passage. Always on only the root view of the passage.
text_passage_glyphs,
@ -100,6 +93,8 @@ enum {
text_comp_count
};
extern const component_t text_components[text_comp_count];
typedef struct featureset_s DARRAY_TYPE (hb_feature_t) featureset_t;
extern hb_feature_t LigatureOff;
@ -111,14 +106,16 @@ extern hb_feature_t CligOn;
struct font_s;
struct passage_s;
extern struct ecs_registry_s *text_reg;
void Text_Init (void);
struct view_s Text_View (struct font_s *font, struct passage_s *passage);
void Text_SetScript (int textid, const char *lang, hb_script_t script,
text_dir_e dir);
void Text_SetFont (int textid, struct font_s *font);
void Text_SetFeatures (int textid, featureset_t *features);
void Text_AddFeature (int textid, hb_feature_t feature);
struct view_s Text_View (ecs_system_t viewsys,
struct font_s *font, struct passage_s *passage);
void Text_SetScript (ecs_system_t textsys, uint32_t textid,
const char *lang, hb_script_t script, text_dir_e dir);
void Text_SetFont (ecs_system_t textsys, uint32_t textid,
struct font_s *font);
void Text_SetFeatures (ecs_system_t textsys, uint32_t textid,
featureset_t *features);
void Text_AddFeature (ecs_system_t textsys, uint32_t textid,
hb_feature_t feature);
#endif//__QF_ui_text_h

View file

@ -85,6 +85,15 @@ typedef struct viewcont_s {
unsigned flow_size:1; ///< If true, view's size is adjusted to flow.
} viewcont_t;
enum {
view_href,
view_comp_count
};
extern const struct component_s view_components[view_comp_count];
// components in the view hierarchy
enum {
/// Coordinates of view's origin relative to parent's gravity point.
view_pos,
@ -122,7 +131,9 @@ typedef void (*view_move_f) (view_t view, view_pos_t abs);
#define VIEWINLINE GNU89INLINE inline
view_t View_New (ecs_registry_t *reg, uint32_t href_comp, view_t parent);
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);
VIEWINLINE void View_Delete (view_t view);
void View_SetParent (view_t view, view_t parent);
void View_UpdateHierarchy (view_t view);
@ -165,6 +176,17 @@ VIEWINLINE void View_SetOnMove (view_t view, view_move_f onmove);
#define VIEWINLINE VISIBLE
#endif
VIEWINLINE
view_t
View_FromEntity (ecs_system_t viewsys, uint32_t ent)
{
return (view_t) {
.id = ent,
.reg = viewsys.reg,
.comp = viewsys.base + view_href,
};
}
VIEWINLINE
hierref_t *
View_GetRef (view_t view)

View file

@ -55,7 +55,8 @@ typedef struct hud_subpic_s {
uint32_t w, h;
} hud_subpic_t;
extern struct ecs_registry_s *hud_registry;
extern struct ecs_system_s hud_system;
extern struct ecs_system_s hud_viewsys;
extern int hud_sb_lines;

View file

@ -171,7 +171,7 @@ CL_Init_Screen (void)
HUD_Init ();
cl_screen_view = View_New (hud_registry, hud_href, nullview);
cl_screen_view = View_New (hud_viewsys, nullview);
con_module->data->console->screen_view = &cl_screen_view;
View_SetPos (cl_screen_view, 0, 0);
@ -180,7 +180,7 @@ CL_Init_Screen (void)
View_SetVisible (cl_screen_view, 1);
pic = r_funcs->Draw_PicFromWad ("ram");
ram_view = View_New (hud_registry, hud_href, cl_screen_view);
ram_view = View_New (hud_viewsys, cl_screen_view);
View_SetPos (ram_view, 32, 0);
View_SetLen (ram_view, pic->width, pic->height);
View_SetGravity (ram_view, grav_northwest);
@ -188,7 +188,7 @@ CL_Init_Screen (void)
View_SetVisible (ram_view, 0);
pic = r_funcs->Draw_PicFromWad ("turtle");
turtle_view = View_New (hud_registry, hud_href, cl_screen_view);
turtle_view = View_New (hud_viewsys, cl_screen_view);
View_SetPos (turtle_view, 32, 0);
View_SetLen (turtle_view, pic->width, pic->height);
View_SetGravity (turtle_view, grav_northwest);
@ -200,14 +200,14 @@ CL_Init_Screen (void)
Cvar_Register (&scr_showturtle_cvar, 0, 0);
pic = r_funcs->Draw_PicFromWad ("net");
net_view = View_New (hud_registry, hud_href, cl_screen_view);
net_view = View_New (hud_viewsys, cl_screen_view);
View_SetPos (net_view, 64, 0);
View_SetLen (net_view, pic->width, pic->height);
View_SetGravity (net_view, grav_northwest);
Ent_SetComponent (net_view.id, hud_pic, net_view.reg, &pic);
View_SetVisible (net_view, 0);
timegraph_view = View_New (hud_registry, hud_href, cl_screen_view);
timegraph_view = View_New (hud_viewsys, cl_screen_view);
View_SetPos (timegraph_view, 0, 0);
View_SetLen (timegraph_view, r_data->vid->width, 100);
View_SetGravity (timegraph_view, grav_southwest);
@ -215,7 +215,7 @@ CL_Init_Screen (void)
Ent_SetComponent (timegraph_view.id, hud_func, timegraph_view.reg, &rtg);
View_SetVisible (timegraph_view, r_timegraph);
zgraph_view = View_New (hud_registry, hud_href, cl_screen_view);
zgraph_view = View_New (hud_viewsys, cl_screen_view);
View_SetPos (zgraph_view, 0, 0);
View_SetLen (zgraph_view, r_data->vid->width, 100);
View_SetGravity (zgraph_view, grav_southwest);
@ -225,7 +225,7 @@ CL_Init_Screen (void)
const char *name = "gfx/loading.lmp";
pic = r_funcs->Draw_CachePic (name, 1);
loading_view = View_New (hud_registry, hud_href, cl_screen_view);
loading_view = View_New (hud_viewsys, cl_screen_view);
View_SetPos (loading_view, 0, -24);
View_SetLen (loading_view, pic->width, pic->height);
View_SetGravity (loading_view, grav_center);
@ -234,7 +234,7 @@ CL_Init_Screen (void)
name = "gfx/pause.lmp";
pic = r_funcs->Draw_CachePic (name, 1);
pause_view = View_New (hud_registry, hud_href, cl_screen_view);
pause_view = View_New (hud_viewsys, cl_screen_view);
View_SetPos (pause_view, 0, -24);
View_SetLen (pause_view, pic->width, pic->height);
View_SetGravity (pause_view, grav_center);

View file

@ -88,7 +88,8 @@ static const component_t hud_components[hud_comp_count] = {
},
};
ecs_registry_t *hud_registry;
ecs_system_t hud_system;
ecs_system_t hud_viewsys;
int hud_sb_lines;
int hud_sbar;
@ -264,9 +265,13 @@ hud_scoreboard_gravity_f (void *data, const cvar_t *cvar)
void
HUD_Init (void)
{
hud_registry = ECS_NewRegistry ();
ECS_RegisterComponents (hud_registry, hud_components, hud_comp_count);
ECS_CreateComponentPools (hud_registry);
hud_system.reg = ECS_NewRegistry ();
hud_viewsys.reg = hud_system.reg;
hud_system.base = ECS_RegisterComponents (hud_system.reg, hud_components,
hud_comp_count);
hud_viewsys.base = ECS_RegisterComponents (hud_system.reg, view_components,
view_comp_count);
ECS_CreateComponentPools (hud_system.reg);
}
void
@ -326,8 +331,7 @@ draw_update (ecs_pool_t *pool)
uint32_t *ent = pool->dense;
hud_update_f *func = pool->data;
while (count-- > 0) {
view_t view = { .id = *ent++, .reg = hud_registry };
(*func++) (view);
(*func++) (View_FromEntity (hud_viewsys, *ent++));
}
}
@ -344,7 +348,7 @@ draw_tile_views (ecs_pool_t *pool)
uint32_t count = pool->count;
uint32_t *ent = pool->dense;
while (count-- > 0) {
view_t view = { .id = *ent++, .reg = hud_registry };
view_t view = View_FromEntity (hud_viewsys, *ent++);
if (View_GetVisible (view)) {
view_pos_t pos = View_GetAbs (view);
view_pos_t len = View_GetLen (view);
@ -360,7 +364,7 @@ draw_pic_views (ecs_pool_t *pool)
uint32_t *ent = pool->dense;
qpic_t **pic = pool->data;
while (count-- > 0) {
view_t view = { .id = *ent++, .reg = hud_registry };
view_t view = View_FromEntity (hud_viewsys, *ent++);
if (View_GetVisible (view)) {
view_pos_t pos = View_GetAbs (view);
r_funcs->Draw_Pic (pos.x, pos.y, *pic);
@ -376,7 +380,7 @@ draw_subpic_views (ecs_pool_t *pool)
uint32_t *ent = pool->dense;
hud_subpic_t *subpic = pool->data;
while (count-- > 0) {
view_t view = { .id = *ent++, .reg = hud_registry };
view_t view = View_FromEntity (hud_viewsys, *ent++);
if (View_GetVisible (view)) {
view_pos_t pos = View_GetAbs (view);
r_funcs->Draw_SubPic (pos.x, pos.y, subpic->pic,
@ -393,7 +397,7 @@ draw_cachepic_views (ecs_pool_t *pool)
uint32_t *ent = pool->dense;
const char **name = pool->data;
while (count-- > 0) {
view_t view = { .id = *ent++, .reg = hud_registry };
view_t view = View_FromEntity (hud_viewsys, *ent++);
if (View_GetVisible (view)) {
view_pos_t pos = View_GetAbs (view);
qpic_t *pic = r_funcs->Draw_CachePic (*name, 1);
@ -410,7 +414,7 @@ draw_fill_views (ecs_pool_t *pool)
uint32_t *ent = pool->dense;
byte *fill = pool->data;
while (count-- > 0) {
view_t view = { .id = *ent++, .reg = hud_registry };
view_t view = View_FromEntity (hud_viewsys, *ent++);
if (View_GetVisible (view)) {
view_pos_t pos = View_GetAbs (view);
view_pos_t len = View_GetLen (view);
@ -427,7 +431,7 @@ draw_charbuff_views (ecs_pool_t *pool)
uint32_t *ent = pool->dense;
draw_charbuffer_t **charbuff = pool->data;
while (count-- > 0) {
view_t view = { .id = *ent++, .reg = hud_registry };
view_t view = View_FromEntity (hud_viewsys, *ent++);
if (View_GetVisible (view)) {
view_pos_t pos = View_GetAbs (view);
r_funcs->Draw_CharBuffer (pos.x, pos.y, *charbuff);
@ -443,7 +447,7 @@ draw_func_views (ecs_pool_t *pool)
uint32_t *ent = pool->dense;
hud_func_f *func = pool->data;
while (count-- > 0) {
view_t view = { .id = *ent++, .reg = hud_registry };
view_t view = View_FromEntity (hud_viewsys, *ent++);
if (View_GetVisible (view)) {
view_pos_t pos = View_GetAbs (view);
view_pos_t len = View_GetLen (view);
@ -461,7 +465,7 @@ draw_outline_views (ecs_pool_t *pool)
byte *col = pool->data;
__auto_type line = r_funcs->Draw_Line;
while (count-- > 0) {
view_t view = { .id = *ent++, .reg = hud_registry };
view_t view = View_FromEntity (hud_viewsys, *ent++);
byte c = *col++;
if (View_GetVisible (view)) {
view_pos_t p = View_GetAbs (view);
@ -492,7 +496,7 @@ HUD_Draw_Views (void)
};
for (int i = 0; i < hud_comp_count; i++) {
if (draw_func[i]) {
draw_func[i] (&hud_registry->comp_pools[i]);
draw_func[i] (&hud_system.reg->comp_pools[i + hud_system.base]);
}
}
}

View file

@ -254,7 +254,7 @@ static draw_charbuffer_t *solo_name;
static view_t
sbar_view (int x, int y, int w, int h, grav_t gravity, view_t parent)
{
view_t view = View_New (hud_registry, hud_href, parent);
view_t view = View_New (hud_viewsys, parent);
View_SetPos (view, x, y);
View_SetLen (view, w, h);
View_SetGravity (view, gravity);
@ -2024,8 +2024,10 @@ href_cmp (const void *_a, const void *_b, void *arg)
{
uint32_t enta = *(const uint32_t *)_a;
uint32_t entb = *(const uint32_t *)_b;
hierref_t *ref_a = Ent_GetComponent (enta, hud_href, hud_registry);
hierref_t *ref_b = Ent_GetComponent (entb, hud_href, hud_registry);
ecs_registry_t *reg = hud_viewsys.reg;
uint32_t href = hud_viewsys.base + hud_href;
hierref_t *ref_a = Ent_GetComponent (enta, href, reg);
hierref_t *ref_b = Ent_GetComponent (entb, href, reg);
if (ref_a->hierarchy == ref_b->hierarchy) {
return ref_a->index - ref_b->index;
}
@ -2123,7 +2125,8 @@ set_hud_sbar (void)
sbar_remcomponent (sbar_tile[0], hud_tile);
sbar_remcomponent (sbar_tile[1], hud_tile);
}
ECS_SortComponentPool (hud_registry, hud_pic, href_cmp, 0);
ECS_SortComponentPool (hud_system.reg, hud_system.base + hud_pic,
href_cmp, 0);
}
static void
@ -2551,7 +2554,7 @@ Sbar_Init (int *stats, float *item_gettime)
sbar_stats = stats;
sbar_item_gettime = item_gettime;
center_passage.reg = hud_registry;
center_passage.reg = hud_viewsys.reg;
HUD_Init_Cvars ();
Cvar_AddListener (Cvar_FindVar ("hud_sbar"), sbar_hud_sbar_f, 0);
Cvar_AddListener (Cvar_FindVar ("hud_swap"), sbar_hud_swap_f, 0);

View file

@ -154,6 +154,8 @@ static cvar_t cl_conmode_cvar = {
};
static ecs_registry_t *client_reg;
static uint32_t client_base;
static uint32_t view_base;
static con_state_t con_state;
static int con_event_id;
@ -1022,7 +1024,10 @@ static void
C_Init (void)
{
client_reg = ECS_NewRegistry ();
ECS_RegisterComponents (client_reg, client_components, client_comp_count);
client_base = ECS_RegisterComponents (client_reg, client_components,
client_comp_count);
view_base = ECS_RegisterComponents (client_reg, view_components,
view_comp_count);
ECS_CreateComponentPools (client_reg);
#ifdef __QNXNTO__
@ -1044,14 +1049,15 @@ C_Init (void)
con_debuglog = COM_CheckParm ("-condebug");
// The console will get resized, so assume initial size is 320x200
screen_view = View_New (client_reg, client_href, nullview);
console_view = View_New (client_reg, client_href, screen_view);
buffer_view = View_New (client_reg, client_href, console_view);
command_view = View_New (client_reg, client_href, console_view);
download_view = View_New (client_reg, client_href, console_view);
notify_view = View_New (client_reg, client_href, screen_view);
say_view = View_New (client_reg, client_href, screen_view);
menu_view = View_New (client_reg, client_href, screen_view);
ecs_system_t sys = { client_reg, view_base };
screen_view = View_New (sys, nullview);
console_view = View_New (sys, screen_view);
buffer_view = View_New (sys, console_view);
command_view = View_New (sys, console_view);
download_view = View_New (sys, console_view);
notify_view = View_New (sys, screen_view);
say_view = View_New (sys, screen_view);
menu_view = View_New (sys, screen_view);
View_SetGravity (screen_view, grav_northwest);
View_SetGravity (console_view, grav_northwest);

View file

@ -161,6 +161,8 @@ static volatile sig_atomic_t interrupted;
static int batch_print;
static ecs_registry_t *server_reg;
static uint32_t server_base;
static uint32_t view_base;
#define MAXCMDLINE 256
@ -246,8 +248,9 @@ draw_fun_char (WINDOW *win, byte c, int blue)
static inline void
sv_refresh_windows (void)
{
sv_view_t *window = server_reg->comp_pools[server_window].data;
uint32_t count = server_reg->comp_pools[server_window].count;
uint32_t window_comp = server_base + server_window;
sv_view_t *window = server_reg->comp_pools[window_comp].data;
uint32_t count = server_reg->comp_pools[window_comp].count;
while (count-- > 0) {
wnoutrefresh ((WINDOW *) (window++)->win);
}
@ -616,7 +619,8 @@ create_window (view_t parent, int xpos, int ypos, int xlen, int ylen,
grav_t grav, void *obj, int opts, void (*draw) (view_t),
void (*setgeometry) (view_t))
{
view_t view = View_New (server_reg, server_href, parent);
view_t view = View_New ((ecs_system_t) { server_reg, view_base },
parent);
View_SetPos (view, xpos, ypos);
View_SetLen (view, xlen, ylen);
View_SetGravity (view, grav);
@ -678,12 +682,15 @@ init (void)
nonl ();
server_reg = ECS_NewRegistry ();
ECS_RegisterComponents (server_reg, server_components, server_comp_count);
server_base = ECS_RegisterComponents (server_reg, server_components,
server_comp_count);
view_base = ECS_RegisterComponents (server_reg, view_components,
view_comp_count);
ECS_CreateComponentPools (server_reg);
get_size (&screen_x, &screen_y);
sv_view = View_New (server_reg, server_href, nullview);
sv_view = View_New ((ecs_system_t) { server_reg, view_base }, nullview);
View_SetPos (sv_view, 0, 0);
View_SetLen (sv_view, screen_x, screen_y);
View_SetGravity (sv_view, grav_northwest);

View file

@ -68,6 +68,10 @@ typedef struct {
rua_passage_t *passages;
PR_RESMAP (rua_font_t) font_map;
rua_font_t *fonts;
ecs_registry_t *reg;
uint32_t text_base;
uint32_t view_base;
} gui_resources_t;
static rua_passage_t *
@ -206,6 +210,7 @@ static void
bi_gui_destroy (progs_t *pr, void *_res)
{
gui_resources_t *res = _res;
ECS_DelRegistry (res->reg);
free (res);
}
@ -225,7 +230,7 @@ bi (Font_Load)
bi (Passage_New)
{
gui_resources_t *res = _res;
passage_t *passage = Passage_New (text_reg, text_href);
passage_t *passage = Passage_New (res->reg, res->text_base + text_href);
R_INT (pr) = alloc_passage (res, passage);
}
@ -272,17 +277,20 @@ bi (Text_View)
gui_resources_t *res = _res;
rua_font_t *font = get_font (res, P_INT (pr, 0));
rua_passage_t *psg = get_passage (res, P_INT (pr, 1));
view_t view = Text_View (font->font, psg->passage);
ecs_system_t viewsys = { .reg = res->reg, .base = res->view_base };
view_t view = Text_View (viewsys, font->font, psg->passage);
R_INT (pr) = view.id;//FIXME
}
bi (Text_SetScript)
{
gui_resources_t *res = _res;
uint32_t textent = P_UINT (pr, 0);
const char *lang = P_GSTRING (pr, 1);
int script = P_INT (pr, 1);
int dir = P_INT (pr, 1);
Text_SetScript (textent, lang, script, dir);
ecs_system_t textsys = { .reg = res->reg, .base = res->text_base };
Text_SetScript (textsys, textent, lang, script, dir);
}
static void
@ -313,15 +321,18 @@ draw_box (view_pos_t *abs, view_pos_t *len, uint32_t ind, int c)
bi (Text_Draw)
{
ecs_pool_t *pool = &text_reg->comp_pools[text_passage_glyphs];
gui_resources_t *res = _res;
uint32_t passage_glyphs = res->text_base + text_passage_glyphs;
uint32_t glyphs = res->text_base + text_glyphs;
uint32_t vhref = res->view_base + view_href;
ecs_pool_t *pool = &res->reg->comp_pools[passage_glyphs];
uint32_t count = pool->count;
uint32_t *ent = pool->dense;
glyphset_t *glyphset = pool->data;
while (count-- > 0) {
view_t psg_view = { .id = *ent++, .reg = text_reg,
.comp = text_href};
view_t psg_view = { .id = *ent++, .reg = res->reg, .comp = vhref};
// first child is always a paragraph view, and all vies after the
// first paragraph's first child are all text views
view_t para_view = View_GetChild (psg_view, 0);
@ -332,8 +343,7 @@ bi (Text_Draw)
view_pos_t *len = h->components[view_len];
for (uint32_t i = href->index; i < h->num_objects; i++) {
glyphref_t *gref = Ent_GetComponent (h->ent[i], text_glyphs,
text_reg);
glyphref_t *gref = Ent_GetComponent (h->ent[i], glyphs, res->reg);
draw_glyphs (&abs[i], glyphset, gref);
if (0) draw_box (abs, len, i, 253);
@ -348,49 +358,61 @@ bi (Text_Draw)
bi (View_ChildCount)
{
gui_resources_t *res = _res;
uint32_t viewid = P_UINT (pr, 0);
view_t view = { .id = viewid, .reg = text_reg };
view_t view = { .id = viewid, .reg = res->reg,
.comp = res->view_base + view_href };
R_UINT (pr) = View_ChildCount (view);
}
bi (View_GetChild)
{
gui_resources_t *res = _res;
uint32_t viewid = P_UINT (pr, 0);
uint32_t index = P_UINT (pr, 1);
view_t view = { .id = viewid, .reg = text_reg };
view_t view = { .id = viewid, .reg = res->reg,
.comp = res->view_base + view_href };
R_UINT (pr) = View_GetChild (view, index).id;
}
bi (View_SetPos)
{
gui_resources_t *res = _res;
uint32_t viewid = P_UINT (pr, 0);
int x = P_INT (pr, 1);
int y = P_INT (pr, 2);
view_t view = { .id = viewid, .reg = text_reg };
view_t view = { .id = viewid, .reg = res->reg,
.comp = res->view_base + view_href };
View_SetPos (view, x, y);
}
bi (View_SetLen)
{
gui_resources_t *res = _res;
uint32_t viewid = P_UINT (pr, 0);
int x = P_INT (pr, 1);
int y = P_INT (pr, 2);
view_t view = { .id = viewid, .reg = text_reg };
view_t view = { .id = viewid, .reg = res->reg,
.comp = res->view_base + view_href };
View_SetLen (view, x, y);
}
bi (View_GetLen)
{
gui_resources_t *res = _res;
uint32_t viewid = P_UINT (pr, 0);
view_t view = { .id = viewid, .reg = text_reg };
view_t view = { .id = viewid, .reg = res->reg,
.comp = res->view_base + view_href };
view_pos_t l = View_GetLen (view);
R_var (pr, ivec2) = (pr_ivec2_t) { l.x, l.y };
}
bi (View_UpdateHierarchy)
{
gui_resources_t *res = _res;
uint32_t viewid = P_UINT (pr, 0);
view_t view = { .id = viewid, .reg = text_reg };
view_t view = { .id = viewid, .reg = res->reg,
.comp = res->view_base + view_href };
View_UpdateHierarchy (view);
}
@ -429,4 +451,11 @@ RUA_GUI_Init (progs_t *pr, int secure)
PR_Resources_Register (pr, "Draw", res, bi_gui_clear, bi_gui_destroy);
PR_RegisterBuiltins (pr, builtins, res);
res->reg = ECS_NewRegistry ();
res->text_base = ECS_RegisterComponents (res->reg, text_components,
text_comp_count);
res->view_base = ECS_RegisterComponents (res->reg, view_components,
view_comp_count);
ECS_CreateComponentPools (res->reg);
}

View file

@ -5,10 +5,12 @@
#include "QF/ui/view.h"
static ecs_registry_t *test_reg;
static ecs_system_t test_sys;
enum {
test_href,
test_comp_count
};
static const component_t test_components[] = {
@ -223,7 +225,7 @@ print_view (view_t view)
static int
test_flow (testdata_t *child_views, int count, void (flow) (view_t, view_pos_t))
{
view_t flow_view = View_New (test_reg, test_href, nullview);
view_t flow_view = View_New (test_sys, nullview);
View_SetPos (flow_view, 0, 0);
View_SetLen (flow_view, 256, 256);
View_SetGravity (flow_view, grav_northwest);
@ -232,7 +234,7 @@ test_flow (testdata_t *child_views, int count, void (flow) (view_t, view_pos_t))
for (int i = 0; i < count; i++) {
testdata_t *td = &child_views[i];
view_t child = View_New (test_reg, test_href, flow_view);
view_t child = View_New (test_sys, flow_view);
View_SetPos (child, 0, 0);
View_SetLen (child, td->xlen, td->ylen);
View_SetGravity (child, grav_flow);
@ -266,8 +268,7 @@ test_flow (testdata_t *child_views, int count, void (flow) (view_t, view_pos_t))
td->expect.xpos, td->expect.ypos,
td->expect.xrel, td->expect.yrel,
td->expect.xabs, td->expect.yabs);
print_view ((view_t) { .reg = test_reg, .id = ent[child],
.comp = flow_view.comp});
print_view (View_FromEntity (test_sys, ent[child]));
}
}
return ret;
@ -278,9 +279,10 @@ main (void)
{
int ret = 0;
test_reg = ECS_NewRegistry ();
ECS_RegisterComponents (test_reg, test_components, 1);
ECS_CreateComponentPools (test_reg);
test_sys.reg = ECS_NewRegistry ();
test_sys.base = ECS_RegisterComponents (test_sys.reg, test_components,
test_comp_count);
ECS_CreateComponentPools (test_sys.reg);
if (test_flow (right_down_views, right_down_count, view_flow_right_down)) {
printf ("right-down failed\n");

View file

@ -5,10 +5,12 @@
#include "QF/ui/view.h"
static ecs_registry_t *test_reg;
static ecs_system_t test_sys;
enum {
test_href,
test_comp_count
};
static const component_t test_components[] = {
@ -224,7 +226,7 @@ static int
test_flow (testdata_t *child_views, int count,
void (*flow) (view_t, view_pos_t))
{
view_t flow_view = View_New (test_reg, test_href, nullview);
view_t flow_view = View_New (test_sys, nullview);
View_SetPos (flow_view, 0, 0);
View_SetLen (flow_view, 256, 256);
View_SetGravity (flow_view, grav_northwest);
@ -232,7 +234,7 @@ test_flow (testdata_t *child_views, int count,
for (int i = 0; i < count; i++) {
testdata_t *td = &child_views[i];
view_t child = View_New (test_reg, test_href, flow_view);
view_t child = View_New (test_sys, flow_view);
View_SetPos (child, 0, 0);
View_SetLen (child, td->xlen, td->ylen);
View_SetGravity (child, grav_flow);
@ -266,8 +268,7 @@ test_flow (testdata_t *child_views, int count,
td->expect.xpos, td->expect.ypos,
td->expect.xrel, td->expect.yrel,
td->expect.xabs, td->expect.yabs);
print_view ((view_t) { .reg = test_reg, .id = ent[child],
.comp = flow_view.comp});
print_view (View_FromEntity (test_sys, ent[child]));
}
}
return ret;
@ -278,9 +279,10 @@ main (void)
{
int ret = 0;
test_reg = ECS_NewRegistry ();
ECS_RegisterComponents (test_reg, test_components, 1);
ECS_CreateComponentPools (test_reg);
test_sys.reg = ECS_NewRegistry ();
test_sys.base = ECS_RegisterComponents (test_sys.reg, test_components,
test_comp_count);
ECS_CreateComponentPools (test_sys.reg);
if (test_flow (right_down_views, right_down_count, view_flow_right_down)) {
printf ("right-down failed\n");

View file

@ -57,7 +57,7 @@ text_features_destroy (void *_features)
DARRAY_CLEAR (features);
}
static const component_t text_components[text_comp_count] = {
const component_t text_components[text_comp_count] = {
[text_href] = {
.size = sizeof (hierref_t),
.name = "href",
@ -85,15 +85,6 @@ static const component_t text_components[text_comp_count] = {
.destroy = text_features_destroy,
},
};
ecs_registry_t *text_reg;
void
Text_Init (void)
{
text_reg = ECS_NewRegistry ();
ECS_RegisterComponents (text_reg, text_components, text_comp_count);
ECS_CreateComponentPools (text_reg);
}
typedef struct glyphnode_s {
struct glyphnode_s *next;
@ -116,8 +107,9 @@ static view_resize_f text_flow_funcs[] = {
};
view_t
Text_View (font_t *font, passage_t *passage)
Text_View (ecs_system_t viewsys, font_t *font, passage_t *passage)
{
ecs_registry_t *reg = passage->reg;
hierarchy_t *h = passage->hierarchy;
psg_text_t *text_objects = h->components[passage_type_text_obj];
glyphnode_t *glyph_nodes = 0;
@ -146,16 +138,15 @@ Text_View (font_t *font, passage_t *passage)
hb_language_t para_language = psg_language;
featureset_t *para_features = psg_features;;
if (Ent_HasComponent (para_ent, text_script, text_reg)) {
if (Ent_HasComponent (para_ent, text_script, reg)) {
script_component_t *s = Ent_GetComponent (para_ent, text_script,
text_reg);
reg);
para_script = s->script;
para_language = s->language;
para_direction = s->direction;
}
if (Ent_HasComponent (para_ent, text_features, text_reg)) {
para_features = Ent_GetComponent (para_ent, text_features,
text_reg);
if (Ent_HasComponent (para_ent, text_features, reg)) {
para_features = Ent_GetComponent (para_ent, text_features, reg);
}
for (uint32_t j = 0; j < h->childCount[paragraph]; j++) {
uint32_t textind = h->childIndex[paragraph] + j;
@ -169,16 +160,15 @@ Text_View (font_t *font, passage_t *passage)
hb_language_t txt_language = para_language;
featureset_t *txt_features = para_features;;
if (Ent_HasComponent (text_ent, text_script, text_reg)) {
if (Ent_HasComponent (text_ent, text_script, reg)) {
script_component_t *s = Ent_GetComponent (text_ent, text_script,
text_reg);
reg);
txt_script = s->script;
txt_language = s->language;
txt_direction = s->direction;
}
if (Ent_HasComponent (text_ent, text_features, text_reg)) {
txt_features = Ent_GetComponent (text_ent, text_features,
text_reg);
if (Ent_HasComponent (text_ent, text_features, reg)) {
txt_features = Ent_GetComponent (text_ent, text_features, reg);
}
hb_buffer_reset (buffer);
@ -240,7 +230,7 @@ Text_View (font_t *font, passage_t *passage)
head = &(*head)->next;
}
}
view_t passage_view = View_New (text_reg, text_href, nullview);
view_t passage_view = View_AddToEntity (h->ent[0], viewsys, nullview);
glyphref_t passage_ref = {};
glyphobj_t *glyphs = malloc (glyph_count * sizeof (glyphobj_t));
glyphnode_t *g = glyph_nodes;
@ -248,10 +238,13 @@ Text_View (font_t *font, passage_t *passage)
int psg_vertical = !!(psg_direction & 2);
for (uint32_t i = 0; i < h->childCount[0]; i++) {
uint32_t paragraph = h->childIndex[0] + i;
view_t paraview = View_New (text_reg, text_href, passage_view);
view_t paraview = View_AddToEntity (h->ent[paragraph], viewsys,
passage_view);
glyphref_t pararef = { .start = passage_ref.count };
for (uint32_t j = 0; j < h->childCount[paragraph]; j++, g = g->next) {
view_t textview = View_New (text_reg, text_href, paraview);
uint32_t to = h->childIndex[paragraph] + j;
view_t textview = View_AddToEntity (h->ent[to], viewsys,
paraview);
glyphref_t glyph_ref = {
.start = passage_ref.count,
.count = g->count,
@ -265,7 +258,7 @@ Text_View (font_t *font, passage_t *passage)
.fontid = go->fontid,
};
}
Ent_SetComponent (textview.id, text_glyphs, text_reg, &glyph_ref);
Ent_SetComponent (textview.id, text_glyphs, reg, &glyph_ref);
View_SetPos (textview, g->mins[0], -g->mins[1]);
View_SetLen (textview, g->maxs[0] - g->mins[0],
g->maxs[1] - g->mins[1]);
@ -273,13 +266,13 @@ Text_View (font_t *font, passage_t *passage)
passage_ref.count += g->count;
}
pararef.count = passage_ref.count - pararef.start;
Ent_SetComponent (paraview.id, text_glyphs, text_reg, &pararef);
Ent_SetComponent (paraview.id, text_glyphs, reg, &pararef);
uint32_t para_ent = h->ent[paragraph];
text_dir_e para_direction = psg_direction;
if (Ent_HasComponent (para_ent, text_script, text_reg)) {
if (Ent_HasComponent (para_ent, text_script, reg)) {
script_component_t *s = Ent_GetComponent (para_ent, text_script,
text_reg);
reg);
para_direction = s->direction;
}
View_SetOnResize (paraview, text_flow_funcs[para_direction]);
@ -287,18 +280,17 @@ Text_View (font_t *font, passage_t *passage)
View_SetGravity (paraview, grav_northwest);
View_Control (paraview)->flow_size = 1;
}
Ent_SetComponent (passage_view.id, text_glyphs, text_reg, &passage_ref);
Ent_SetComponent (passage_view.id, text_glyphs, reg, &passage_ref);
glyphset_t glyphset = {
.glyphs = glyphs,
.count = glyph_count,
};
Ent_SetComponent (passage_view.id, text_passage_glyphs, text_reg,
&glyphset);
Ent_SetComponent (passage_view.id, text_passage_glyphs, reg, &glyphset);
return passage_view;
}
void
Text_SetScript (int textid, const char *lang, hb_script_t script,
Text_SetScript (ecs_system_t textsys, uint32_t textid, const char *lang, hb_script_t script,
text_dir_e dir)
{
script_component_t scr = {
@ -306,32 +298,34 @@ Text_SetScript (int textid, const char *lang, hb_script_t script,
.script = script,
.direction = dir,
};
Ent_SetComponent (textid, text_script, text_reg, &scr);
Ent_SetComponent (textid, textsys.base + text_script, textsys.reg, &scr);
}
void
Text_SetFont (int textid, font_t *font)
Text_SetFont (ecs_system_t textsys, uint32_t textid, font_t *font)
{
Ent_SetComponent (textid, text_font, text_reg, &font);
Ent_SetComponent (textid, textsys.base + text_font, textsys.reg, &font);
}
void
Text_SetFeatures (int textid, featureset_t *features)
Text_SetFeatures (ecs_system_t textsys, uint32_t textid, featureset_t *features)
{
if (Ent_HasComponent (textid, text_features, text_reg)) {
Ent_RemoveComponent (textid, text_features, text_reg);
uint32_t features_comp = textsys.base + text_features;
if (Ent_HasComponent (textid, features_comp, textsys.reg)) {
Ent_RemoveComponent (textid, features_comp, textsys.reg);
}
featureset_t *f = Ent_SetComponent (textid, text_features, text_reg, 0);
featureset_t *f = Ent_SetComponent (textid, features_comp, textsys.reg, 0);
DARRAY_RESIZE (f, features->size);
memcpy (f->a, features->a, features->size * sizeof (hb_feature_t));
}
void
Text_AddFeature (int textid, hb_feature_t feature)
Text_AddFeature (ecs_system_t textsys, uint32_t textid, hb_feature_t feature)
{
if (!Ent_HasComponent (textid, text_features, text_reg)) {
Ent_SetComponent (textid, text_features, text_reg, 0);
uint32_t features_comp = textsys.base + text_features;
if (!Ent_HasComponent (textid, features_comp, textsys.reg)) {
Ent_SetComponent (textid, features_comp, textsys.reg, 0);
}
featureset_t *f = Ent_GetComponent (textid, text_features, text_reg);
featureset_t *f = Ent_GetComponent (textid, features_comp, textsys.reg);
DARRAY_APPEND (f, feature);
}

View file

@ -90,7 +90,14 @@ view_modified_init (void *_modified)
*modified = 1;
}
static const component_t view_components[view_type_count] = {
const component_t view_components[view_comp_count] = {
[view_href] = {
.size = sizeof (hierref_t),
.name = "view href",
},
};
static const component_t view_type_components[view_type_count] = {
[view_pos] = {
.size = sizeof (view_pos_t),
.name = "pos",
@ -132,14 +139,14 @@ static const component_t view_components[view_type_count] = {
static const hierarchy_type_t view_type = {
.num_components = view_type_count,
.components = view_components,
.components = view_type_components,
};
view_t
View_New (ecs_registry_t *reg, uint32_t href_comp, view_t parent)
View_AddToEntity (uint32_t ent, ecs_system_t viewsys, view_t parent)
{
uint32_t view = ECS_NewEntity (reg);
hierref_t *ref = Ent_AddComponent (view, href_comp, reg);
uint32_t href_comp = viewsys.base + view_href;
hierref_t *ref = Ent_AddComponent (ent, href_comp, viewsys.reg);
if (parent.reg && parent.id != nullent) {
hierref_t *pref = View_GetRef (parent);
@ -147,11 +154,18 @@ View_New (ecs_registry_t *reg, uint32_t href_comp, view_t parent)
ref->index = Hierarchy_InsertHierarchy (pref->hierarchy, 0,
pref->index, 0);
} else {
ref->hierarchy = Hierarchy_New (reg, href_comp, &view_type, 1);
ref->hierarchy = Hierarchy_New (viewsys.reg, href_comp, &view_type, 1);
ref->index = 0;
}
ref->hierarchy->ent[ref->index] = view;
return (view_t) { .reg = reg, .id = view, .comp = href_comp };
ref->hierarchy->ent[ref->index] = ent;
return (view_t) { .reg = viewsys.reg, .id = ent, .comp = href_comp };
}
view_t
View_New (ecs_system_t viewsys, view_t parent)
{
uint32_t view = ECS_NewEntity (viewsys.reg);
return View_AddToEntity (view, viewsys, parent);
}
void

View file

@ -88,14 +88,16 @@ qtv_sbar_init (void)
sv_view_t sv_view = *(sv_view_t *) comp;
sv_view.setgeometry = 0;
view = View_New (status.reg, status.comp, status);
ecs_system_t viewsys = { .reg = status.reg,
.base = status.comp - view_href };
view = View_New (viewsys, status);
View_SetPos (view, 0, 0);
View_SetLen (view, 8, 1);
View_SetGravity (view, grav_northwest);
sv_view.draw = draw_servers;
Ent_SetComponent (view.id, server_view, view.reg, &sv_view);
view = View_New (status.reg, status.comp, status);
view = View_New (viewsys, status);
View_SetPos (view, 8, 0);
View_SetLen (view, 9, 1);
View_SetGravity (view, grav_northwest);

View file

@ -156,7 +156,7 @@ CL_NetGraph (view_pos_t abs, view_pos_t len)
void
CL_NetGraph_Init (void)
{
cl_netgraph_view = View_New (hud_registry, hud_href, cl_screen_view);
cl_netgraph_view = View_New (hud_viewsys, cl_screen_view);
View_SetPos (cl_netgraph_view, 0, 64);
View_SetLen (cl_netgraph_view, NET_TIMINGS + 16, cl_netgraph_height + 25);
View_SetGravity (cl_netgraph_view, grav_southwest);

View file

@ -118,21 +118,23 @@ SV_Sbar_Init (void)
sv_view_t sv_view = *(sv_view_t *) comp;
sv_view.setgeometry = 0;
view = View_New (status.reg, status.comp, status);
ecs_system_t viewsys = { .reg = status.reg,
.base = status.comp - view_href };
view = View_New (viewsys, status);
View_SetPos (view, 0, 0);
View_SetLen (view, 11, 1);
View_SetGravity (view, grav_northwest);
sv_view.draw = draw_cpu;
Ent_SetComponent (view.id, server_view, view.reg, &sv_view);
view = View_New (status.reg, status.comp, status);
view = View_New (viewsys, status);
View_SetPos (view, 11, 0);
View_SetLen (view, 8, 1);
View_SetGravity (view, grav_northwest);
sv_view.draw = draw_rec;
Ent_SetComponent (view.id, server_view, view.reg, &sv_view);
view = View_New (status.reg, status.comp, status);
view = View_New (viewsys, status);
View_SetPos (view, 19, 0);
View_SetLen (view, 18, 1);
View_SetGravity (view, grav_northwest);

View file

@ -346,7 +346,6 @@ BI_Graphics_Init (progs_t *pr)
Mod_Init ();
R_Init ();
Font_Init ();
Text_Init ();
R_Progs_Init (pr);
RUA_Game_Init (pr, thread->rua_security);