aboutsummaryrefslogtreecommitdiff
path: root/web/http
diff options
context:
space:
mode:
Diffstat (limited to 'web/http')
-rw-r--r--web/http/worker.mjs190
1 files changed, 190 insertions, 0 deletions
diff --git a/web/http/worker.mjs b/web/http/worker.mjs
new file mode 100644
index 0000000..12de1dc
--- /dev/null
+++ b/web/http/worker.mjs
@@ -0,0 +1,190 @@
1import Nissy from "./nissy_web_module.mjs"
2
3const nissy = await Nissy();
4const log = (msg) => postMessage({ command: "log", id: -1, object: msg });
5nissy.setLogger(nissy._addCallbackFunction(log));
6
7const commands = [
8 { name: "load solver data", exec: loadSolverDataFromStorage },
9 { name: "download solver data", exec: downloadSolverData },
10 { name: "generate solver data", exec: generateSolverData },
11 { name: "validate scramble", exec: validateScramble },
12 { name: "solve", exec: solve },
13];
14
15// Message structure:
16// {
17// command: string // The function to run.
18// id: number // An identification number for the command, used for
19// // sending responses back to the caller and having them
20// // caught by the correct handler.
21// arg: object // The actual argument of the message, command-specific.
22// // See below for details.
23// }
24onmessage = (event) => {
25 for (var i = 0; i < commands.length; i++) {
26 if (commands[i].name == event.data.command) {
27 commands[i].exec(event.data.id, event.data.arg);
28 console.log("[worker] Received '" + commands[i].name + "'");
29 return;
30 }
31 }
32
33 console.log("[nissy worker] unknown command " + event.data.command);
34};
35
36// Load solver data from storage.
37// Argument: string (the name of the solver)
38async function loadSolverDataFromStorage(id, solver) {
39 const async_return = (success, message = "") => postMessage({
40 command: "load solver data",
41 id: id,
42 arg: {
43 success: success,
44 message: message
45 }
46 });
47
48 if (!(await nissy.isSolverAvailable(solver))) {
49 async_return(false, "Error: solver " + solver +
50 " is not available in this version of nissy.");
51 return;
52 }
53
54 if (await nissy.isSolverLoaded(solver)) {
55 async_return(true);
56 return;
57 }
58
59 if (await nissy.initSolverFromStorage(solver)) {
60 async_return(true);
61 } else {
62 async_return(false, "Could not read data for " + solver +
63 " from local storage");
64 }
65}
66
67// Download solver data.
68// Argument: string (the name of the solver)
69async function downloadSolverData(id, solver) {
70 const async_return = (success, message = "") => postMessage({
71 command: "download solver data",
72 id: id,
73 arg: {
74 success: success,
75 message: message
76 }
77 });
78
79 if (!(await nissy.isSolverAvailable(solver))) {
80 async_return(false, "Error: solver " + arg.solver +
81 " is not available in this version of nissy.");
82 return;
83 }
84
85 if (await nissy.initSolverDownload(solver, "/tables")) {
86 async_return(true);
87 } else {
88 async_return(false, "Error retrieving solver data");
89 }
90}
91
92// Generate solver data locally.
93// Argument: string (the name of the solver)
94async function generateSolverData(id, solver) {
95 const async_return = (success, message = "") => postMessage({
96 command: "generate solver data",
97 id: id,
98 arg: {
99 success: success,
100 message: message
101 }
102 });
103
104 if (!(await nissy.isSolverAvailable(solver))) {
105 async_return(false, "Error: solver " + arg.solver +
106 " is not available in this version of nissy.");
107 return;
108 }
109
110 if (await nissy.initSolverGenerate(solver)) {
111 async_return(true);
112 } else {
113 async_return(false, "Error generating solver data");
114 }
115}
116
117// Check if the scramble is valid.
118// Argument: string (the scramble).
119async function validateScramble(id, arg) {
120 const async_return = (success) => postMessage({
121 command: "validate scramble",
122 id: id,
123 arg: success
124 });
125
126 var cube = new nissy.Cube();
127 async_return(cube.move(arg).ok());
128}
129
130// Solve the cube with the given options.
131// Argument: {
132// solver: string
133// scramble: string
134// minmoves: number
135// maxmoves: number
136// maxsolutions: number
137// optimal: number
138// threads: number
139// }
140async function solve(id, arg) {
141 const async_return = (success, solutions = [], message = "") => postMessage({
142 command: "solve",
143 id: id,
144 arg: {
145 success: success,
146 solutions: solutions,
147 message: message
148 }
149 });
150
151 if (!(await nissy.isSolverAvailable(arg.solver))) {
152 async_return(false, [], "Error: solver " + arg.solver +
153 " is not available in this version of nissy.");
154 return;
155 }
156
157 if (!(await nissy.isSolverLoaded(arg.solver)) &&
158 !(await nissy.initSolverFromStorage(arg.solver))) {
159 async_return(false, [], "Error: solver " + arg.solver + " has not been " +
160 "loaded. Its data must be donwloaded or generated before using it.");
161 return;
162 }
163
164 var cube = new nissy.Cube();
165 cube.move(arg.scramble);
166
167 // TODO: error handling here?
168 const nissFlag = ((str) => {
169 switch (str) {
170 case "inverse": return nissy.NissFlag.inverse;
171 case "mixed": return nissy.NissFlag.mixed;
172 case "linear": return nissy.NissFlag.linear;
173 case "all": return nissy.NissFlag.all;
174 default: return nissy.NissFlag.normal;
175 }
176 })(arg.nissFlag);
177
178 const result = await nissy.solve(arg.solver, cube, nissFlag, arg.minmoves,
179 arg.maxmoves, arg.maxsolutions, arg.optimal, arg.threads, id);
180
181 if (result.err.ok()) {
182 //TODO: add solution lenght?
183 var solutions = result.solutions == "" ? [] : result.solutions.split("\n");
184 solutions.pop(); // Solver always returns string ending in newline
185 async_return(true, solutions);
186 } else {
187 async_return(false, [],
188 "Error while solving (error " + result.err.value + ")");
189 }
190};

Generated with cgit - Back to sebastiano.tronto.net