forked from thlorenz/pec
-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathpec.background.js
98 lines (91 loc) · 3.04 KB
/
pec.background.js
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
'use strict'
const work = require('webworkify')
const now = Date.now
const workerBlob = require('./pec.worker')
const stopMsg = JSON.stringify({ stop: true })
function readMessage(msg, trackCombos) {
if (!trackCombos) {
const [ win, loose, tie, iterations, uid ] = msg
return { win, loose, tie, iterations, uid }
}
const { win, loose, tie, iterations, combos, uid } = msg
return { win, loose, tie, iterations, combos: new Map(combos), uid }
}
class BackgroundWorker {
constructor(update) {
this._update = update
this._worker = work(workerBlob)
this._onresult = this._onresult.bind(this)
this._stopped = true
this._worker.addEventListener('message', this._onresult)
}
/**
*
* @name BackgroundWorker.raceRange
* @function
* @param {Array.<string>} combo to race i.e. `[ 'As', 'Ad' ]`
* @param {Array.<Array.<string>> range multiple combos to raise against it, i.e. `[ [ 'Ks', 'Kd' ], [ 'Qs', 'Qd' ] ]`
* @param {Number} total the total number of times to race, `100` are processed
* each time and `update` invoked until the `total` is reached
* @param {Boolean} [trackCombos=false] if `true` the counts for each combos are tracked
* @param {Array.<string>} [board=null] if supplied the range will be raced
* against subsets boards that include all cards of the given board
* @return {Number} the uid generated to identify this background job,
* the same uid will be included in the message the result to identify it with the job
*/
raceRange(combo, range, total, trackCombos, board) {
this._trackCombos = !!trackCombos
this._stopped = false
const runAll = total == null
const uid = now()
if (runAll) {
const msg = JSON.stringify({ combo, range, runAll, trackCombos: this._trackCombos, board, uid })
this._worker.postMessage(msg)
} else {
// let's do 100 at a time to come back with at least some result quickly
// progress communication is a simple array with 3 elements which shouldn't add too much overload
const times = Math.min(total, 100)
const repeat = Math.round(total / times)
const msg = JSON.stringify({
combo
, range
, runAll
, times
, repeat
, trackCombos: this._trackCombos
, board
, uid
})
this._worker.postMessage(msg)
}
return uid
}
/**
* Stops any races in progress.
*
* @name BackgroundWorker.stop
* @function
*/
stop() {
if (this._stopped) return
this._stopped = true
this._worker.postMessage(stopMsg)
}
_onresult(e) {
if (this._stopped) return
const res = readMessage(e.data, this._trackCombos)
this._update(res)
}
}
/**
* Creates a background worker which uses a web worker
* under the hood to process _race_ requests.
*
* @name createBackgroundWorker
* @function
* @param {funcion} update will be called with updates: `{ win, loose, tie, iterations, uid }`
* @return {BackgroundWorker} backgroundWorker
*/
module.exports = function createBackgroundWorker(update) {
return new BackgroundWorker(update)
}