arrayTools.js 4.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103
  1. /* eslint-disable @typescript-eslint/naming-convention */
  2. /**
  3. * Class containing a set of static utilities functions for arrays.
  4. */
  5. export class ArrayTools {
  6. /**
  7. * Returns an array of the given size filled with elements built from the given constructor and the parameters.
  8. * @param size the number of element to construct and put in the array.
  9. * @param itemBuilder a callback responsible for creating new instance of item. Called once per array entry.
  10. * @returns a new array filled with new objects.
  11. */
  12. static BuildArray(size, itemBuilder) {
  13. const a = [];
  14. for (let i = 0; i < size; ++i) {
  15. a.push(itemBuilder());
  16. }
  17. return a;
  18. }
  19. /**
  20. * Returns a tuple of the given size filled with elements built from the given constructor and the parameters.
  21. * @param size he number of element to construct and put in the tuple.
  22. * @param itemBuilder a callback responsible for creating new instance of item. Called once per tuple entry.
  23. * @returns a new tuple filled with new objects.
  24. */
  25. static BuildTuple(size, itemBuilder) {
  26. return ArrayTools.BuildArray(size, itemBuilder);
  27. }
  28. }
  29. /**
  30. * Observes a function and calls the given callback when it is called.
  31. * @param object Defines the object the function to observe belongs to.
  32. * @param functionName Defines the name of the function to observe.
  33. * @param callback Defines the callback to call when the function is called.
  34. * @returns A function to call to stop observing
  35. */
  36. function _observeArrayfunction(object, functionName, callback) {
  37. // Finds the function to observe
  38. const oldFunction = object[functionName];
  39. if (typeof oldFunction !== "function") {
  40. return null;
  41. }
  42. // Creates a new function that calls the callback and the old function
  43. const newFunction = function () {
  44. const previousLength = object.length;
  45. const returnValue = newFunction.previous.apply(object, arguments);
  46. callback(functionName, previousLength);
  47. return returnValue;
  48. };
  49. // Doublishly links the new function and the old function
  50. oldFunction.next = newFunction;
  51. newFunction.previous = oldFunction;
  52. // Replaces the old function with the new function
  53. object[functionName] = newFunction;
  54. // Returns a function to disable the hook
  55. return () => {
  56. // Only unhook if the function is still hooked
  57. const previous = newFunction.previous;
  58. if (!previous) {
  59. return;
  60. }
  61. // Finds the ref to the next function in the chain
  62. const next = newFunction.next;
  63. // If in the middle of the chain, link the previous and next functions
  64. if (next) {
  65. previous.next = next;
  66. next.previous = previous;
  67. }
  68. // If at the end of the chain, remove the reference to the previous function
  69. // and restore the previous function
  70. else {
  71. previous.next = undefined;
  72. object[functionName] = previous;
  73. }
  74. // Lose reference to the previous and next functions
  75. newFunction.next = undefined;
  76. newFunction.previous = undefined;
  77. };
  78. }
  79. /**
  80. * Defines the list of functions to proxy when observing an array.
  81. * The scope is currently reduced to the common functions used in the render target render list and the scene cameras.
  82. */
  83. const observedArrayFunctions = ["push", "splice", "pop", "shift", "unshift"];
  84. /**
  85. * Observes an array and notifies the given observer when the array is modified.
  86. * @param array Defines the array to observe
  87. * @param callback Defines the function to call when the array is modified (in the limit of the observed array functions)
  88. * @returns A function to call to stop observing the array
  89. * @internal
  90. */
  91. export function _ObserveArray(array, callback) {
  92. // Observes all the required array functions and stores the unhook functions
  93. const unObserveFunctions = observedArrayFunctions.map((name) => {
  94. return _observeArrayfunction(array, name, callback);
  95. });
  96. // Returns a function that unhook all the observed functions
  97. return () => {
  98. unObserveFunctions.forEach((unObserveFunction) => {
  99. unObserveFunction?.();
  100. });
  101. };
  102. }
  103. //# sourceMappingURL=arrayTools.js.map