deepCopier.js 4.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101
  1. import { Logger } from "./logger.js";
  2. const CloneValue = (source, destinationObject, shallowCopyValues) => {
  3. if (!source) {
  4. return null;
  5. }
  6. if (source.getClassName && source.getClassName() === "Mesh") {
  7. return null;
  8. }
  9. if (source.getClassName && (source.getClassName() === "SubMesh" || source.getClassName() === "PhysicsBody")) {
  10. return source.clone(destinationObject);
  11. }
  12. else if (source.clone) {
  13. return source.clone();
  14. }
  15. else if (Array.isArray(source)) {
  16. return source.slice();
  17. }
  18. else if (shallowCopyValues && typeof source === "object") {
  19. return { ...source };
  20. }
  21. return null;
  22. };
  23. function GetAllPropertyNames(obj) {
  24. const props = [];
  25. do {
  26. Object.getOwnPropertyNames(obj).forEach(function (prop) {
  27. if (props.indexOf(prop) === -1) {
  28. props.push(prop);
  29. }
  30. });
  31. } while ((obj = Object.getPrototypeOf(obj)));
  32. return props;
  33. }
  34. /**
  35. * Class containing a set of static utilities functions for deep copy.
  36. */
  37. export class DeepCopier {
  38. /**
  39. * Tries to copy an object by duplicating every property
  40. * @param source defines the source object
  41. * @param destination defines the target object
  42. * @param doNotCopyList defines a list of properties to avoid
  43. * @param mustCopyList defines a list of properties to copy (even if they start with _)
  44. * @param shallowCopyValues defines wether properties referencing objects (none cloneable) must be shallow copied (false by default)
  45. * @remarks shallowCopyValues will not instantite the copied values which makes it only usable for "JSON objects"
  46. */
  47. static DeepCopy(source, destination, doNotCopyList, mustCopyList, shallowCopyValues = false) {
  48. const properties = GetAllPropertyNames(source);
  49. for (const prop of properties) {
  50. if (prop[0] === "_" && (!mustCopyList || mustCopyList.indexOf(prop) === -1)) {
  51. continue;
  52. }
  53. if (prop.endsWith("Observable")) {
  54. continue;
  55. }
  56. if (doNotCopyList && doNotCopyList.indexOf(prop) !== -1) {
  57. continue;
  58. }
  59. const sourceValue = source[prop];
  60. const typeOfSourceValue = typeof sourceValue;
  61. if (typeOfSourceValue === "function") {
  62. continue;
  63. }
  64. try {
  65. if (typeOfSourceValue === "object") {
  66. if (sourceValue instanceof Uint8Array) {
  67. destination[prop] = Uint8Array.from(sourceValue);
  68. }
  69. else if (sourceValue instanceof Array) {
  70. destination[prop] = [];
  71. if (sourceValue.length > 0) {
  72. if (typeof sourceValue[0] == "object") {
  73. for (let index = 0; index < sourceValue.length; index++) {
  74. const clonedValue = CloneValue(sourceValue[index], destination, shallowCopyValues);
  75. if (destination[prop].indexOf(clonedValue) === -1) {
  76. // Test if auto inject was not done
  77. destination[prop].push(clonedValue);
  78. }
  79. }
  80. }
  81. else {
  82. destination[prop] = sourceValue.slice(0);
  83. }
  84. }
  85. }
  86. else {
  87. destination[prop] = CloneValue(sourceValue, destination, shallowCopyValues);
  88. }
  89. }
  90. else {
  91. destination[prop] = sourceValue;
  92. }
  93. }
  94. catch (e) {
  95. // Log a warning (it could be because of a read-only property)
  96. Logger.Warn(e.message);
  97. }
  98. }
  99. }
  100. }
  101. //# sourceMappingURL=deepCopier.js.map