UNPKG

typegpu

Version:

A thin layer between JS and WebGPU/WGSL that improves development experience and allows for faster iteration.

84 lines (83 loc) 2.81 kB
import { isDisarray, isLooseDecorated, isUnstruct } from "./dataTypes.js"; import { isAtomic, isDecorated, isPtr, isWgslArray, isWgslStruct } from "./wgslTypes.js"; /** * Performs a deep comparison of two TypeGPU data schemas. * * @param a The first data schema to compare. * @param b The second data schema to compare. * @returns `true` if the schemas are deeply equal, `false` otherwise. * * @example * ```ts * import { vec3f, struct, deepEqual } from 'typegpu/data'; * * const schema1 = struct({ a: vec3f }); * const schema2 = struct({ a: vec3f }); * const schema3 = struct({ b: vec3f }); * * console.log(deepEqual(schema1, schema2)); // true * console.log(deepEqual(schema1, schema3)); // false * ``` */ export function deepEqual(a, b) { if (a === b) { return true; } if (a.type !== b.type) { return false; } if ((isWgslStruct(a) && isWgslStruct(b)) || (isUnstruct(a) && isUnstruct(b))) { const aProps = a.propTypes; const bProps = b.propTypes; const aKeys = Object.keys(aProps); const bKeys = Object.keys(bProps); if (aKeys.length !== bKeys.length) { return false; } for (let i = 0; i < aKeys.length; i++) { const keyA = aKeys[i]; const keyB = bKeys[i]; if (keyA !== keyB || !keyA || !keyB || !deepEqual(aProps[keyA], bProps[keyB])) { return false; } } return true; } if ((isWgslArray(a) && isWgslArray(b)) || (isDisarray(a) && isDisarray(b))) { return (a.elementCount === b.elementCount && deepEqual(a.elementType, b.elementType)); } if (isPtr(a) && isPtr(b)) { return (a.addressSpace === b.addressSpace && a.access === b.access && deepEqual(a.inner, b.inner)); } if (isAtomic(a) && isAtomic(b)) { return deepEqual(a.inner, b.inner); } if ((isDecorated(a) && isDecorated(b)) || (isLooseDecorated(a) && isLooseDecorated(b))) { if (!deepEqual(a.inner, b.inner)) { return false; } if (a.attribs.length !== b.attribs.length) { return false; } // Create comparable string representations for each attribute const getAttrKey = (attr) => { const anyAttr = attr; return `${anyAttr.type}(${(anyAttr.params ?? []).join(',')})`; }; const attrsA = a.attribs.map(getAttrKey); const attrsB = b.attribs.map(getAttrKey); for (let i = 0; i < attrsA.length; i++) { if (attrsA[i] !== attrsB[i]) { return false; } } } // All other types have been checked for equality at the start return true; }