@awayjs/graphics
Version:
AwayJS graphics classes
124 lines (123 loc) • 4.84 kB
JavaScript
import { GraphicsFactoryFills } from './GraphicsFactoryFills';
import { WORKER_BODY } from './WorkerTesselatorBody';
var WebWorkerTessealtor = /** @class */ (function () {
function WebWorkerTessealtor() {
}
WebWorkerTessealtor.prefarmWorkers = function () {
for (var i = 0; i < this.MAX_TASK; i++) {
this.workers.push(this.generateWorker('' + i));
}
return this.waitFreeWorker().then(function () { return void 0; });
};
WebWorkerTessealtor.onError = function (error) {
console.error(error.target, error.message);
};
WebWorkerTessealtor.onData = function (result) {
switch (result.data.status) {
case 'ready': {
//console.debug('[WorkerTesselator] Runed succesfylly! ', result.target);
break;
}
case 'done': {
this.tasks[result.data.id].resolve(result.data);
this.tasks[result.data.id] = null;
//console.debug('[WorkerTesselator] Task reached back succesfylly! ', result.target);
break;
}
case 'error': {
this.tasks[result.data.id].reject(result.data);
this.tasks[result.data.id] = null;
//console.error('[WorkerTesselator] Task reached with error! ', result.data);
break;
}
default: {
throw 'Unknown worker answer:' + result.data;
}
}
this.freeWorkers.push(result.target);
this.anyCallback && this.anyCallback(result.target);
this.anyCallback = null;
this.busyWaiter = null;
};
WebWorkerTessealtor.waitFreeWorker = function () {
var _this = this;
if (this.freeWorkers.length > 0) {
return Promise.resolve(this.freeWorkers[0]);
}
if (this.busyWaiter) {
return this.busyWaiter;
}
return this.busyWaiter = new Promise(function (res) {
_this.anyCallback = res;
});
};
WebWorkerTessealtor.generateWorker = function (id) {
if (id === void 0) { id = ''; }
var source = WORKER_BODY.toString();
var b0 = source.indexOf('{');
var b1 = source.lastIndexOf('}');
source = source.substring(b0 + 1, b1);
source = source.replace('__TESS__LIB__', this.TESS_URL);
var url = URL.createObjectURL(new Blob([source]));
var worker = new Worker(url, { name: 'Tesselator_worker_' + id });
worker.name = 'Tesselator_worker_' + id;
worker.onmessage = this.onData.bind(this);
worker.onerror = this.onError.bind(this);
URL.revokeObjectURL(url);
return worker;
};
WebWorkerTessealtor.tesselatedWorker = function (path) {
var _this = this;
var id = this.TASK_ID++;
var contours = GraphicsFactoryFills.prepareContours(path, GraphicsFactoryFills.USE_TESS_FIX);
var scaleRatio = GraphicsFactoryFills.USE_TESS_FIX
? GraphicsFactoryFills.TESS_SCALE
: 1;
var size = 0;
contours.forEach(function (e) { return size += e.length; });
if (size < 6) {
return Promise.reject({
status: 'error',
error: 'Invalid shape',
id: id,
});
}
return this.waitFreeWorker().then(function (w) {
var store = new Float32Array(size);
var bufferContours = [];
var next = 0;
for (var _i = 0, contours_1 = contours; _i < contours_1.length; _i++) {
var c = contours_1[_i];
var buffer = store.subarray(next, c.length + next);
buffer.set(c);
bufferContours.push(buffer);
next += c.length;
}
return new Promise(function (resolve, reject) {
_this.tasks[id] = {
resolve: resolve,
reject: reject,
id: id
};
w.postMessage({
scaleRatio: scaleRatio,
contours: bufferContours,
vertexSize: 2,
polySize: 3,
elementType: 0,
windingRule: 0,
id: id
});
_this.freeWorkers.splice(_this.freeWorkers.indexOf(w), 1);
});
});
};
WebWorkerTessealtor.TESS_URL = 'https://cdn.jsdelivr.net/npm/tess2-ts@1.0.5/dist/tess2.min.js';
WebWorkerTessealtor.TASK_ID = 0;
WebWorkerTessealtor.MAX_TASK = 8;
WebWorkerTessealtor.tasks = {};
WebWorkerTessealtor.workers = [];
WebWorkerTessealtor.freeWorkers = [];
return WebWorkerTessealtor;
}());
export { WebWorkerTessealtor };