1 | const get = require('lodash/get');
|
2 | const computed = require('mutant/computed');
|
3 | const Value = require('mutant/value');
|
4 |
|
5 | const chessWorker = require ('./worker')();
|
6 |
|
7 | module.exports = () => {
|
8 |
|
9 |
|
10 | const awaitingWorkerResponses = {};
|
11 |
|
12 | |
13 |
|
14 |
|
15 |
|
16 | function validMovesForSituationObs(situationObs) {
|
17 | return computed([situationObs], (situation) => {
|
18 | const destsObs = Value({});
|
19 |
|
20 | const key = getDestsKey(situation.gameId, situation.ply);
|
21 |
|
22 | awaitingWorkerResponses[key] = destsObs;
|
23 |
|
24 | chessWorker.postMessage({
|
25 | topic: 'dests',
|
26 | payload: {
|
27 | fen: situation.fen,
|
28 | },
|
29 | reqid: {
|
30 | gameRootMessage: situation.gameId,
|
31 | ply: situation.ply,
|
32 | },
|
33 | });
|
34 |
|
35 | return destsObs;
|
36 | });
|
37 | }
|
38 |
|
39 | |
40 |
|
41 |
|
42 |
|
43 | function canClaimDrawObs(situationObs) {
|
44 |
|
45 |
|
46 | return computed([situationObs], (situation) => {
|
47 | const drawObs = Value({});
|
48 | const key = getDrawKey(situation.gameId, situation.ply);
|
49 |
|
50 | awaitingWorkerResponses[key] = drawObs;
|
51 |
|
52 | chessWorker.postMessage({
|
53 | topic: 'threefoldTest',
|
54 | payload: {
|
55 | initialFen: situation.getInitialFen(),
|
56 | pgnMoves: situation.pgnMoves,
|
57 | },
|
58 | reqid: {
|
59 | gameRootMessage: situation.gameId,
|
60 | ply: situation.ply,
|
61 | },
|
62 | });
|
63 |
|
64 | return drawObs;
|
65 | });
|
66 | }
|
67 |
|
68 |
|
69 |
|
70 | function listenForWorkerResults() {
|
71 | chessWorker.addEventListener('message', (event) => {
|
72 | const gameId = event.data.reqid.gameRootMessage;
|
73 | const { ply } = event.data.reqid;
|
74 |
|
75 | if (event.data.topic === 'dests') {
|
76 | const destsMapKey = getDestsKey(gameId, ply);
|
77 | const awaitingDestsObs = get(awaitingWorkerResponses, destsMapKey);
|
78 |
|
79 | if (awaitingDestsObs) {
|
80 | const validDests = event.data.payload.dests;
|
81 | awaitingDestsObs.set(validDests);
|
82 | delete awaitingWorkerResponses[destsMapKey];
|
83 | }
|
84 | } else if (event.data.topic === 'threefoldTest') {
|
85 | const canDrawKey = getDrawKey(gameId, ply);
|
86 |
|
87 | const awaitingCanDraw = get(awaitingWorkerResponses, canDrawKey);
|
88 |
|
89 | if (awaitingCanDraw) {
|
90 | const canClaimDraw = event.data.payload.threefoldRepetition;
|
91 | awaitingCanDraw.set(canClaimDraw);
|
92 | delete awaitingWorkerResponses[canDrawKey];
|
93 | }
|
94 | }
|
95 | });
|
96 | }
|
97 |
|
98 | function getDestsKey(gameId, ply) {
|
99 | return `${gameId}.${ply}.dests`;
|
100 | }
|
101 |
|
102 | function getDrawKey(gameId, ply) {
|
103 | return `${gameId}.${ply}.canClaimDraw`;
|
104 | }
|
105 |
|
106 | listenForWorkerResults();
|
107 |
|
108 | return {
|
109 | validMovesForSituationObs,
|
110 | canClaimDrawObs,
|
111 | };
|
112 | };
|