createTaskProcessorWorker.js 4.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132
  1. import defaultValue from "../Core/defaultValue.js";
  2. import defined from "../Core/defined.js";
  3. import formatError from "../Core/formatError.js";
  4. import when from "../ThirdParty/when.js";
  5. // createXXXGeometry functions may return Geometry or a Promise that resolves to Geometry
  6. // if the function requires access to ApproximateTerrainHeights.
  7. // For fully synchronous functions, just wrapping the function call in a `when` Promise doesn't
  8. // handle errors correctly, hence try-catch
  9. function callAndWrap(workerFunction, parameters, transferableObjects) {
  10. var resultOrPromise;
  11. try {
  12. resultOrPromise = workerFunction(parameters, transferableObjects);
  13. return resultOrPromise; // errors handled by Promise
  14. } catch (e) {
  15. return when.reject(e);
  16. }
  17. }
  18. /**
  19. * Creates an adapter function to allow a calculation function to operate as a Web Worker,
  20. * paired with TaskProcessor, to receive tasks and return results.
  21. *
  22. * @function createTaskProcessorWorker
  23. *
  24. * @param {createTaskProcessorWorker.WorkerFunction} workerFunction The calculation function,
  25. * which takes parameters and returns a result.
  26. * @returns {createTaskProcessorWorker.TaskProcessorWorkerFunction} A function that adapts the
  27. * calculation function to work as a Web Worker onmessage listener with TaskProcessor.
  28. *
  29. *
  30. * @example
  31. * function doCalculation(parameters, transferableObjects) {
  32. * // calculate some result using the inputs in parameters
  33. * return result;
  34. * }
  35. *
  36. * return Cesium.createTaskProcessorWorker(doCalculation);
  37. * // the resulting function is compatible with TaskProcessor
  38. *
  39. * @see TaskProcessor
  40. * @see {@link http://www.w3.org/TR/workers/|Web Workers}
  41. * @see {@link http://www.w3.org/TR/html5/common-dom-interfaces.html#transferable-objects|Transferable objects}
  42. */
  43. function createTaskProcessorWorker(workerFunction) {
  44. var postMessage;
  45. return function (event) {
  46. var data = event.data;
  47. var transferableObjects = [];
  48. var responseMessage = {
  49. id: data.id,
  50. result: undefined,
  51. error: undefined,
  52. };
  53. return when(
  54. callAndWrap(workerFunction, data.parameters, transferableObjects)
  55. )
  56. .then(function (result) {
  57. responseMessage.result = result;
  58. })
  59. .otherwise(function (e) {
  60. if (e instanceof Error) {
  61. // Errors can't be posted in a message, copy the properties
  62. responseMessage.error = {
  63. name: e.name,
  64. message: e.message,
  65. stack: e.stack,
  66. };
  67. } else {
  68. responseMessage.error = e;
  69. }
  70. })
  71. .always(function () {
  72. if (!defined(postMessage)) {
  73. postMessage = defaultValue(self.webkitPostMessage, self.postMessage);
  74. }
  75. if (!data.canTransferArrayBuffer) {
  76. transferableObjects.length = 0;
  77. }
  78. try {
  79. postMessage(responseMessage, transferableObjects);
  80. } catch (e) {
  81. // something went wrong trying to post the message, post a simpler
  82. // error that we can be sure will be cloneable
  83. responseMessage.result = undefined;
  84. responseMessage.error =
  85. "postMessage failed with error: " +
  86. formatError(e) +
  87. "\n with responseMessage: " +
  88. JSON.stringify(responseMessage);
  89. postMessage(responseMessage);
  90. }
  91. });
  92. };
  93. }
  94. /**
  95. * A function that performs a calculation in a Web Worker.
  96. * @callback createTaskProcessorWorker.WorkerFunction
  97. *
  98. * @param {Object} parameters Parameters to the calculation.
  99. * @param {Array} transferableObjects An array that should be filled with references to objects inside
  100. * the result that should be transferred back to the main document instead of copied.
  101. * @returns {Object} The result of the calculation.
  102. *
  103. * @example
  104. * function calculate(parameters, transferableObjects) {
  105. * // perform whatever calculation is necessary.
  106. * var typedArray = new Float32Array(0);
  107. *
  108. * // typed arrays are transferable
  109. * transferableObjects.push(typedArray)
  110. *
  111. * return {
  112. * typedArray : typedArray
  113. * };
  114. * }
  115. */
  116. /**
  117. * A Web Worker message event handler function that handles the interaction with TaskProcessor,
  118. * specifically, task ID management and posting a response message containing the result.
  119. * @callback createTaskProcessorWorker.TaskProcessorWorkerFunction
  120. *
  121. * @param {Object} event The onmessage event object.
  122. */
  123. export default createTaskProcessorWorker;