import { vi } from "vitest"; import type { ToolcraftModelDocument } from "../../model-import/canonical/model-document"; import type { ToolcraftModelPresentationLease, ToolcraftModelRenderResourceContext, } from "./model-render-binding"; import { buildToolcraftCanonicalThreeModel } from "./three-canonical-model"; import { createToolcraftThreeModelAppearance } from "./three-model-appearance"; import type { ToolcraftThreeRenderer } from "./three-model-render-adapter"; export function createRenderer(): ToolcraftThreeRenderer & { dispose: ReturnType; render: ReturnType; } { return { dispose: vi.fn(), domElement: document.createElement("canvas"), render: vi.fn(), renderLists: { dispose: vi.fn() }, setPixelRatio: vi.fn(), setSize: vi.fn(), }; } export const asset = { activeDocumentRef: "document:model", id: "model-1", layerId: "layer-1", lifecycle: "clean" as const, sourceTarget: "source.model", }; export function createModelRenderContext( canonicalDocument: ToolcraftModelDocument, onRelease: () => void = () => undefined, ): ToolcraftModelRenderResourceContext & { acquirePresentation: ReturnType; } { const acquirePresentation = vi.fn(async (): Promise< ToolcraftModelPresentationLease > => { const appearance = createToolcraftThreeModelAppearance( canonicalDocument, new Map(), ); const built = buildToolcraftCanonicalThreeModel( canonicalDocument, appearance.materialForPrimitive, ); let released = false; return Object.freeze({ bounds: canonicalDocument.bounds, document: canonicalDocument, release: () => { if (released) return; released = true; for (const geometry of new Set(built.geometries)) geometry.dispose(); appearance.dispose(); built.modelRoot.clear(); onRelease(); }, root: built.modelRoot, }); }); return { acquirePresentation, signal: new AbortController().signal, }; }