| 1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374 |
- import { describe, expect, it } from "vitest";
- import type { AssetEntry } from "@nengine/core";
- import { AssetCoordinator, MAX_ASSET_REQUEST_IDS } from "../src/sync/asset-coordinator.js";
- const index = (ids: string[]): Record<string, { kind: "image" | "audio"; mime: string; size: number }> => {
- const out: Record<string, { kind: "image" | "audio"; mime: string; size: number }> = {};
- for (const id of ids) out[id] = { kind: "image", mime: "image/png", size: 1 };
- return out;
- };
- const entry = (id: string): Record<string, AssetEntry> => ({ [id]: { kind: "image", mime: "image/png", data: "x" } });
- describe("AssetCoordinator (D37 on-demand asset requests)", () => {
- it("requests only wanted ids known to the server index", () => {
- const c = new AssetCoordinator();
- c.setIndex(index(["grass-1", "water-1"]));
- c.want(["grass-1", "water-1", "missing-asset"]);
- expect(c.requestBatch()).toEqual(["grass-1", "water-1"]);
- expect(c.requestBatch()).toEqual([]);
- });
- it("dedupes: never re-requests ids that are pending or loaded", () => {
- const c = new AssetCoordinator();
- c.setIndex(index(["a", "b", "c"]));
- c.want(["a", "b", "c"]);
- const batch1 = c.requestBatch();
- expect(batch1).toEqual(["a", "b", "c"]);
- // all pending — nothing new
- expect(c.requestBatch()).toEqual([]);
- // a response for a and b arrives; c's request is still in flight
- c.applyAssets({ ...entry("a"), ...entry("b") });
- expect(c.has("a")).toBe(true);
- expect(c.has("b")).toBe(true);
- expect(c.has("c")).toBe(false);
- expect(c.requestBatch()).toEqual([]); // c still pending
- // c's response arrives — nothing left to request
- c.applyAssets(entry("c"));
- expect(c.has("c")).toBe(true);
- expect(c.requestBatch()).toEqual([]);
- });
- it("caps a batch at MAX_ASSET_REQUEST_IDS", () => {
- const ids = Array.from({ length: MAX_ASSET_REQUEST_IDS + 10 }, (_, i) => `a${i}`);
- const c = new AssetCoordinator();
- c.setIndex(index(ids));
- c.want(ids);
- const batch = c.requestBatch();
- expect(batch).toHaveLength(MAX_ASSET_REQUEST_IDS);
- const rest = c.requestBatch();
- expect(rest).toHaveLength(10);
- });
- it("new wanted ids from a later snapshot are requested after a prior batch resolved", () => {
- const c = new AssetCoordinator();
- c.setIndex(index(["a"]));
- c.want(["a"]);
- expect(c.requestBatch()).toEqual(["a"]);
- c.applyAssets(entry("a"));
- // a fresh snapshot adds a new referenced asset
- c.setIndex(index(["a", "b"]));
- c.want(["b"]);
- expect(c.requestBatch()).toEqual(["b"]);
- });
- it("applyAssets with an empty frame changes nothing", () => {
- const c = new AssetCoordinator();
- c.setIndex(index(["a"]));
- c.want(["a"]);
- expect(c.requestBatch()).toEqual(["a"]);
- c.applyAssets({});
- expect(c.has("a")).toBe(false);
- expect(c.requestBatch()).toEqual([]); // still pending until a response arrives
- });
- });
|