Harden gameplay timing and map loading
This commit is contained in:
44
lib/panorama-textures.ts
Normal file
44
lib/panorama-textures.ts
Normal file
@@ -0,0 +1,44 @@
|
||||
import * as THREE from "three";
|
||||
|
||||
// Each viewer owns its textures. Browser HTTP caching handles repeat downloads;
|
||||
// keeping GPU resources in a global cache leaks every visited map and signed URL.
|
||||
export async function loadPanoramaTextures(
|
||||
urls: string[],
|
||||
loader: Pick<THREE.TextureLoader, "loadAsync"> = new THREE.TextureLoader(),
|
||||
timeoutMs = 30000,
|
||||
): Promise<THREE.Texture[]> {
|
||||
const textures: THREE.Texture[] = [];
|
||||
let failed = false;
|
||||
let timer: ReturnType<typeof setTimeout> | undefined;
|
||||
try {
|
||||
return await Promise.race([
|
||||
Promise.all(
|
||||
urls.map(async (url) => {
|
||||
const texture = await loader.loadAsync(url);
|
||||
if (failed) {
|
||||
texture.dispose();
|
||||
throw new Error("Panorama loading cancelled");
|
||||
}
|
||||
texture.colorSpace = THREE.SRGBColorSpace;
|
||||
textures.push(texture);
|
||||
return texture;
|
||||
}),
|
||||
),
|
||||
new Promise<never>((_, reject) => {
|
||||
timer = setTimeout(
|
||||
() =>
|
||||
reject(
|
||||
new Error("Panorama loading timed out. Reconnect to retry."),
|
||||
),
|
||||
timeoutMs,
|
||||
);
|
||||
}),
|
||||
]);
|
||||
} catch (error) {
|
||||
failed = true;
|
||||
textures.forEach((texture) => texture.dispose());
|
||||
throw error;
|
||||
} finally {
|
||||
clearTimeout(timer);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user