You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
149 lines
3.2 KiB
149 lines
3.2 KiB
"use strict"; |
|
|
|
var adapter = require('./node/index.js') |
|
var circularize = require('./common/circularize.js') |
|
|
|
|
|
function createWorker(workerOptions){ |
|
return new TesseractWorker(workerOptions) |
|
} |
|
|
|
class TesseractWorker { |
|
constructor(workerOptions){ |
|
this.worker = null; |
|
this.workerOptions = workerOptions; |
|
this._currentJob = null; |
|
this._queue = [] |
|
} |
|
|
|
recognize(image, options){ |
|
return this._delay(job => { |
|
if(typeof options === 'string'){ |
|
options = { lang: options }; |
|
}else{ |
|
options = options || {} |
|
options.lang = options.lang || 'eng'; |
|
} |
|
|
|
job._send('recognize', { image: image, options: options, workerOptions: this.workerOptions }) |
|
}) |
|
} |
|
detect(image, options){ |
|
options = options || {} |
|
return this._delay(job => { |
|
job._send('detect', { image: image, options: options, workerOptions: this.workerOptions }) |
|
}) |
|
} |
|
|
|
terminate(){ |
|
if(this.worker) adapter.terminateWorker(this); |
|
this.worker = null; |
|
} |
|
|
|
_delay(fn){ |
|
if(!this.worker) this.worker = adapter.spawnWorker(this, this.workerOptions); |
|
|
|
var job = new TesseractJob(this); |
|
this._queue.push(e => { |
|
this._queue.shift() |
|
this._currentJob = job; |
|
fn(job) |
|
}) |
|
if(!this._currentJob) this._dequeue(); |
|
return job |
|
} |
|
|
|
_dequeue(){ |
|
this._currentJob = null; |
|
if(this._queue.length > 0){ |
|
this._queue[0]() |
|
} |
|
} |
|
|
|
_recv(packet){ |
|
|
|
if(packet.status === 'resolve' && packet.action === 'recognize'){ |
|
packet.data = circularize(packet.data); |
|
} |
|
|
|
if(this._currentJob.id === packet.jobId){ |
|
this._currentJob._handle(packet) |
|
}else{ |
|
console.warn('Job ID ' + packet.jobId + ' not known.') |
|
} |
|
} |
|
} |
|
|
|
var jobCounter = 0; |
|
|
|
class TesseractJob { |
|
constructor(instance){ |
|
this.id = 'Job-' + (++jobCounter) + '-' + Math.random().toString(16).slice(3, 8) |
|
|
|
this._instance = instance; |
|
this._resolve = [] |
|
this._reject = [] |
|
this._progress = [] |
|
} |
|
|
|
then(resolve, reject){ |
|
if(this._resolve.push){ |
|
this._resolve.push(resolve) |
|
}else{ |
|
resolve(this._resolve) |
|
} |
|
|
|
if(reject) this.catch(reject); |
|
return this; |
|
} |
|
catch(reject){ |
|
if(this._reject.push){ |
|
this._reject.push(reject) |
|
}else{ |
|
reject(this._reject) |
|
} |
|
return this; |
|
} |
|
progress(fn){ |
|
this._progress.push(fn) |
|
return this; |
|
} |
|
_send(action, payload){ |
|
adapter.sendPacket(this._instance, { |
|
jobId: this.id, |
|
action: action, |
|
payload: payload |
|
}) |
|
} |
|
|
|
_handle(packet){ |
|
var data = packet.data; |
|
if(packet.status === 'resolve'){ |
|
if(this._resolve.length === 0) console.debug(data); |
|
this._resolve.forEach(fn => { |
|
var ret = fn(data); |
|
if(ret && typeof ret.then == 'function'){ |
|
console.warn('TesseractJob instances do not chain like ES6 Promises. To convert it into a real promise, use Promise.resolve.') |
|
} |
|
}) |
|
this._resolve = data; |
|
this._instance._dequeue() |
|
}else if(packet.status === 'reject'){ |
|
if(this._reject.length === 0) console.error(data); |
|
this._reject.forEach(fn => fn(data)) |
|
this._reject = data; |
|
this._instance._dequeue() |
|
}else if(packet.status === 'progress'){ |
|
this._progress.forEach(fn => fn(data)) |
|
}else{ |
|
console.warn('Message type unknown', packet.status) |
|
} |
|
} |
|
} |
|
|
|
|
|
var DefaultTesseract = createWorker(adapter.defaultOptions) |
|
DefaultTesseract.createWorker = createWorker; |
|
|
|
module.exports = DefaultTesseract |
|
|
|
|