From 05dd0652a768ac05740d1465d30e1792b874414f Mon Sep 17 00:00:00 2001 From: David Vazgenovich Shakaryan Date: Wed, 20 Apr 2022 11:00:24 -0700 Subject: add web interface using Wasm --- web/static/dartboat.js | 260 +++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 260 insertions(+) create mode 100644 web/static/dartboat.js (limited to 'web/static/dartboat.js') diff --git a/web/static/dartboat.js b/web/static/dartboat.js new file mode 100644 index 0000000..b261f28 --- /dev/null +++ b/web/static/dartboat.js @@ -0,0 +1,260 @@ +let match_active = false; +let prompt_disable = false; +let match_state, user_rem, boat_rem; +let oi_timeout; +let delay_ms = 1000; + +const POINT_CLASSES = [180, 140, 100, 60, 40, 20, 1, 0]; + +function stcall(f, ret_type, arg_types, args) { + return Module.ccall(f, ret_type, + arg_types ? ['number'].concat(arg_types) : ['number'], + args ? [match_state].concat(args) : [match_state]); +} + +function initMatch() { + stcall('free_match'); + updateDelay(delay_ms); + match_state = stcall('start_match', 'number'); + match_active = true; + document.getElementById('user-rem').className = 'active'; + document.getElementById('match').textContent = ''; + promptSuggStr(""); + stcall('draw_match'); +} + +function oi() { + document.getElementById('oi').textContent = 'oi!'; + + oi_timeout = setTimeout(function() { oi_timeout = null; clearOi() }, 3000); +} + +function clearOi() { + document.getElementById('oi').textContent = ''; + + if (oi_timeout) { + clearTimeout(oi_timeout); + oi_timeout = null; + } +} + +function updateUserRem(rem) { + user_rem = document.getElementById('user-rem').textContent = rem; +} + +function updateBoatRem(rem) { + boat_rem = document.getElementById('boat-rem').textContent = rem; +} + +function promptMsg(p) { + document.getElementById('prompt-msg').textContent = UTF8ToString(p); +} + +function promptMsgStr(str) { + document.getElementById('prompt-msg').textContent = str; +} + +function promptSugg(p) { + document.getElementById('prompt-sugg').textContent = UTF8ToString(p); +} + +function promptSuggStr(str) { + document.getElementById('prompt-sugg').textContent = str; +} + +function promptUpdateRem() { + let elem = document.getElementById('user-rem'); + let pts = document.getElementById('prompt').textContent; + if (pts) + elem.textContent = `${user_rem} » ${user_rem - pts}`; + else + elem.textContent = user_rem; +} + +function boatTempRem(pts, str) { + let elem = document.getElementById('boat-rem'); + elem.textContent = `${boat_rem - pts} « ${boat_rem}`; + + document.getElementById('prompt').textContent = pts; + promptSuggStr(str); +} + +function promptAppend(val) { + if (!match_active || prompt_disable) return; + clearOi(); + + let elem = document.getElementById('prompt'); + if (elem.textContent.length < 3) { + elem.textContent += val; + promptUpdateRem(); + } +} + +function promptClear() { + if (!match_active || prompt_disable) return; + clearOi(); + + document.getElementById('prompt').textContent = ''; + promptUpdateRem(); +} + +function promptBackspace() { + if (!match_active || prompt_disable) return; + clearOi(); + + let elem = document.getElementById('prompt'); + elem.textContent = elem.textContent.slice(0, -1); + promptUpdateRem(); +} + +function setBoatActive() { + document.getElementById('user-rem').className = ''; + document.getElementById('boat-rem').className = 'active'; + promptMsgStr("Bot is throwing…"); + prompt_disable = true; +} + +function setUserActive() { + document.getElementById('user-rem').className = 'active'; + document.getElementById('boat-rem').className = ''; + prompt_disable = false; +} + +function promptSubmit() { + clearOi(); + if (prompt_disable) return; + if (!match_active) { + initMatch(); + return; + } + + let elem = document.getElementById('prompt'); + let p_user = elem.textContent; + if (!p_user) return; + promptClear(); + + if (!stcall('user_visit', 'number', ['number'], [p_user])) { + oi(); + return; + } + + elem = document.getElementById('match'); + elem.textContent = ''; + stcall('draw_match'); + + if (!stcall('is_match_over', 'number')) { + setBoatActive(); + stcall('boat_visit', 'number'); + } +} + +function boatVisitRes(rem, n, p1, p2, p3, ptr1, ptr2, ptr3) { + // cannot convert in timeout func because strings are freed in c func + let s1 = UTF8ToString(ptr1); + let s2 = UTF8ToString(ptr2); + let s3 = UTF8ToString(ptr3); + + if (delay_ms == 0) { + updateBoatRem(rem); + document.getElementById('match').textContent = ''; + stcall('draw_match'); + setUserActive(); + } else { + // backup to restore after bot is done + let user_sugg = document.getElementById('prompt-sugg').textContent; + promptSuggStr(''); + + setTimeout(function() { boatTempRem(p1, s1); }, delay_ms); + + if (n > 1) { + setTimeout(function() { boatTempRem(p1 + p2, `${s1}-${s2}`); }, delay_ms * 2); + } + + if (n > 2) { + setTimeout(function() { boatTempRem(p1 + p2 + p3, `${s1}-${s2}-${s3}`); }, delay_ms * 3); + } + + setTimeout(function() { + updateBoatRem(rem); + document.getElementById('prompt').textContent = ''; + document.getElementById('match').textContent = ''; + promptSuggStr(user_sugg); + stcall('draw_match'); + setUserActive(); + }, delay_ms * (n + 1)); + } +} + +function matchOver() { + match_active = false; + promptSuggStr("Press OK to play again."); + document.getElementById('user-rem').className = ''; +} + +function drawVisitNames(n1, n2) { + let elem = document.getElementById('match'); + for (let [k, v] of Object.entries({ 'user-name': n1, 'boat-name': n2 })) { + let div = document.createElement('div'); + div.className = k; + div.textContent = UTF8ToString(v); + elem.append(div); + } +} + +function drawVisit(visit_no, u_pts, u_rem, b_pts, b_rem, b_darts) { + let elem = document.getElementById('match'); + + for (let [i, v] of [visit_no, u_pts, u_rem, b_rem, b_pts, b_darts].entries()) { + let div = document.createElement('div'); + let vv = div.textContent = UTF8ToString(v); + if (i == 0) { + div.className = 'visit-no'; + } else if (i == 1 || i == 4) { + div.className = `p${POINT_CLASSES.find(x => x <= vv)}`; + } else if (i == 5) { + div.className = 'darts'; + } + elem.append(div); + } + + elem.scrollTop = elem.scrollHeight; +} + +function stdevChanged(val) { + Module.ccall('change_stdev', null, ['number', 'number'], [val, val]); +} + +function updateStdev(val) { + document.getElementById('stdev').value = val; +} + +function updateDelay(val) { + document.getElementById('delay').value = val; +} + +function delayChanged(val) { + delay_ms = val; +} + +function processKey(data) { + if (data.altKey || data.ctrlKey || data.metaKey || data.target.type == 'text') + return; + let key = data.key; + + if (isFinite(key)) + promptAppend(key); + else if (key == 'Enter') + promptSubmit(); + else if (key == 'Backspace') + promptBackspace(); +} + +function modal(id) { + document.getElementById(id).style.display = 'block'; +} + +window.onclick = function(e) { + if (e.target.classList.contains('modal')) e.target.style.display = 'none'; +} + +document.addEventListener('keydown', processKey); -- cgit v1.2.3-70-g09d2