aboutsummaryrefslogtreecommitdiff
path: root/web/worker.mjs
blob: dca980e06cb8ae5d0891173c4f2f8ac6a2998daf (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
import Nissy from "./nissy_web_module.mjs"

const nissy = await Nissy();
function log(message) {
  postMessage({ command: "log", id: -1, object: message });
  console.log(message);
}
nissy.setLogger(nissy._addCallbackFunction(log));

const commands = [
    { name: "solve", exec: solve },
    { name: "download solver data", exec: downloadSolverData },
];

// Message structure:
// {
//   command: string // The function to run.
//   id: number      // An identification number for the command, used for
//                   // sending responses back to the caller and having them
//                   // caught by the correct handler.
//   arg: object     // The actual argument of the message, command-specific.
//                   // See below for details.
// }
onmessage = (event) => {
  for (var i = 0; i < commands.length; i++) {
    if (commands[i].name == event.data.command) {
      commands[i].exec(event.data.id, event.data.arg);
      return;
    }
  }
 
  log("[nissy worker] unknown command " + event.data.command);
};

// Download solver data.
// Argument: string
async function downloadSolverData(id, solver) {
  const downloadSolverDataReturn = (success, message = "") => postMessage({
    command: "download solver data",
    id: id,
    arg: {
      success: success,
      message: message
    }
  });

  if (await nissy.initSolverDownload(arg.solver, "/tables")) {
    downloadSolverDataReturn(true);
  } else {
    downloadSolverDataReturn(false, "Error retrieving the solver data");
  }
}

// Solve the cube with the given options.
// Argument: {
//   solver: string
//   scramble: string
//   minmoves: number
//   maxmoves: number
//   maxsolutions: number
//   optimal: number
//   threads: number
// }
async function solve(id, arg) {
  const solveReturn = (success, solutions = [], message = "") => postMessage({
    command: "solve",
    id: id,
    arg: {
      success: success,
      solutions: solutions,
      message: message
    }
  });

  if (!(await nissy.isSolverAvailable(arg.solver))) {
    solveReturn(false, [], "Error: solver " + arg.solver +
      " is not available in this version of nissy.");
    return;
  }

  if (!(await nissy.isSolverLoaded(arg.solver)) &&
      !(await nissy.initSolverFromStorage(arg.solver))) {
    solveReturn(false, [], "Error: solver " + arg.solver + " has not been " +
      "loaded. Its data must be donwloaded or generated before using it.");
    return;
  }

  var cube = new nissy.Cube();
  cube.move(arg.scramble);

  // TODO: error handling here?
  const nissFlag = ((str) => {
    switch (str) {
      case "inverse": return nissy.NissFlag.inverse;
      case "mixed": return nissy.NissFlag.mixed;
      case "linear": return nissy.NissFlag.linear;
      case "all": return nissy.NissFlag.all;
      default: return nissy.NissFlag.normal;
    }
  })(arg.nissFlag);

  const result = await nissy.solve(arg.solver, cube, nissFlag, arg.minmoves,
    arg.maxmoves, arg.maxsolutions, arg.optimal, arg.threads, id);

  if (result.err.ok()) {
    //TODO: add solution lenght?
    var solutions = result.solutions == "" ? [] : result.solutions.split("\n");
    solutions.pop(); // Solver always returns string ending in newline
    solveReturn(true, solutions);
  } else {
    solveReturn(false, [],
      "Error while solving (error " + result.err.value + ")");
  }
};

Generated with cgit - Back to sebastiano.tronto.net