#include "web_control.h" #include "web_dom.h" #include "web_prompt.h" #include "web_match.h" #include "web_scoreboard.h" #include #include #include #include int oi_timeout; struct prompt_state { char *msgl, *input, *msgr; }; struct prompt_state prompt_buffered, prompt_flushed; enum prompt_mode pm; void oi() { dom_elem_add_class("#oi", "visible"); oi_timeout = EM_ASM_INT({return scheduleCCall($0, $1)}, "clear_oi", 3000); } EMSCRIPTEN_KEEPALIVE void clear_oi() { if (!oi_timeout) return; dom_elem_remove_class("#oi", "visible"); EM_ASM({clearTimeout($0)}, oi_timeout); oi_timeout = 0; } 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 prompt_set_msgl(char *str) { buffer_str(str, &prompt_buffered.msgl, prompt_flushed.msgl); } void prompt_set_msgr(char *str) { buffer_str(str, &prompt_buffered.msgr, prompt_flushed.msgr); } void prompt_set_input(char *str) { buffer_str(str, &prompt_buffered.input, prompt_flushed.input); } 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 prompt_flush() { if (buffered_str_changed(prompt_buffered.msgl, prompt_flushed.msgl)) dom_elem_set_content("#prompt-msg-l", prompt_buffered.msgl); if (buffered_str_changed(prompt_buffered.msgr, prompt_flushed.msgr)) dom_elem_set_content("#prompt-msg-r", prompt_buffered.msgr); if (buffered_str_changed(prompt_buffered.input, prompt_flushed.input)) dom_elem_set_content("#prompt-input", prompt_buffered.input); free_flushed_str(prompt_flushed.msgl, prompt_buffered.msgl); free_flushed_str(prompt_flushed.msgr, prompt_buffered.msgr); free_flushed_str(prompt_flushed.input, prompt_buffered.input); prompt_flushed = prompt_buffered; } void set_prompt_mode(enum prompt_mode mode) { pm = mode; if (pm != PM_DARTBOARD) dom_elem_add_class("#prompt", "active"); else dom_elem_remove_class("#prompt", "active"); dom_elem_set_uniq_class( pm == PM_DARTBOARD ? "#keypad-dartboard" : pm == PM_SELECT_MODE ? "#keypad-select_mode" : "#keypad-default", "visible", ".keypad"); } void prompt_visit() { set_prompt_mode(PM_VISIT); prompt_set_msgl("Enter points:"); prompt_set_msgr(NULL); dom_elem_set_content("#key-submit", "OK"); dom_elem_set_content("#key-rem", "REMAINING"); } void prompt_bot_visit() { set_prompt_mode(PM_DARTBOARD); prompt_set_msgl("Bot is throwing…"); prompt_set_msgr(NULL); } void prompt_num_darts() { set_prompt_mode(PM_NUM_DARTS); prompt_set_msgl("Darts needed?"); prompt_set_msgr(NULL); dom_elem_set_content("#key-submit", "OK"); dom_elem_set_content("#key-rem", "REMAINING"); } void prompt_end_match() { scoreboard_set_player_active(-1); // sets all inactive set_prompt_mode(PM_END_MATCH); prompt_set_msgl( state->mode == M_PVC && state->legs[1]->rem <= 0 ? "Bot wins. :(" : "You win! :)"); prompt_set_msgr(NULL); dom_elem_set_content("#key-submit", "END MATCH"); dom_elem_set_content("#key-rem", "REMATCH"); } void prompt_select_mode() { dom_elem_set_uniq_class(NULL, "visible", "[id$=-info-inner]"); for (int pn = 1; pn < 3; ++pn) clear_player_info(pn); dom_elem_set_content("#visits", NULL); set_prompt_mode(PM_SELECT_MODE); prompt_set_msgl("Select match mode:"); prompt_set_msgr(NULL); } bool key_is_active(char *k) { char sel[64]; sprintf(sel, "#key-%s", k); return dom_elem_has_class(sel, "active"); } void toggle_key(char *k) { char sel[64]; sprintf(sel, "#key-%s", k); dom_elem_toggle_class(sel, "active"); } void deactivate_key(char *k) { char sel[64]; sprintf(sel, "#key-%s", k); dom_elem_remove_class(sel, "active"); } char *prompt_get() { return dom_elem_get_content("#prompt-input"); } void prompt_handle_pre(char *command) { if (pm == PM_DARTBOARD) return; clear_oi(); if ((pm == PM_VISIT || pm == PM_NUM_DARTS || pm == PM_END_MATCH) && strcmp(command, "undo")) deactivate_key("undo"); if (pm == PM_END_MATCH && strcmp(command, "rem")) deactivate_key("rem"); if (pm == PM_END_MATCH && strcmp(command, "submit")) deactivate_key("submit"); } void prompt_handle_on_change() { prompt_flush(); if (pm != PM_VISIT) return; char *str = prompt_get(); update_user_rem_from_pts(atoi(str)); free(str); } void prompt_handle_append(char *data) { if (pm != PM_SELECT_MODE && pm != PM_VISIT && pm != PM_NUM_DARTS) return; char *str = prompt_get(); size_t len_str = strlen(str); size_t len_data = strlen(data); if (len_str < 3) { str = realloc(str, len_str + len_data + 1); memcpy(str + len_str, data, len_data + 1); prompt_set_input(str); prompt_handle_on_change(); } free(str); } void prompt_handle_backspace() { if (pm == PM_DARTBOARD) return; char *str = prompt_get(); size_t len_str = strlen(str); if (len_str > 0) { str[len_str-1] = 0; prompt_set_input(str); prompt_handle_on_change(); } free(str); } void prompt_handle_clear() { if (pm == PM_DARTBOARD) return; prompt_set_input(NULL); prompt_handle_on_change(); } void prompt_handle_submit() { if (pm == PM_END_MATCH) { if (key_is_active("submit")) end_match(); toggle_key("submit"); return; } if (pm != PM_VISIT && pm != PM_NUM_DARTS && pm != PM_SELECT_MODE) return; char *str = prompt_get(); prompt_handle_clear(); if (*str) { if (pm == PM_VISIT) user_visit(atoi(str)); else if (pm == PM_NUM_DARTS) user_num_darts(atoi(str)); else if (pm == PM_SELECT_MODE) start_match(atoi(str)); } free(str); } void prompt_handle_rem() { if (pm == PM_END_MATCH) { if (key_is_active("rem")) start_match(state->mode); toggle_key("rem"); return; } if (pm != PM_VISIT) return; char *str = prompt_get(); prompt_handle_clear(); if (*str) user_visit_to_rem(atoi(str)); free(str); } void prompt_handle_undo() { if (pm != PM_VISIT && pm != PM_NUM_DARTS && pm != PM_END_MATCH) return; prompt_handle_clear(); if (key_is_active("undo")) user_undo(); toggle_key("undo"); } EMSCRIPTEN_KEEPALIVE void prompt_handle(char *command, char *data) { prompt_handle_pre(command); if (!strcmp(command, "append")) prompt_handle_append(data); else if (!strcmp(command, "backspace")) prompt_handle_backspace(); else if (!strcmp(command, "clear")) prompt_handle_clear(); else if (!strcmp(command, "submit")) prompt_handle_submit(); else if (!strcmp(command, "rem")) prompt_handle_rem(); else if (!strcmp(command, "undo")) prompt_handle_undo(); }