All files / tools/src/utilities/segmentation createEnsureSliceLoadedForVolume.ts

0% Statements 0/23
0% Branches 0/13
0% Functions 0/5
0% Lines 0/22

Press n or j to go to the next uncovered block, b, p or k for the previous block.

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55                                                                                                             
import { imageLoader } from '@cornerstonejs/core';
import type { Types } from '@cornerstonejs/core';
 
/**
 * Builds an idempotent per-slice loader for volumes backed by `imageIds` (e.g. streaming stacks).
 * No-op when `imageIds` is missing or empty. Uses `imageLoader.loadImage` for the slice imageId.
 *
 * After a slice loads successfully once, it is remembered so callers (e.g. flood fill per voxel)
 * do not re-enter `loadImage` or await redundant work on the same z index.
 */
export function createEnsureSliceLoadedForVolume(
  volume: Types.IImageVolume
): (z: number) => Promise<void> {
  const numSlices = volume.dimensions[2];
  const imageIds = volume.imageIds;
  if (!imageIds?.length) {
    return async () => undefined;
  }
 
  const loadedSlices = new Set<number>();
  const inFlight = new Map<number, Promise<void>>();
 
  return async function ensureSliceLoaded(z: number): Promise<void> {
    if (!Number.isFinite(z) || z < 0 || z >= numSlices) {
      return;
    }
 
    if (loadedSlices.has(z)) {
      return;
    }
 
    const existing = inFlight.get(z);
    if (existing) {
      return existing;
    }
 
    const imageId = imageIds[z];
    if (!imageId) {
      return;
    }
 
    const promise = imageLoader
      .loadImage(imageId)
      .then(() => {
        loadedSlices.add(z);
      })
      .finally(() => {
        inFlight.delete(z);
      });
 
    inFlight.set(z, promise);
    return promise;
  };
}