UNPKG

typegpu

Version:

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

60 lines (59 loc) 1.95 kB
import { validateProp } from "../nameUtils.js"; import { getName, setName } from "../shared/meta.js"; import { $internal } from "../shared/symbols.js"; import { schemaCallWrapper } from "./schemaCallWrapper.js"; // ---------- // Public API // ---------- /** * Creates a struct schema that can be used to construct GPU buffers. * Ensures proper alignment and padding of properties (as opposed to a `d.unstruct` schema). * The order of members matches the passed in properties object. * * @example * const CircleStruct = d.struct({ radius: d.f32, pos: d.vec3f }); * * @param props Record with `string` keys and `TgpuData` values, * each entry describing one struct member. */ export function struct(props) { return INTERNAL_createStruct(props, false); } export function abstruct(props) { return INTERNAL_createStruct(props, true); } // -------------- // Implementation // -------------- export function INTERNAL_createStruct(props, isAbstruct) { Object.keys(props).forEach((key) => { const result = validateProp(key); if (!result.success) { throw new Error(`Invalid property key '${key}'${result.error ? `: ${result.error}` : ''}`); } }); // In the schema call, create and return a deep copy // by wrapping all the values in corresponding schema calls. const structSchema = (instanceProps) => Object.fromEntries(Object.entries(props).map(([key, schema]) => [ key, schemaCallWrapper(schema, instanceProps?.[key]), ])); Object.setPrototypeOf(structSchema, WgslStructImpl); structSchema.propTypes = props; Object.defineProperty(structSchema, $internal, { value: { isAbstruct, }, }); return structSchema; } const WgslStructImpl = { type: 'struct', $name(label) { setName(this, label); return this; }, toString() { return `struct:${getName(this) ?? '<unnamed>'}`; }, };