From 12e0680e13e3b00fe085ff419abcef88dd512b23 Mon Sep 17 00:00:00 2001 From: David Vazgenovich Shakaryan Date: Tue, 3 May 2022 15:27:10 -0700 Subject: web: reuse elem array appending for drawing visits --- web/static/dartboat.js | 34 ++++++------------- web/web_scoreboard.c | 91 ++++++++++++++++++++++++++++++++++++++------------ web/web_svg.c | 40 +++++++++++----------- 3 files changed, 99 insertions(+), 66 deletions(-) diff --git a/web/static/dartboat.js b/web/static/dartboat.js index 94337be..44daabb 100644 --- a/web/static/dartboat.js +++ b/web/static/dartboat.js @@ -60,6 +60,11 @@ function elemSetUniqClass(sel, c, sel_set) { e.classList[sel && e.matches(selstr) ? 'add' : 'remove'](cstr)); } +function elemScrollToBottom(sel) { + const e = $(UTF8ToString(sel)); + e.scrollTop = e.scrollHeight; +} + function promptHandle(command, data) { const str_c = toCString(command); const str_d = data && toCString(data); @@ -69,34 +74,17 @@ function promptHandle(command, data) { if (str_d) _free(str_d); } -const POINT_CLASSES = [180, 140, 100, 60, 40, 20, 0]; -function drawVisit(visit_no, p1_pts, p1_rem, p2_pts, p2_rem, p2_darts) { - const e = $('#visits'); - - for (const [i, ptr] of [ - p1_pts, p1_rem, visit_no, p2_rem, p2_pts, p2_darts].entries()) { - - const div = e.appendChild(document.createElement('div')); - const v = div.textContent = UTF8ToString(ptr); - div.classList.add(`visit-col${i+1}`); - if (i == 0 || i == 4) - div.classList.add(`p${POINT_CLASSES.find(x => x <= v)}`); - else if (i == 5 && v) - div.textContent = `… ${v}`; - } - - e.scrollTop = e.scrollHeight; -} - -function svgAppendElemv(sel, elemc, elemv, off_name, off_n_attrs, - off_attr_names, off_attr_vals, off_content) { +function elemAppendElemv(sel, elemc, elemv, off_ns, off_name, off_content, + off_n_attrs, off_attr_names, off_attr_vals) { const target = $(UTF8ToString(sel)); for (let ptr = elemv; ptr < elemv + 4*elemc; ptr += 4) { const struct = HEAP32[ptr>>2]; - const e = document.createElementNS('http://www.w3.org/2000/svg', - UTF8ToString(HEAP32[(struct + off_name)>>2])); + const nsptr = HEAP32[(struct + off_ns)>>2]; + const name = UTF8ToString(HEAP32[(struct + off_name)>>2]); + const e = nsptr ? document.createElementNS(UTF8ToString(nsptr), name) : + document.createElement(name); const n_attrs = HEAP32[(struct + off_n_attrs)>>2]; if (n_attrs) { diff --git a/web/web_scoreboard.c b/web/web_scoreboard.c index b9b4688..18835eb 100644 --- a/web/web_scoreboard.c +++ b/web/web_scoreboard.c @@ -176,44 +176,91 @@ void clear_player_info(int pn) scoreboard_set_player_avg(pn, 0); } -void draw_visits() + +// FIXME move html/svg elem stuff to common file +struct elem { + char *ns, *name, *content; + int n_attrs, size_attrs; + char **attr_names, **attr_vals; +}; +struct elem *elem_init(char *ns, char *name, int size_attrs); +void elem_free(struct elem *e); +void elem_add_attr(struct elem *e, char *name, char *val); +void elem_add_attr_double(struct elem *e, char *name, double val); +void append_elemv(char *sel, int elemc, struct elem **elemv); + +struct elem *gen_div(char *str, char *class) { - EM_ASM({elemSetContent($0, $1)}, "#visits", NULL); + struct elem *e = elem_init(NULL, "div", 1); + e->content = strdup(str); + elem_add_attr(e, "class", class); + return e; +} - char visit_no[10], p1_pts[10], p1_rem[10], - p2_pts[10], p2_rem[10], p2_darts[100]; +void add_colour_class(char *buf, int pts) +{ + if (pts >= 180) + strcat(buf, " p180"); + else if (pts >= 140) + strcat(buf, " p140"); + else if (pts >= 100) + strcat(buf, " p100"); + else if (pts >= 60) + strcat(buf, " p60"); + else if (pts >= 40) + strcat(buf, " p40"); + else if (pts >= 20) + strcat(buf, " p20"); + else + strcat(buf, " p0"); +} - sprintf(p1_rem, "%d", state->legs[0]->start); - sprintf(p2_rem, "%d", state->legs[1]->start); - EM_ASM({drawVisit($0, $1, $2, $3, $4, $5)}, - "0", "", p1_rem, "", state->mode == M_P ? "" : p2_rem, ""); +void draw_visits() +{ + EM_ASM({elemSetContent($0, $1)}, "#visits", NULL); int n_visits = state->legs[0]->n_visits > state->legs[1]->n_visits ? state->legs[0]->n_visits : state->legs[1]->n_visits; - for (int i = 0; i < n_visits; ++i) { - visit_no[0] = p1_pts[0] = p1_rem[0] = - p2_pts[0] = p2_rem[0] = p2_darts[0] = 0; - sprintf(visit_no, "%d", i + 1); + struct elem **elemv = malloc(6 * n_visits * sizeof(*elemv)); + int elemc = 0; + for (int i = 0; i < n_visits; ++i) { + char buf[32], buf2[32]; struct visit *v = state->legs[0]->visits + i; - sprintf(p1_pts, "%d", v->points); - sprintf(p1_rem, "%d", v->rem); + sprintf(buf, "%d", v->points); + strcpy(buf2, "visit-col1"); + add_colour_class(buf2, v->points); + elemv[elemc++] = gen_div(buf, buf2); + sprintf(buf, "%d", v->rem); + elemv[elemc++] = gen_div(buf, "visit-col2"); + + sprintf(buf, "%d", i + 1); + elemv[elemc++] = gen_div(buf, "visit-col3"); if (i < state->legs[1]->n_visits) { v = state->legs[1]->visits + i; - sprintf(p2_pts, "%d", v->points); - sprintf(p2_rem, "%d", v->rem); - + sprintf(buf, "%d", v->rem); + elemv[elemc++] = gen_div(buf, "visit-col4"); + sprintf(buf, "%d", v->points); + strcpy(buf2, "visit-col5"); + add_colour_class(buf2, v->points); + elemv[elemc++] = gen_div(buf, buf2); + + strcpy(buf, "… "); for (int j = 0; j < v->n_darts; ++j) { char *n = segment_name(v->darts[j]); - sprintf(p2_darts + (j ? (j*5 - 1) : 0), - j == 0 ? "%4s" : " %4s", n); + sprintf(buf + strlen(buf), j == 0 ? "%4s" : " %4s", n); // FIXME free(n); } + elemv[elemc++] = gen_div(buf, "visit-col6"); + } else { + elemv[elemc++] = gen_div("", "visit-col4"); + elemv[elemc++] = gen_div("", "visit-col5"); + elemv[elemc++] = gen_div("", "visit-col6"); } - - EM_ASM({drawVisit($0, $1, $2, $3, $4, $5)}, - visit_no, p1_pts, p1_rem, p2_pts, p2_rem, p2_darts); } + + append_elemv("#visits", elemc, elemv); + EM_ASM({elemScrollToBottom($0)}, "#visits"); } diff --git a/web/web_svg.c b/web/web_svg.c index 6524754..2f7dc07 100644 --- a/web/web_svg.c +++ b/web/web_svg.c @@ -20,19 +20,17 @@ #define C_WIRE_INNER "#d8e6ec" struct elem { - char *name; + char *ns, *name, *content; int n_attrs, size_attrs; char **attr_names, **attr_vals; - char *content; }; -struct elem *elem_init(char *name, int size_attrs) +struct elem *elem_init(char *ns, char *name, int size_attrs) { struct elem *e = malloc(sizeof(*e)); - size_t size = strlen(name) + 1; - e->name = malloc(size * sizeof(*(e->name))); - memcpy(e->name, name, size); + e->ns = ns ? strdup(ns) : NULL; + e->name = strdup(name); e->n_attrs = 0; e->size_attrs = size_attrs; @@ -43,6 +41,11 @@ struct elem *elem_init(char *name, int size_attrs) return e; } +static inline struct elem *svg_elem_init(char *name, int size_attrs) +{ + return elem_init("http://www.w3.org/2000/svg", name, size_attrs); +} + void elem_free(struct elem *e) { for(int i = 0; i < e->n_attrs; ++i) { @@ -67,13 +70,8 @@ void elem_add_attr(struct elem *e, char *name, char *val) e->size_attrs * sizeof(*(e->attr_vals))); } - size_t size = strlen(name) + 1; - e->attr_names[e->n_attrs] = malloc(size); - memcpy(e->attr_names[e->n_attrs], name, size); - - size = strlen(val) + 1; - e->attr_vals[e->n_attrs] = malloc(size); - memcpy(e->attr_vals[e->n_attrs++], val, size); + e->attr_names[e->n_attrs] = strdup(name); + e->attr_vals[e->n_attrs++] = strdup(val); } void elem_add_attr_double(struct elem *e, char *name, double val) @@ -95,7 +93,7 @@ struct elem *gen_arc(double a1, double a2, double r1, double r2, char *col) struct ccoords cc4 = pol_to_cart((struct pcoords){ .a = (a1 == a2 ? 1 : a2), .r = r2 }); - struct elem *e = elem_init("path", 2); + struct elem *e = svg_elem_init("path", 2); elem_add_attr(e, "fill", col); char buf[512]; @@ -131,7 +129,7 @@ struct elem *gen_ring(double r, double w, char *col) struct elem *gen_circle(double r, char *col) { - struct elem *e = elem_init("circle", 2); + struct elem *e = svg_elem_init("circle", 2); elem_add_attr(e, "fill", col); elem_add_attr_double(e, "r", r); @@ -143,7 +141,7 @@ struct elem *gen_line(double a, double r1, double r2, double w, char *col) struct ccoords cc1 = pol_to_cart((struct pcoords){ .a = a, .r = r1 }); struct ccoords cc2 = pol_to_cart((struct pcoords){ .a = a, .r = r2 }); - struct elem *e = elem_init("line", 6); + struct elem *e = svg_elem_init("line", 6); elem_add_attr(e, "stroke", col); elem_add_attr_double(e, "x1", cc1.x); elem_add_attr_double(e, "y1", cc1.y); @@ -185,7 +183,7 @@ int draw_numbers(int elemc, struct elem **elemv) int r = DIAMETER/2 - 33/2; for (int i = 0; i < 20; ++i) { - struct elem *e = elemv[elemc++] = elem_init("text", 5); + struct elem *e = elemv[elemc++] = svg_elem_init("text", 5); elem_add_attr(e, "font-size", "33"); elem_add_attr(e, "fill", "#fff"); elem_add_attr(e, "text-anchor", "middle"); @@ -208,11 +206,11 @@ int draw_numbers(int elemc, struct elem **elemv) void append_elemv(char *sel, int elemc, struct elem **elemv) { - EM_ASM({svgAppendElemv($0, $1, $2, $3, $4, $5, $6, $7)}, + EM_ASM({elemAppendElemv($0, $1, $2, $3, $4, $5, $6, $7, $8)}, sel, elemc, elemv, - offsetof(struct elem, name), offsetof(struct elem, n_attrs), - offsetof(struct elem, attr_names), offsetof(struct elem, attr_vals), - offsetof(struct elem, content)); + offsetof(struct elem, ns), offsetof(struct elem, name), + offsetof(struct elem, content), offsetof(struct elem, n_attrs), + offsetof(struct elem, attr_names), offsetof(struct elem, attr_vals)); } void svg_draw_board() -- cgit v1.2.3-70-g09d2