workerPool.ts 1.9 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364
  1. import { IDisposable } from "../scene";
  2. interface WorkerInfo {
  3. worker: Worker;
  4. active: boolean;
  5. }
  6. /**
  7. * Helper class to push actions to a pool of workers.
  8. */
  9. export class WorkerPool implements IDisposable {
  10. private _workerInfos: Array<WorkerInfo>;
  11. private _pendingActions = new Array<(worker: Worker, onComplete: () => void) => void>();
  12. /**
  13. * Constructor
  14. * @param workers Array of workers to use for actions
  15. */
  16. constructor(workers: Array<Worker>) {
  17. this._workerInfos = workers.map((worker) => ({
  18. worker: worker,
  19. active: false
  20. }));
  21. }
  22. /**
  23. * Terminates all workers and clears any pending actions.
  24. */
  25. public dispose(): void {
  26. for (const workerInfo of this._workerInfos) {
  27. workerInfo.worker.terminate();
  28. }
  29. this._workerInfos = [];
  30. this._pendingActions = [];
  31. }
  32. /**
  33. * Pushes an action to the worker pool. If all the workers are active, the action will be
  34. * pended until a worker has completed its action.
  35. * @param action The action to perform. Call onComplete when the action is complete.
  36. */
  37. public push(action: (worker: Worker, onComplete: () => void) => void): void {
  38. for (const workerInfo of this._workerInfos) {
  39. if (!workerInfo.active) {
  40. this._execute(workerInfo, action);
  41. return;
  42. }
  43. }
  44. this._pendingActions.push(action);
  45. }
  46. private _execute(workerInfo: WorkerInfo, action: (worker: Worker, onComplete: () => void) => void): void {
  47. workerInfo.active = true;
  48. action(workerInfo.worker, () => {
  49. workerInfo.active = false;
  50. const nextAction = this._pendingActions.shift();
  51. if (nextAction) {
  52. this._execute(workerInfo, nextAction);
  53. }
  54. });
  55. }
  56. }