summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDavid Vazgenovich Shakaryan <dvshakaryan@gmail.com>2022-05-02 15:20:34 -0700
committerDavid Vazgenovich Shakaryan <dvshakaryan@gmail.com>2022-05-02 15:20:34 -0700
commit237359d107c5f8fb3e1f7a3532696eb19a6c56fc (patch)
tree192f6007e9a59c334477dd6ab6ce209b067614ba
parent09c23f60189223db58d98e49ee94df947667662d (diff)
downloaddartboat-237359d107c5f8fb3e1f7a3532696eb19a6c56fc.tar.gz
dartboat-237359d107c5f8fb3e1f7a3532696eb19a6c56fc.tar.xz
web: buffer player info and flush on state change
Constant calls from Wasm to JS to replace unchanged elements in the DOM is not very efficient.
-rw-r--r--web/static/dartboat.js6
-rw-r--r--web/web_control.c19
-rw-r--r--web/web_ui.c100
-rw-r--r--web/web_ui.h6
4 files changed, 113 insertions, 18 deletions
diff --git a/web/static/dartboat.js b/web/static/dartboat.js
index 8716185..13a5da4 100644
--- a/web/static/dartboat.js
+++ b/web/static/dartboat.js
@@ -98,15 +98,15 @@ function hidePlayerInfo(n) {
}
function updatePlayerName(n, ptr) {
- $(`#p${n}-name`).textContent = UTF8ToString(ptr);
+ $(`#p${n}-name`).textContent = ptr && UTF8ToString(ptr);
}
function updatePlayerRem(n, ptr) {
- $(`#p${n}-rem`).textContent = UTF8ToString(ptr);
+ $(`#p${n}-rem`).textContent = ptr && UTF8ToString(ptr);
}
function updatePlayerSugg(n, ptr) {
- $(`#p${n}-sugg`).textContent = UTF8ToString(ptr);
+ $(`#p${n}-sugg`).textContent = ptr && UTF8ToString(ptr);
}
function updatePlayerAvg(n, avg) {
diff --git a/web/web_control.c b/web/web_control.c
index 13e37ec..4f78d67 100644
--- a/web/web_control.c
+++ b/web/web_control.c
@@ -33,6 +33,7 @@ EMSCRIPTEN_KEEPALIVE
void update_user_rem_from_pts(int pts)
{
update_player_rem(state->active_player, state->active_leg->rem - pts);
+ ui_flush_player_info(state->active_player);
}
EMSCRIPTEN_KEEPALIVE
@@ -40,7 +41,7 @@ void end_boat_visit(int rem, double avg)
{
EM_ASM(svgClearPoints());
update_player_rem(2, rem);
- EM_ASM({updatePlayerAvg($0, $1)}, 2, avg);
+ ui_set_player_avg(2, avg);
EM_ASM({setPromptInput($0)}, "");
EM_ASM({promptMsgR($0)}, "");
@@ -114,6 +115,8 @@ void handle_next()
boat_visit();
}
}
+
+ ui_flush();
}
EMSCRIPTEN_KEEPALIVE
@@ -156,7 +159,7 @@ void user_undo()
if (state->num_darts) {
state->num_darts = 0;
- EM_ASM({updatePlayerAvg($0, $1)}, state->active_player,
+ ui_set_player_avg(state->active_player,
((double)(state->active_leg->start -
state->active_leg->visits[
state->active_leg->n_visits-2].rem) /
@@ -186,10 +189,10 @@ void user_undo()
++state->boat_undone;
}
- update_player_avg(state->active_player, 0);
+ ui_set_player_avg(state->active_player, 0);
update_player_rem(state->active_player, l->rem);
if (state->mode == M_PVC) {
- update_player_avg(2, 0);
+ ui_set_player_avg(2, 0);
update_player_rem(2, state->legs[1]->rem);
}
@@ -229,15 +232,15 @@ void start_match(int mode)
state->legs[1] = leg_init(501, mode == M_PVC ? "Bot" : "Player 2");
EM_ASM({showPlayerInfo($0)}, 1);
- EM_ASM({updatePlayerName($0, $1)}, 1, state->legs[0]->name);
+ update_player_name(1, state->legs[0]->name);
update_player_rem(1, state->legs[0]->rem);
- EM_ASM({updatePlayerAvg($0, $1)}, 1, 0);
+ update_player_avg(1, 0);
if (mode != M_P) {
EM_ASM({showPlayerInfo($0)}, 2);
- EM_ASM({updatePlayerName($0, $1)}, 2, state->legs[1]->name);
+ update_player_name(2, state->legs[1]->name);
update_player_rem(2, state->legs[1]->rem);
- EM_ASM({updatePlayerAvg($0, $1)}, 2, 0);
+ update_player_avg(2, 0);
}
draw_visits();
diff --git a/web/web_ui.c b/web/web_ui.c
index 7ac4182..070b898 100644
--- a/web/web_ui.c
+++ b/web/web_ui.c
@@ -12,6 +12,90 @@
#include <emscripten/emscripten.h>
+struct player_info {
+ char *name, *rem, *sugg;
+ double avg;
+};
+
+struct player_info buffered_info[2], flushed_info[2];
+
+static inline void buffer_str(char *str, char **buffer, char *flushed)
+{
+ if (str == *buffer || (str && *buffer && !strcmp(str, *buffer)))
+ return;
+
+ if (*buffer && *buffer != flushed)
+ free(*buffer);
+
+ *buffer = str ? strdup(str) : NULL;
+}
+
+void ui_set_player_name(int pn, char *str)
+{
+ buffer_str(str, &buffered_info[pn-1].name, flushed_info[pn-1].name);
+}
+
+void ui_set_player_rem(int pn, char *str)
+{
+ buffer_str(str, &buffered_info[pn-1].rem, flushed_info[pn-1].rem);
+}
+
+void ui_set_player_sugg(int pn, char *str)
+{
+ buffer_str(str, &buffered_info[pn-1].sugg, flushed_info[pn-1].sugg);
+}
+
+void ui_set_player_avg(int pn, double avg)
+{
+ buffered_info[pn-1].avg = avg;
+}
+
+static inline bool buffered_str_changed(char *buffered, char *flushed)
+{
+ return (!buffered != !flushed) ||
+ (buffered && flushed && strcmp(buffered, flushed));
+}
+
+static inline void free_flushed_str(char *flushed, char *buffered)
+{
+ if (flushed && flushed != buffered)
+ free(flushed);
+}
+
+void ui_flush_player_info(int pn)
+{
+ if (buffered_str_changed(buffered_info[pn-1].name,
+ flushed_info[pn-1].name))
+ EM_ASM({updatePlayerName($0, $1)}, pn, buffered_info[pn-1].name);
+
+ if (buffered_str_changed(buffered_info[pn-1].rem,
+ flushed_info[pn-1].rem))
+ EM_ASM({updatePlayerRem($0, $1)}, pn, buffered_info[pn-1].rem);
+
+ if (buffered_str_changed(buffered_info[pn-1].sugg,
+ flushed_info[pn-1].sugg))
+ EM_ASM({updatePlayerSugg($0, $1)}, pn, buffered_info[pn-1].sugg);
+
+ if (buffered_info[pn-1].avg != flushed_info[pn-1].avg)
+ EM_ASM({updatePlayerAvg($0, $1)}, pn, buffered_info[pn-1].avg);
+
+ free_flushed_str(flushed_info[pn-1].name, buffered_info[pn-1].name);
+ free_flushed_str(flushed_info[pn-1].rem, buffered_info[pn-1].rem);
+ free_flushed_str(flushed_info[pn-1].sugg, buffered_info[pn-1].sugg);
+ flushed_info[pn-1] = buffered_info[pn-1];
+}
+
+void ui_flush()
+{
+ ui_flush_player_info(1);
+ ui_flush_player_info(2);
+}
+
+void update_player_name(int pn, char *str)
+{
+ ui_set_player_name(pn, str);
+}
+
void update_player_sugg(int pn, int rem)
{
char str[15] = {0}, *p = str;
@@ -25,13 +109,13 @@ void update_player_sugg(int pn, int rem)
}
}
- EM_ASM({updatePlayerSugg($0, $1)}, pn, str);
+ ui_set_player_sugg(pn, str);
}
void update_player_avg(int pn, int n_darts)
{
struct leg *l = state->legs[pn-1];
- EM_ASM({updatePlayerAvg($0, $1)}, pn,
+ ui_set_player_avg(pn,
l->n_visits ?
(l->rem > 0 ? ((double)(l->start - l->rem) / l->n_visits) :
((double)l->start / (((l->n_visits - 1) * 3) + n_darts) * 3)) :
@@ -88,17 +172,17 @@ void update_player_rem(int pn, int rem)
else
sprintf(str, "%d", rem);
- EM_ASM({updatePlayerRem($0, $1)}, pn, str);
+ ui_set_player_rem(pn, str);
if (pn == 1 || state->mode != M_PVC)
update_player_sugg(pn, rem);
}
void clear_player_info(int pn)
{
- EM_ASM({updatePlayerName($0, $1)}, pn, "");
- EM_ASM({updatePlayerRem($0, $1)}, pn, "");
- EM_ASM({updatePlayerSugg($0, $1)}, pn, "");
- EM_ASM({updatePlayerAvg($0, $1)}, pn, 0);
+ ui_set_player_name(pn, "");
+ ui_set_player_rem(pn, "");
+ ui_set_player_sugg(pn, "");
+ ui_set_player_avg(pn, 0);
}
EMSCRIPTEN_KEEPALIVE
@@ -116,6 +200,8 @@ void draw_boat_throwing(int pts, char *str, double x, double y)
EM_ASM({setPromptInput($0)}, pts_str);
EM_ASM({promptMsgR($0)}, str);
free(str);
+
+ ui_flush_player_info(2); // FIXME bot hard-coded as player 2
}
bool is_key_active(char *k)
diff --git a/web/web_ui.h b/web/web_ui.h
index fa961fb..a302e0a 100644
--- a/web/web_ui.h
+++ b/web/web_ui.h
@@ -3,6 +3,12 @@
#include <stdbool.h>
+void ui_flush();
+
+void ui_flush_player_info(int pn);
+void ui_set_player_avg(int pn, double avg);
+
+void update_player_name(int pn, char *str);
void update_player_sugg(int pn, int rem);
void update_player_avg(int pn, int n_darts);
void update_player_rem(int pn, int rem);