UNPKG

@motion-core/motion-gpu

Version:

Framework-agnostic WebGPU runtime for fullscreen WGSL shaders with explicit Svelte, React, and Vue adapter entrypoints.

99 lines (98 loc) 2.92 kB
import { toMotionGPUErrorReport } from "./error-report.js"; import { createCurrentWritable } from "./current-value.js"; import { isAbortError, loadTexturesFromUrls, mergeAbortSignals } from "./texture-loader.js"; //#region src/lib/core/texture-load-controller.ts function disposeTextures(textures) { for (const texture of textures ?? []) texture.dispose(); } function toError(error) { return error instanceof Error ? error : /* @__PURE__ */ new Error("Unknown texture loading error"); } function createTextureLoadController({ getUrls, getOptions }) { const textures = createCurrentWritable(null); const loading = createCurrentWritable(true); const error = createCurrentWritable(null); const errorReport = createCurrentWritable(null); let disposed = false; let requestVersion = 0; let activeController = null; let runningLoad = null; let reloadQueued = false; const executeLoad = async () => { if (disposed) return; const version = ++requestVersion; const controller = new AbortController(); activeController = controller; loading.set(true); error.set(null); errorReport.set(null); const previous = textures.current; const options = getOptions() ?? {}; const mergedSignal = mergeAbortSignals(controller.signal, options.signal); try { const loaded = await loadTexturesFromUrls(getUrls(), { ...options, signal: mergedSignal.signal }); if (disposed || version !== requestVersion) { disposeTextures(loaded); return; } textures.set(loaded); disposeTextures(previous); } catch (nextError) { if (disposed || version !== requestVersion || isAbortError(nextError)) return; disposeTextures(previous); textures.set(null); const normalizedError = toError(nextError); error.set(normalizedError); errorReport.set(toMotionGPUErrorReport(normalizedError, "initialization")); } finally { if (!disposed && version === requestVersion) loading.set(false); if (activeController === controller) activeController = null; mergedSignal.dispose(); } }; const runLoadLoop = async () => { do { reloadQueued = false; await executeLoad(); } while (reloadQueued && !disposed); }; const reload = () => { activeController?.abort(); if (runningLoad) { reloadQueued = true; return runningLoad; } const trackedPending = runLoadLoop().finally(() => { if (runningLoad === trackedPending) runningLoad = null; }); runningLoad = trackedPending; return trackedPending; }; const resume = () => { disposed = false; }; const dispose = () => { if (disposed) return; disposed = true; requestVersion += 1; activeController?.abort(); disposeTextures(textures.current); textures.set(null); loading.set(false); }; return { textures, loading, error, errorReport, reload, resume, dispose }; } //#endregion export { createTextureLoadController }; //# sourceMappingURL=texture-load-controller.js.map