Source: Workers/createTaskProcessorWorker.js

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