UNPKG

typegpu

Version:

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

75 lines (74 loc) 2.36 kB
import { getResolutionCtx } from "../../execMode.js"; import { makeDereferenceable } from "../../tgsl/makeDereferenceable.js"; import { makeResolvable } from "../../tgsl/makeResolvable.js"; import { $gpuValueOf, $internal, $providing } from "../../shared/symbols.js"; import { getGpuValueRecursively } from "../valueProxyUtils.js"; import { isAccessor, isMutableAccessor, } from "./slotTypes.js"; // ---------- // Public API // ---------- export function lazy(compute) { if (getResolutionCtx()) { throw new Error('Cannot create tgpu.lazy objects during shader resolution.'); } return new TgpuLazyImpl(compute, undefined); } // -------------- // Implementation // -------------- class TgpuLazyImpl { [$internal]; [$providing]; static { TgpuLazyImpl.prototype.resourceType = 'lazy'; makeDereferenceable(makeResolvable(TgpuLazyImpl.prototype, { asString: () => 'lazy', resolve(_ctx) { throw new Error(`Unreachable, is never resolved directly`); }, }), { codegenMode: { get() { return this.#getValue(); }, }, normalMode: { get() { return this.#getValue(); }, }, }); } constructor(compute, providing) { this[$internal] = { compute, }; this[$providing] = providing; } get [$gpuValueOf]() { const ctx = getResolutionCtx(); if (!ctx) { throw new Error(`Cannot access tgpu.lazy's value outside of resolution.`); } return getGpuValueRecursively(ctx.unwrap(this)); } get $() { return this[$gpuValueOf]; } #getValue() { const ctx = getResolutionCtx(); if (!ctx) { throw new Error(`Cannot access tgpu.lazy's value outside of resolution.`); } return getGpuValueRecursively(ctx.unwrap(this)); } with(slot, value) { return new TgpuLazyImpl(this[$internal].compute.bind(this), { inner: this[$providing]?.inner ?? this, pairs: [ ...(this[$providing]?.pairs ?? []), [isAccessor(slot) || isMutableAccessor(slot) ? slot.slot : slot, value], ], }); } }