createTaskProcessorWorker.js 5.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126
  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. * @exports 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(callAndWrap(workerFunction, data.parameters, transferableObjects))
  54. .then(function(result) {
  55. responseMessage.result = result;
  56. })
  57. .otherwise(function(e) {
  58. if (e instanceof Error) {
  59. // Errors can't be posted in a message, copy the properties
  60. responseMessage.error = {
  61. name : e.name,
  62. message : e.message,
  63. stack : e.stack
  64. };
  65. } else {
  66. responseMessage.error = e;
  67. }
  68. })
  69. .always(function() {
  70. if (!defined(postMessage)) {
  71. postMessage = defaultValue(self.webkitPostMessage, self.postMessage);
  72. }
  73. if (!data.canTransferArrayBuffer) {
  74. transferableObjects.length = 0;
  75. }
  76. try {
  77. postMessage(responseMessage, transferableObjects);
  78. } catch (e) {
  79. // something went wrong trying to post the message, post a simpler
  80. // error that we can be sure will be cloneable
  81. responseMessage.result = undefined;
  82. responseMessage.error = 'postMessage failed with error: ' + formatError(e) + '\n with responseMessage: ' + JSON.stringify(responseMessage);
  83. postMessage(responseMessage);
  84. }
  85. });
  86. };
  87. }
  88. /**
  89. * A function that performs a calculation in a Web Worker.
  90. * @callback createTaskProcessorWorker~WorkerFunction
  91. *
  92. * @param {Object} parameters Parameters to the calculation.
  93. * @param {Array} transferableObjects An array that should be filled with references to objects inside
  94. * the result that should be transferred back to the main document instead of copied.
  95. * @returns {Object} The result of the calculation.
  96. *
  97. * @example
  98. * function calculate(parameters, transferableObjects) {
  99. * // perform whatever calculation is necessary.
  100. * var typedArray = new Float32Array(0);
  101. *
  102. * // typed arrays are transferable
  103. * transferableObjects.push(typedArray)
  104. *
  105. * return {
  106. * typedArray : typedArray
  107. * };
  108. * }
  109. */
  110. /**
  111. * A Web Worker message event handler function that handles the interaction with TaskProcessor,
  112. * specifically, task ID management and posting a response message containing the result.
  113. * @callback createTaskProcessorWorker~TaskProcessorWorkerFunction
  114. *
  115. * @param {Object} event The onmessage event object.
  116. */
  117. export default createTaskProcessorWorker;