snakeia-server 1.1.5 → 1.2.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.drone.yml +2 -1
- package/GameEngineMultithreading.js +111 -54
- package/GameEngineMultithreadingController.js +144 -101
- package/Player.js +132 -0
- package/README.md +40 -4
- package/assets/css/dark-theme.css +103 -0
- package/config/default.json +4 -1
- package/package.json +6 -6
- package/server.js +159 -193
- package/views/admin.html +7 -0
- package/views/authentication.html +7 -0
- package/views/banned.html +7 -0
- package/views/index.html +7 -0
package/.drone.yml
CHANGED
|
@@ -23,20 +23,57 @@ const Position = snakeia.Position;
|
|
|
23
23
|
const Grid = snakeia.Grid;
|
|
24
24
|
const Snake = snakeia.Snake;
|
|
25
25
|
const GameEngine = snakeia.GameEngine;
|
|
26
|
-
const seedrandom = require("seedrandom");
|
|
27
26
|
|
|
28
27
|
let game;
|
|
29
28
|
|
|
30
29
|
function copySnakes(snakes) {
|
|
31
|
-
|
|
30
|
+
const snakesCopy = [];
|
|
32
31
|
|
|
33
|
-
if(
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
32
|
+
if(snakes) {
|
|
33
|
+
snakes.forEach(snake => {
|
|
34
|
+
if(snake) {
|
|
35
|
+
const snakeCopy = new Snake();
|
|
36
|
+
|
|
37
|
+
snakeCopy.color = snake.color;
|
|
38
|
+
snakeCopy.direction = snake.direction;
|
|
39
|
+
snakeCopy.errorInit = snake.errorInit;
|
|
40
|
+
snakeCopy.gameOver = snake.gameOver;
|
|
41
|
+
snakeCopy.autoRetry = snake.autoRetry;
|
|
42
|
+
snakeCopy.aiLevel = snake.aiLevel;
|
|
43
|
+
|
|
44
|
+
if(snake.lastTail) {
|
|
45
|
+
snakeCopy.lastTail = JSON.parse(JSON.stringify(snake.lastTail));
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
if(snake.lastHead) {
|
|
49
|
+
snakeCopy.lastHead = JSON.parse(JSON.stringify(snake.lastHead));
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
snakeCopy.lastTailMoved = snake.lastTailMoved;
|
|
53
|
+
snakeCopy.lastHeadMoved = snake.lastHeadMoved;
|
|
54
|
+
snakeCopy.name = snake.name;
|
|
55
|
+
snakeCopy.player = snake.player;
|
|
56
|
+
|
|
57
|
+
if(snake.queue) {
|
|
58
|
+
snakeCopy.queue = JSON.parse(JSON.stringify(snake.queue));
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
snakeCopy.score = snake.score;
|
|
62
|
+
snakeCopy.scoreMax = snake.scoreMax;
|
|
63
|
+
snakeCopy.ticksDead = snake.ticksDead;
|
|
64
|
+
snakeCopy.ticksWithoutAction = snake.ticksWithoutAction;
|
|
65
|
+
snakeCopy.grid = null;
|
|
66
|
+
|
|
67
|
+
if(snake.snakeAI && snake.snakeAI.aiLevelText) {
|
|
68
|
+
snakeCopy.snakeAI.aiLevelText = snake.snakeAI.aiLevelText;
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
snakesCopy.push(snakeCopy);
|
|
72
|
+
}
|
|
73
|
+
});
|
|
37
74
|
}
|
|
38
75
|
|
|
39
|
-
return
|
|
76
|
+
return snakesCopy;
|
|
40
77
|
}
|
|
41
78
|
|
|
42
79
|
function copyGrid(grid) {
|
|
@@ -51,35 +88,22 @@ function copyGrid(grid) {
|
|
|
51
88
|
}
|
|
52
89
|
|
|
53
90
|
function parseSnakes(snakes, grid) {
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
}
|
|
57
|
-
|
|
58
|
-
grid = Object.assign(new Grid(), grid);
|
|
59
|
-
|
|
60
|
-
if(!snakes && game) {
|
|
61
|
-
snakes = game.snakes;
|
|
62
|
-
}
|
|
63
|
-
|
|
64
|
-
for(var i = 0; i < snakes.length; i++) {
|
|
65
|
-
snakes[i].grid = grid;
|
|
66
|
-
snakes[i] = Object.assign(new Snake(), snakes[i]);
|
|
67
|
-
|
|
68
|
-
for(var j = 0; j < snakes[i].queue.length; j++) {
|
|
69
|
-
snakes[i].queue[j] = Object.assign(new Position(), snakes[i].queue[j]);
|
|
70
|
-
}
|
|
91
|
+
let gridCopy = game ? (grid ?? game.grid) : grid;
|
|
92
|
+
gridCopy = Object.assign(new Grid(), gridCopy);
|
|
71
93
|
|
|
72
|
-
|
|
73
|
-
|
|
94
|
+
snakes = snakes ?? game?.snakes;
|
|
95
|
+
const snakesCopy = (Array.isArray(snakes) ? snakes : [snakes]).map(snake => {
|
|
96
|
+
const newSnake = Object.assign(new Snake(), snake);
|
|
97
|
+
newSnake.grid = gridCopy;
|
|
98
|
+
newSnake.queue = newSnake.queue.map(pos => Object.assign(new Position(), pos));
|
|
99
|
+
return newSnake;
|
|
100
|
+
});
|
|
74
101
|
|
|
75
|
-
return {
|
|
76
|
-
grid: grid,
|
|
77
|
-
snakes: snakes
|
|
78
|
-
};
|
|
102
|
+
return { grid: gridCopy, snakes: snakesCopy };
|
|
79
103
|
}
|
|
80
104
|
|
|
81
105
|
if(!isMainThread) {
|
|
82
|
-
parentPort.on("message",
|
|
106
|
+
parentPort.on("message", async data => {
|
|
83
107
|
const type = data.type;
|
|
84
108
|
const keys = Object.keys(data);
|
|
85
109
|
|
|
@@ -89,19 +113,17 @@ if(!isMainThread) {
|
|
|
89
113
|
const snakes = parsed["snakes"];
|
|
90
114
|
|
|
91
115
|
if(!game) {
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
"errorOccurred": game.errorOccurred
|
|
104
|
-
});
|
|
116
|
+
try {
|
|
117
|
+
game = new GameEngine(grid, snakes, data.speed, data.enablePause, data.enableRetry, data.progressiveSpeed, data.aiStuckLimit, data.disableStuckAIDetection, data.aiUltraModelSettings);
|
|
118
|
+
await initGame();
|
|
119
|
+
} catch(e) {
|
|
120
|
+
console.error(e);
|
|
121
|
+
|
|
122
|
+
parentPort.postMessage({
|
|
123
|
+
type: "init",
|
|
124
|
+
errorOccurred: true
|
|
125
|
+
});
|
|
126
|
+
}
|
|
105
127
|
|
|
106
128
|
game.onReset(() => {
|
|
107
129
|
parentPort.postMessage({
|
|
@@ -127,7 +149,8 @@ if(!isMainThread) {
|
|
|
127
149
|
"getInfosGame": false,
|
|
128
150
|
"errorOccurred": game.errorOccurred,
|
|
129
151
|
"aiStuck": game.aiStuck,
|
|
130
|
-
"precAiStuck": false
|
|
152
|
+
"precAiStuck": false,
|
|
153
|
+
"engineLoading": game.engineLoading
|
|
131
154
|
});
|
|
132
155
|
});
|
|
133
156
|
|
|
@@ -144,7 +167,8 @@ if(!isMainThread) {
|
|
|
144
167
|
"confirmExit": false,
|
|
145
168
|
"getInfos": false,
|
|
146
169
|
"getInfosGame": false,
|
|
147
|
-
"errorOccurred": game.errorOccurred
|
|
170
|
+
"errorOccurred": game.errorOccurred,
|
|
171
|
+
"engineLoading": game.engineLoading
|
|
148
172
|
});
|
|
149
173
|
});
|
|
150
174
|
|
|
@@ -156,7 +180,8 @@ if(!isMainThread) {
|
|
|
156
180
|
"confirmExit": false,
|
|
157
181
|
"getInfos": false,
|
|
158
182
|
"getInfosGame": false,
|
|
159
|
-
"errorOccurred": game.errorOccurred
|
|
183
|
+
"errorOccurred": game.errorOccurred,
|
|
184
|
+
"engineLoading": game.engineLoading
|
|
160
185
|
});
|
|
161
186
|
});
|
|
162
187
|
|
|
@@ -167,7 +192,8 @@ if(!isMainThread) {
|
|
|
167
192
|
"confirmExit": false,
|
|
168
193
|
"getInfos": false,
|
|
169
194
|
"getInfosGame": false,
|
|
170
|
-
"errorOccurred": game.errorOccurred
|
|
195
|
+
"errorOccurred": game.errorOccurred,
|
|
196
|
+
"engineLoading": game.engineLoading
|
|
171
197
|
});
|
|
172
198
|
});
|
|
173
199
|
|
|
@@ -182,7 +208,8 @@ if(!isMainThread) {
|
|
|
182
208
|
"confirmExit": false,
|
|
183
209
|
"getInfos": false,
|
|
184
210
|
"getInfosGame": false,
|
|
185
|
-
"errorOccurred": game.errorOccurred
|
|
211
|
+
"errorOccurred": game.errorOccurred,
|
|
212
|
+
"engineLoading": game.engineLoading
|
|
186
213
|
});
|
|
187
214
|
});
|
|
188
215
|
|
|
@@ -197,7 +224,8 @@ if(!isMainThread) {
|
|
|
197
224
|
"confirmExit": false,
|
|
198
225
|
"getInfos": false,
|
|
199
226
|
"getInfosGame": false,
|
|
200
|
-
"errorOccurred": game.errorOccurred
|
|
227
|
+
"errorOccurred": game.errorOccurred,
|
|
228
|
+
"engineLoading": game.engineLoading
|
|
201
229
|
});
|
|
202
230
|
});
|
|
203
231
|
|
|
@@ -214,7 +242,8 @@ if(!isMainThread) {
|
|
|
214
242
|
"confirmExit": false,
|
|
215
243
|
"getInfos": false,
|
|
216
244
|
"getInfosGame": false,
|
|
217
|
-
"errorOccurred": game.errorOccurred
|
|
245
|
+
"errorOccurred": game.errorOccurred,
|
|
246
|
+
"engineLoading": game.engineLoading
|
|
218
247
|
});
|
|
219
248
|
});
|
|
220
249
|
|
|
@@ -243,7 +272,8 @@ if(!isMainThread) {
|
|
|
243
272
|
"numFruit": game.numFruit,
|
|
244
273
|
"offsetFrame": 0,
|
|
245
274
|
"errorOccurred": game.errorOccurred,
|
|
246
|
-
"aiStuck": game.aiStuck
|
|
275
|
+
"aiStuck": game.aiStuck,
|
|
276
|
+
"engineLoading": game.engineLoading
|
|
247
277
|
});
|
|
248
278
|
});
|
|
249
279
|
|
|
@@ -266,14 +296,25 @@ if(!isMainThread) {
|
|
|
266
296
|
"speed": game.speed,
|
|
267
297
|
"countBeforePlay": game.countBeforePlay,
|
|
268
298
|
"numFruit": game.numFruit,
|
|
269
|
-
"errorOccurred": game.errorOccurred
|
|
299
|
+
"errorOccurred": game.errorOccurred,
|
|
300
|
+
"engineLoading": game.engineLoading
|
|
270
301
|
});
|
|
271
302
|
});
|
|
272
303
|
} else {
|
|
273
304
|
game.snakes = snakes;
|
|
274
305
|
game.grid = grid;
|
|
275
306
|
game.countBeforePlay = 3;
|
|
276
|
-
|
|
307
|
+
|
|
308
|
+
try {
|
|
309
|
+
await initGame();
|
|
310
|
+
} catch(e) {
|
|
311
|
+
console.error(e);
|
|
312
|
+
|
|
313
|
+
parentPort.postMessage({
|
|
314
|
+
type: "init",
|
|
315
|
+
errorOccurred: true
|
|
316
|
+
});
|
|
317
|
+
}
|
|
277
318
|
}
|
|
278
319
|
} else if(game) {
|
|
279
320
|
switch(type) {
|
|
@@ -347,4 +388,20 @@ if(!isMainThread) {
|
|
|
347
388
|
}
|
|
348
389
|
}
|
|
349
390
|
});
|
|
391
|
+
}
|
|
392
|
+
|
|
393
|
+
async function initGame() {
|
|
394
|
+
await game.init();
|
|
395
|
+
|
|
396
|
+
parentPort.postMessage({
|
|
397
|
+
type: "init",
|
|
398
|
+
"snakes": copySnakes(game.snakes),
|
|
399
|
+
"grid": copyGrid(game.grid),
|
|
400
|
+
"enablePause": game.enablePause,
|
|
401
|
+
"enableRetry": game.enableRetry,
|
|
402
|
+
"progressiveSpeed": game.progressiveSpeed,
|
|
403
|
+
"offsetFrame": game.speed * GameConstants.Setting.TIME_MULTIPLIER,
|
|
404
|
+
"errorOccurred": game.errorOccurred,
|
|
405
|
+
"engineLoading": game.engineLoading
|
|
406
|
+
});
|
|
350
407
|
}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
/*
|
|
2
|
-
* Copyright (C) 2020 Eliastik (eliastiksofts.com)
|
|
2
|
+
* Copyright (C) 2020-2025 Eliastik (eliastiksofts.com)
|
|
3
3
|
*
|
|
4
4
|
* This file is part of "SnakeIA Server".
|
|
5
5
|
*
|
|
@@ -16,7 +16,7 @@
|
|
|
16
16
|
* You should have received a copy of the GNU General Public License
|
|
17
17
|
* along with "SnakeIA Server". If not, see <http://www.gnu.org/licenses/>.
|
|
18
18
|
*/
|
|
19
|
-
const { Worker } = require(
|
|
19
|
+
const { Worker } = require("worker_threads");
|
|
20
20
|
const snakeia = require("snakeia");
|
|
21
21
|
const GameEngine = snakeia.GameEngine;
|
|
22
22
|
const Grid = snakeia.Grid;
|
|
@@ -25,132 +25,157 @@ const Position = snakeia.Position;
|
|
|
25
25
|
let logger;
|
|
26
26
|
|
|
27
27
|
class GameEngineMultithreadingController extends GameEngine {
|
|
28
|
-
|
|
29
|
-
|
|
28
|
+
|
|
29
|
+
constructor(grid, snakes, speed, enablePause, enableRetry, progressiveSpeed, aiStuckLimit, disableStuckAIDetection, aiUltraModelSettings) {
|
|
30
|
+
super(grid, snakes, speed, enablePause, enableRetry, progressiveSpeed, aiStuckLimit, disableStuckAIDetection, aiUltraModelSettings);
|
|
30
31
|
this.worker = new Worker("./GameEngineMultithreading.js");
|
|
32
|
+
this.workerReady = false;
|
|
33
|
+
this.messageQueue = []; // Queue of message if the worker is still loading
|
|
31
34
|
this.eventsInit = false;
|
|
32
35
|
}
|
|
33
36
|
|
|
34
|
-
init() {
|
|
37
|
+
async init() {
|
|
35
38
|
if(!this.eventsInit) {
|
|
36
|
-
this.
|
|
37
|
-
|
|
38
|
-
const dataKeys = Object.keys(data);
|
|
39
|
+
this.initEventHandlers();
|
|
40
|
+
}
|
|
39
41
|
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
42
|
+
if(this.grid) {
|
|
43
|
+
this.grid.rngGrid = null;
|
|
44
|
+
this.grid.rngGame = null;
|
|
45
|
+
}
|
|
43
46
|
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
47
|
+
return new Promise(resolve => {
|
|
48
|
+
const handleMessage = (data) => {
|
|
49
|
+
if(data.type === "init") {
|
|
50
|
+
this.worker.off("message", handleMessage);
|
|
51
|
+
resolve();
|
|
52
|
+
}
|
|
53
|
+
};
|
|
54
|
+
|
|
55
|
+
this.worker.on("message", handleMessage);
|
|
56
|
+
|
|
57
|
+
this.worker.postMessage({
|
|
58
|
+
type: "init",
|
|
59
|
+
grid: this.grid,
|
|
60
|
+
snakes: this.snakes,
|
|
61
|
+
speed: this.speed,
|
|
62
|
+
enablePause: this.enablePause,
|
|
63
|
+
enableRetry: this.enableRetry,
|
|
64
|
+
progressiveSpeed: this.progressiveSpeed,
|
|
65
|
+
aiStuckLimit: this.aiStuckLimit,
|
|
66
|
+
disableStuckAIDetection: this.disableStuckAIDetection,
|
|
67
|
+
aiUltraModelSettings: this.aiUltraModelSettings
|
|
68
|
+
});
|
|
69
|
+
});
|
|
70
|
+
}
|
|
58
71
|
|
|
59
|
-
|
|
60
|
-
|
|
72
|
+
initEventHandlers() {
|
|
73
|
+
this.worker.on("message", data => {
|
|
74
|
+
const type = data.type;
|
|
75
|
+
const dataKeys = Object.keys(data);
|
|
76
|
+
|
|
77
|
+
if (dataKeys.length > 1) {
|
|
78
|
+
let grid = this.grid;
|
|
79
|
+
let snakes = this.snakes;
|
|
80
|
+
|
|
81
|
+
if (data.grid) {
|
|
82
|
+
grid = Object.assign(new Grid(), data.grid);
|
|
83
|
+
data.grid = grid;
|
|
84
|
+
}
|
|
61
85
|
|
|
62
|
-
|
|
63
|
-
|
|
86
|
+
if (data.snakes) {
|
|
87
|
+
for (let i = 0; i < data.snakes.length; i++) {
|
|
88
|
+
data.snakes[i].grid = grid;
|
|
89
|
+
data.snakes[i] = Object.assign(new Snake(), data.snakes[i]);
|
|
64
90
|
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
this[dataKeys[i]] = data[dataKeys[i]];
|
|
91
|
+
for (let j = 0; j < data.snakes[i].queue.length; j++) {
|
|
92
|
+
data.snakes[i].queue[j] = Object.assign(new Position(), data.snakes[i].queue[j]);
|
|
68
93
|
}
|
|
69
94
|
}
|
|
70
|
-
}
|
|
71
95
|
|
|
72
|
-
|
|
73
|
-
case "reset":
|
|
74
|
-
this.reactor.dispatchEvent("onReset");
|
|
75
|
-
break;
|
|
76
|
-
case "start":
|
|
77
|
-
this.reactor.dispatchEvent("onStart");
|
|
78
|
-
break;
|
|
79
|
-
case "pause":
|
|
80
|
-
this.reactor.dispatchEvent("onPause");
|
|
81
|
-
break;
|
|
82
|
-
case "continue":
|
|
83
|
-
this.reactor.dispatchEvent("onContinue");
|
|
84
|
-
break;
|
|
85
|
-
case "stop":
|
|
86
|
-
this.reactor.dispatchEvent("onStop");
|
|
87
|
-
break;
|
|
88
|
-
case "exit":
|
|
89
|
-
this.reactor.dispatchEvent("onExit");
|
|
90
|
-
break;
|
|
91
|
-
case "kill":
|
|
92
|
-
this.reactor.dispatchEvent("onKill");
|
|
93
|
-
break;
|
|
94
|
-
case "scoreIncreased":
|
|
95
|
-
this.reactor.dispatchEvent("onScoreIncreased");
|
|
96
|
-
break;
|
|
97
|
-
case "update":
|
|
98
|
-
this.reactor.dispatchEvent("onUpdate");
|
|
99
|
-
break;
|
|
100
|
-
case "updateCounter":
|
|
101
|
-
this.reactor.dispatchEvent("onUpdateCounter");
|
|
102
|
-
break;
|
|
96
|
+
snakes = data.snakes;
|
|
103
97
|
}
|
|
104
|
-
});
|
|
105
|
-
|
|
106
|
-
this.worker.on("error", (error) => {
|
|
107
|
-
if(logger) logger.error("Error in GameEngineMultithreading", error);
|
|
108
|
-
this.errorOccurred = true;
|
|
109
|
-
this.reactor.dispatchEvent("onStop");
|
|
110
|
-
});
|
|
111
|
-
|
|
112
|
-
this.worker.on("exit", () => {
|
|
113
|
-
this.gameFinished = true;
|
|
114
|
-
this.reactor.dispatchEvent("onStop");
|
|
115
|
-
});
|
|
116
98
|
|
|
117
|
-
|
|
118
|
-
|
|
99
|
+
this.snakes = snakes;
|
|
100
|
+
this.grid = grid;
|
|
119
101
|
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
102
|
+
for (let i = 0; i < dataKeys.length; i++) {
|
|
103
|
+
if (dataKeys[i] != "snakes" && dataKeys[i] != "grid") {
|
|
104
|
+
this[dataKeys[i]] = data[dataKeys[i]];
|
|
105
|
+
}
|
|
106
|
+
}
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
switch (type) {
|
|
110
|
+
case "init":
|
|
111
|
+
this.workerReady = true;
|
|
112
|
+
this.passQueuedMessages();
|
|
113
|
+
break;
|
|
114
|
+
case "reset":
|
|
115
|
+
this.reactor.dispatchEvent("onReset");
|
|
116
|
+
break;
|
|
117
|
+
case "start":
|
|
118
|
+
this.reactor.dispatchEvent("onStart");
|
|
119
|
+
break;
|
|
120
|
+
case "pause":
|
|
121
|
+
this.reactor.dispatchEvent("onPause");
|
|
122
|
+
break;
|
|
123
|
+
case "continue":
|
|
124
|
+
this.reactor.dispatchEvent("onContinue");
|
|
125
|
+
break;
|
|
126
|
+
case "stop":
|
|
127
|
+
this.reactor.dispatchEvent("onStop");
|
|
128
|
+
break;
|
|
129
|
+
case "exit":
|
|
130
|
+
this.reactor.dispatchEvent("onExit");
|
|
131
|
+
break;
|
|
132
|
+
case "kill":
|
|
133
|
+
this.reactor.dispatchEvent("onKill");
|
|
134
|
+
break;
|
|
135
|
+
case "scoreIncreased":
|
|
136
|
+
this.reactor.dispatchEvent("onScoreIncreased");
|
|
137
|
+
break;
|
|
138
|
+
case "update":
|
|
139
|
+
this.reactor.dispatchEvent("onUpdate");
|
|
140
|
+
break;
|
|
141
|
+
case "updateCounter":
|
|
142
|
+
this.reactor.dispatchEvent("onUpdateCounter");
|
|
143
|
+
break;
|
|
144
|
+
}
|
|
145
|
+
});
|
|
146
|
+
|
|
147
|
+
this.worker.on("error", (error) => {
|
|
148
|
+
if (logger) logger.error("Error in GameEngineMultithreading", error);
|
|
149
|
+
this.errorOccurred = true;
|
|
150
|
+
this.reactor.dispatchEvent("onStop");
|
|
151
|
+
});
|
|
124
152
|
|
|
125
|
-
this.worker.
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
snakes: this.snakes,
|
|
129
|
-
speed: this.speed,
|
|
130
|
-
enablePause: this.enablePause,
|
|
131
|
-
enableRetry: this.enableRetry,
|
|
132
|
-
progressiveSpeed: this.progressiveSpeed
|
|
153
|
+
this.worker.on("exit", () => {
|
|
154
|
+
this.gameFinished = true;
|
|
155
|
+
this.reactor.dispatchEvent("onStop");
|
|
133
156
|
});
|
|
157
|
+
|
|
158
|
+
this.eventsInit = true;
|
|
134
159
|
}
|
|
135
160
|
|
|
136
161
|
reset() {
|
|
137
|
-
|
|
162
|
+
this.passMessage({ type: "reset" });
|
|
138
163
|
}
|
|
139
164
|
|
|
140
165
|
start() {
|
|
141
|
-
|
|
166
|
+
this.passMessage({ type: "start" });
|
|
142
167
|
}
|
|
143
168
|
|
|
144
169
|
stop(finish) {
|
|
145
|
-
|
|
170
|
+
this.passMessage({ type: finish ? "finish" : "stop" });
|
|
146
171
|
}
|
|
147
172
|
|
|
148
173
|
finish(finish) {
|
|
149
|
-
|
|
174
|
+
this.passMessage({ type: finish ? "finish" : "stop" });
|
|
150
175
|
}
|
|
151
176
|
|
|
152
177
|
pause() {
|
|
153
|
-
|
|
178
|
+
this.passMessage({ type: "pause" });
|
|
154
179
|
}
|
|
155
180
|
|
|
156
181
|
kill() {
|
|
@@ -162,27 +187,27 @@ class GameEngineMultithreadingController extends GameEngine {
|
|
|
162
187
|
}
|
|
163
188
|
|
|
164
189
|
tick() {
|
|
165
|
-
|
|
190
|
+
this.passMessage({ type: "tick" });
|
|
166
191
|
}
|
|
167
192
|
|
|
168
193
|
exit() {
|
|
169
|
-
|
|
194
|
+
this.passMessage({ type: "exit" });
|
|
170
195
|
}
|
|
171
196
|
|
|
172
197
|
key(key, numSnake) {
|
|
173
|
-
|
|
198
|
+
this.passMessage({ type: "key", key: key, numSnake: numSnake });
|
|
174
199
|
}
|
|
175
200
|
|
|
176
201
|
setGameOver(numSnake) {
|
|
177
|
-
|
|
202
|
+
this.passMessage({ type: "setGameOver", numSnake: numSnake });
|
|
178
203
|
}
|
|
179
204
|
|
|
180
205
|
forceStart() {
|
|
181
|
-
|
|
206
|
+
this.passMessage({ type: "forceStart" });
|
|
182
207
|
}
|
|
183
208
|
|
|
184
209
|
updateEngine(key, data) {
|
|
185
|
-
|
|
210
|
+
this.passMessage({ type: "update", key: key, data: data });
|
|
186
211
|
}
|
|
187
212
|
|
|
188
213
|
onReset(callback) {
|
|
@@ -224,6 +249,24 @@ class GameEngineMultithreadingController extends GameEngine {
|
|
|
224
249
|
onUpdateCounter(callback) {
|
|
225
250
|
this.reactor.addEventListener("onUpdateCounter", callback);
|
|
226
251
|
}
|
|
252
|
+
|
|
253
|
+
passMessage(message) {
|
|
254
|
+
if(this.workerReady && this.worker) {
|
|
255
|
+
this.worker.postMessage(message);
|
|
256
|
+
} else {
|
|
257
|
+
this.messageQueue.push(message);
|
|
258
|
+
}
|
|
259
|
+
}
|
|
260
|
+
|
|
261
|
+
passQueuedMessages() {
|
|
262
|
+
if(this.workerReady && this.worker) {
|
|
263
|
+
this.messageQueue.forEach(message => {
|
|
264
|
+
this.worker.postMessage(message);
|
|
265
|
+
});
|
|
266
|
+
|
|
267
|
+
this.messageQueue = [];
|
|
268
|
+
}
|
|
269
|
+
}
|
|
227
270
|
}
|
|
228
271
|
|
|
229
272
|
module.exports = function(l) {
|