UNPKG

3.06 kBJavaScriptView Raw
1const get = require('lodash/get');
2const computed = require('mutant/computed');
3const Value = require('mutant/value');
4
5const chessWorker = require ('./worker')();
6
7module.exports = () => {
8 // A map of observables that are currently awaiting a response from the asynchronous
9 // chess logic webworker.
10 const awaitingWorkerResponses = {};
11
12 /**
13 * @return An observable of the valid moves for the current game position for the
14 * user
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 * @return An observable of whether the player currently playing may claim a draw.
42 */
43 function canClaimDrawObs(situationObs) {
44 // TODO: test this, use this to expose 'claim draw' button
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 // Listens for respones from the chess webworker and updates observables
69 // awaiting the response
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};