feat(world): Orte beim Vorladen vorwärmen
PlaceLayer nimmt jetzt ein optionales warmUp(root) entgegen und ruft es nach prepareModel, aber vor dem Einsetzen auf. main.js nutzt das, um Texturen hochzuladen und CSM-Shader zu übersetzen, solange der Ort noch nicht in der Szene ist — gemessen kostete das sonst rund 130 ms auf einen Schlag im ersten Bild, in dem der Hof erscheint. Schlägt das Vorwärmen fehl, wird nur gewarnt; der Ort wird trotzdem eingesetzt. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
This commit is contained in:
1 parent
522101c026
commit
1c24fbf71e
3 files changed
+68
-7
No files matched your search
+35
-2
@@ -157,10 +157,10 @@ describe("PlaceLayer", () => {
|
||||
// Spieler distance Meter südlich der Ortsmitte (three: +z ist Süden).
|
||||
const south = (distance) => ({ x: 1489, y: 0, z: -1067.5 + distance });
|
||||
|
||||
function makeLayer(load) {
|
||||
function makeLayer(load, { warmUp } = {}) {
|
||||
const scene = new Scene();
|
||||
const player = { addCollider: vi.fn(() => ({ id: 7 })), removeCollider: vi.fn() };
|
||||
const layer = new PlaceLayer({ scene, player, places: [place], load });
|
||||
const layer = new PlaceLayer({ scene, player, places: [place], load, warmUp });
|
||||
return { scene, player, layer };
|
||||
}
|
||||
|
||||
@@ -259,4 +259,37 @@ describe("PlaceLayer", () => {
|
||||
expect(load).toHaveBeenCalledTimes(1);
|
||||
expect(scene.children).toHaveLength(0);
|
||||
});
|
||||
|
||||
// Bruch: warmUp läuft erst nach dem Einsetzen oder gar nicht — der einmalige Stall durch
|
||||
// Texturupload und Shader-Übersetzung (~130 ms, gemessen im Spiel) bliebe dann im ersten Bild,
|
||||
// statt im Vorladen zu verschwinden.
|
||||
it("wärmt ein Modell vor dem Einsetzen einmalig vor", async () => {
|
||||
const model = fakeModel();
|
||||
const load = vi.fn(async () => model);
|
||||
const warmUp = vi.fn(async (root) => {
|
||||
expect(scene.children).not.toContain(root);
|
||||
});
|
||||
const { scene, player, layer } = makeLayer(load, { warmUp });
|
||||
|
||||
layer.update(south(100));
|
||||
await vi.waitFor(() => expect(scene.children).toContain(model));
|
||||
|
||||
expect(warmUp).toHaveBeenCalledTimes(1);
|
||||
expect(warmUp).toHaveBeenCalledWith(model);
|
||||
});
|
||||
|
||||
// Bruch: eine fehlschlagende Vorwärmung lässt den Ort für immer draußen, obwohl das Modell
|
||||
// längst geladen und vorbereitet ist.
|
||||
it("setzt einen Ort trotz fehlgeschlagener Vorwärmung ein und warnt", async () => {
|
||||
const warn = vi.spyOn(console, "warn").mockImplementation(() => {});
|
||||
const model = fakeModel();
|
||||
const load = vi.fn(async () => model);
|
||||
const warmUp = vi.fn(async () => { throw new Error("Kontextverlust"); });
|
||||
const { scene, layer } = makeLayer(load, { warmUp });
|
||||
|
||||
layer.update(south(100));
|
||||
await vi.waitFor(() => expect(scene.children).toContain(model));
|
||||
|
||||
expect(warn).toHaveBeenCalledWith(expect.stringContaining("hof"), expect.any(Error));
|
||||
});
|
||||
});
|
||||
Reference in new issue
Block a user