diff options
| author | Sebastiano Tronto <sebastiano@tronto.net> | 2025-05-28 12:17:55 +0200 |
|---|---|---|
| committer | Sebastiano Tronto <sebastiano@tronto.net> | 2025-05-28 12:17:55 +0200 |
| commit | fcf5a819ef52ab3069f687e6943599fa3ccf96b3 (patch) | |
| tree | d969a0bb60508f7af0130051c580884cdf3c6d63 /web/http/nissyapp.mjs | |
| parent | cf2896324e60e2dc3890c658378499383100e79c (diff) | |
| download | nissy-core-fcf5a819ef52ab3069f687e6943599fa3ccf96b3.tar.gz nissy-core-fcf5a819ef52ab3069f687e6943599fa3ccf96b3.zip | |
Web solver is usable
Diffstat (limited to 'web/http/nissyapp.mjs')
| -rw-r--r-- | web/http/nissyapp.mjs | 134 |
1 files changed, 127 insertions, 7 deletions
diff --git a/web/http/nissyapp.mjs b/web/http/nissyapp.mjs index 23e74d0..b8a525c 100644 --- a/web/http/nissyapp.mjs +++ b/web/http/nissyapp.mjs | |||
| @@ -7,30 +7,149 @@ var scrField = document.getElementById("scrambleText"); | |||
| 7 | var resultsLabel = document.getElementById("resultsLabel"); | 7 | var resultsLabel = document.getElementById("resultsLabel"); |
| 8 | var resultsText = document.getElementById("results"); | 8 | var resultsText = document.getElementById("results"); |
| 9 | var solverSelector = document.getElementById("solverSelector"); | 9 | var solverSelector = document.getElementById("solverSelector"); |
| 10 | var toggleLog = document.getElementById("toggleShowLog"); | ||
| 11 | var logPane = document.getElementById("logPane"); | ||
| 10 | 12 | ||
| 11 | var lastCallbackId = 0; | 13 | var lastCallbackId = 0; |
| 12 | var callbacks = new Map(); // Values: { f: function, arg: object } | 14 | var callbacks = new Map(); // Values: { f: function, arg: object } |
| 13 | var worker = new Worker("./worker.mjs", { type: "module" }); | 15 | var worker = new Worker("./worker.mjs", { type: "module" }); |
| 14 | worker.onmessage = (event) => { | 16 | worker.onmessage = (event) => { |
| 15 | if (event.data.command == "log") { | 17 | if (event.data.command == "log") { |
| 16 | console.log(event.data.object); // TODO | 18 | logPane.innerText += event.data.object; |
| 19 | console.log(event.data.object); | ||
| 17 | } else if (!callbacks.has(event.data.id)) { | 20 | } else if (!callbacks.has(event.data.id)) { |
| 18 | console.log("[nissy app] Unknown callback " + event.data.id + | 21 | console.log("[nissy app] Unknown callback " + event.data.id + |
| 19 | " for command " + event.data.command); | 22 | " for command " + event.data.command); |
| 20 | } else { | 23 | } else { |
| 21 | var callback = callbacks.get(event.data.id); | 24 | var callback = callbacks.get(event.data.id); |
| 25 | callbacks.delete(event.data.id); | ||
| 22 | callback.f(callback.arg, event.data.arg); | 26 | callback.f(callback.arg, event.data.arg); |
| 23 | } | 27 | } |
| 24 | }; | 28 | }; |
| 25 | 29 | ||
| 26 | function updateResults(label, results, buttonState) { | 30 | function updateResults(label, results, enable) { |
| 27 | resultsLabel.innerText = label; | 31 | resultsLabel.innerText = label; |
| 28 | resultsText.innerText = results; | 32 | resultsText.innerText = results; |
| 29 | solveButton.disable = !buttonState; | 33 | solveButton.disable = !enable; |
| 34 | solverSelector.disable = !enable; | ||
| 30 | } | 35 | } |
| 31 | 36 | ||
| 37 | var logVisible = false; | ||
| 38 | toggleLog.addEventListener("click", () => { | ||
| 39 | logVisible = !logVisible; | ||
| 40 | if (logVisible) { | ||
| 41 | logPane.style.display = "block"; | ||
| 42 | toggleLog.innerText = "Hide nissy log messages"; | ||
| 43 | } else { | ||
| 44 | logPane.style.display = "none"; | ||
| 45 | toggleLog.innerText = "Show nissy log messages"; | ||
| 46 | } | ||
| 47 | }); | ||
| 48 | |||
| 32 | solveButton.addEventListener("click", () => { | 49 | solveButton.addEventListener("click", () => { |
| 33 | updateResults("Loading solutions...", "", false); | 50 | const solver = solverSelector.options[solverSelector.selectedIndex].value; |
| 51 | const scramble = scrField.value; | ||
| 52 | loadDataThenSolve(solver, scramble); | ||
| 53 | |||
| 54 | const solveCallbackId = ++lastCallbackId; | ||
| 55 | callbacks.set(solveCallbackId, { | ||
| 56 | f: (callbackArg, loadResult) => { | ||
| 57 | if (loadResult.success) { | ||
| 58 | startSolve(callbackArg.solver, callbackArg.scramble); | ||
| 59 | } else { | ||
| 60 | updateResults("", "", true); | ||
| 61 | } | ||
| 62 | }, | ||
| 63 | arg: { solver: solver, scramble: scramble } | ||
| 64 | }); | ||
| 65 | |||
| 66 | const downloadCallbackId = ++lastCallbackId; | ||
| 67 | }); | ||
| 68 | |||
| 69 | function loadDataThenSolve(solver, scramble) { | ||
| 70 | updateResults("Loading solver " + solver + "...", "", false); | ||
| 71 | |||
| 72 | const callbackId = ++lastCallbackId; | ||
| 73 | callbacks.set(callbackId, { | ||
| 74 | f: (callbackArg, loadResult) => { | ||
| 75 | if (loadResult.success) | ||
| 76 | startSolve(callbackArg.solver, callbackArg.scramble); | ||
| 77 | else | ||
| 78 | askDownloadThenSolve(callbackArg.solver, callbackArg.scramble); | ||
| 79 | }, | ||
| 80 | arg: { solver: solver, scramble: scramble } | ||
| 81 | }); | ||
| 82 | |||
| 83 | worker.postMessage({ | ||
| 84 | command: "load solver data", | ||
| 85 | id: callbackId, | ||
| 86 | arg: solver | ||
| 87 | }); | ||
| 88 | } | ||
| 89 | |||
| 90 | function askDownloadThenSolve(solver, scramble) { | ||
| 91 | var confirmDiv = document.getElementById("confirmDownload"); | ||
| 92 | var cancel = document.getElementById("confirmDownloadCancel"); | ||
| 93 | var download = document.getElementById("confirmDownloadConfirm"); | ||
| 94 | var generate = document.getElementById("confirmDownloadGenerate"); | ||
| 95 | const cleanup = () => { | ||
| 96 | confirmDiv.style.display = "none"; | ||
| 97 | |||
| 98 | // Remove event listeners by cloning the buttons | ||
| 99 | cancel.outerHTML = cancel.outerHTML; | ||
| 100 | download.outerHTML = download.outerHTML; | ||
| 101 | generate.outerHTML = generate.outerHTML; | ||
| 102 | }; | ||
| 103 | |||
| 104 | updateResults("", "", false); | ||
| 105 | confirmDiv.style.display = "block"; | ||
| 106 | |||
| 107 | cancel.addEventListener("click", cleanup); | ||
| 108 | |||
| 109 | download.addEventListener("click", () => { | ||
| 110 | cleanup(); | ||
| 111 | downloadDataThenSolve(solver, scramble); | ||
| 112 | }); | ||
| 113 | |||
| 114 | generate.addEventListener("click", () => { | ||
| 115 | cleanup(); | ||
| 116 | generateDataThenSolve(solver, scramble); | ||
| 117 | }); | ||
| 118 | } | ||
| 119 | |||
| 120 | const downloadDataThenSolve = (solver, scramble) => | ||
| 121 | downloadOrGenerateThenSolve(solver, scramble, true); | ||
| 122 | |||
| 123 | const generateDataThenSolve = (solver, scramble) => | ||
| 124 | downloadOrGenerateThenSolve(solver, scramble, false); | ||
| 125 | |||
| 126 | function downloadOrGenerateThenSolve(solver, scramble, download) { | ||
| 127 | const msg = download ? "Downloading data for " : "Generating data for "; | ||
| 128 | const command = download ? "download solver data" : "generate solver data"; | ||
| 129 | |||
| 130 | updateResults(msg + solver + "...", "", false); | ||
| 131 | |||
| 132 | const callbackId = ++lastCallbackId; | ||
| 133 | callbacks.set(callbackId, { | ||
| 134 | f: (callbackArg, loadResult) => { | ||
| 135 | if (loadResult.success) | ||
| 136 | startSolve(callbackArg.solver, callbackArg.scramble); | ||
| 137 | else | ||
| 138 | updateResults("Failed", loadResult.message, true); | ||
| 139 | }, | ||
| 140 | arg: { solver: solver, scramble: scramble } | ||
| 141 | }); | ||
| 142 | |||
| 143 | worker.postMessage({ | ||
| 144 | command: command, | ||
| 145 | id: callbackId, | ||
| 146 | arg: solver | ||
| 147 | }); | ||
| 148 | } | ||
| 149 | |||
| 150 | function startSolve(solver, scramble) { | ||
| 151 | updateResults("Solving...", "", false); | ||
| 152 | |||
| 34 | const callbackId = ++lastCallbackId; | 153 | const callbackId = ++lastCallbackId; |
| 35 | callbacks.set(callbackId, { | 154 | callbacks.set(callbackId, { |
| 36 | f: (callbackArg, solveResult) => { | 155 | f: (callbackArg, solveResult) => { |
| @@ -46,12 +165,13 @@ solveButton.addEventListener("click", () => { | |||
| 46 | }, | 165 | }, |
| 47 | arg: "" // Currently unused | 166 | arg: "" // Currently unused |
| 48 | }); | 167 | }); |
| 168 | |||
| 49 | worker.postMessage({ | 169 | worker.postMessage({ |
| 50 | command: "solve", | 170 | command: "solve", |
| 51 | id: callbackId, | 171 | id: callbackId, |
| 52 | arg: { | 172 | arg: { |
| 53 | solver: solverSelector.options[solverSelector.selectedIndex].value, | 173 | solver: solver, |
| 54 | scramble: scrField.value, | 174 | scramble: scramble, |
| 55 | minmoves: 0, | 175 | minmoves: 0, |
| 56 | maxmoves: 20, | 176 | maxmoves: 20, |
| 57 | maxsolutions: 1, | 177 | maxsolutions: 1, |
| @@ -59,4 +179,4 @@ solveButton.addEventListener("click", () => { | |||
| 59 | threads: window.navigator.hardwareConcurrency, | 179 | threads: window.navigator.hardwareConcurrency, |
| 60 | } | 180 | } |
| 61 | }); | 181 | }); |
| 62 | }); | 182 | } |
