fix(world): restore portal and distant use lifecycles

This commit is contained in:
Erik 2026-07-25 09:59:25 +02:00
parent c730632075
commit 1a14812c44
18 changed files with 401 additions and 196 deletions

View file

@ -1,4 +1,5 @@
using AcDream.App.Streaming;
using AcDream.App.World;
using AcDream.Core.Selection;
namespace AcDream.App.Tests.Streaming;
@ -155,7 +156,7 @@ public sealed class WorldRevealCoordinatorTests
}
[Fact]
public void PortalViewportReveal_ReopensWorldWithoutCompletingProtocolTail()
public void Materialization_ReopensWorldBeforePortalViewportRelease()
{
var availability = new WorldGenerationAvailabilityState();
var world = new GpuWorldState(availability: availability);
@ -180,6 +181,16 @@ public sealed class WorldRevealCoordinatorTests
WorldRevealKind.Portal,
0x3032001Cu);
Assert.False(availability.IsWorldAvailable);
coordinator.ObserveMaterialized();
Assert.True(availability.IsWorldAvailable);
Assert.False(coordinator.Snapshot.WorldViewportObserved);
Assert.False(coordinator.Snapshot.Completed);
Assert.Equal(1, audio.ResumeCalls);
Assert.Empty(scheduler.Ends);
coordinator.RevealWorldViewport();
coordinator.RevealWorldViewport();
@ -195,6 +206,53 @@ public sealed class WorldRevealCoordinatorTests
Assert.Equal([generation], scheduler.Ends);
}
[Fact]
public void TunnelContinue_TicksDestinationObjectsBehindPortalViewport()
{
var availability = new WorldGenerationAvailabilityState();
var world = new GpuWorldState(availability: availability);
var quiescence = new WorldGenerationQuiescence(
availability,
new SelectionState(),
world,
audio: null);
var scheduler = new RecordingDestinationScheduler();
var coordinator = new WorldRevealCoordinator(
isRenderNeighborhoodReady: (_, _) => true,
isSpawnCellReady: _ => true,
isTerrainNeighborhoodReady: (_, _) => true,
areCompositeTexturesReady: () => true,
prepareCompositeTextures: (_, _) => { },
invalidateCompositeTextures: () => { },
isSpawnClaimUnhydratable: _ => false,
quiescence: quiescence,
streaming: scheduler);
var calls = new List<string>();
var frame = new RetailLiveFrameCoordinator(
new global::AcDream.App.Tests.TestLiveObjectFramePhase(
_ => calls.Add("objects")),
world,
new global::AcDream.App.Tests.TestLiveSessionFramePhase(
() => calls.Add("network")),
new global::AcDream.App.Tests.TestPostNetworkCommandFramePhase(
() => calls.Add("commands")),
new global::AcDream.App.Tests.TestLiveSpatialReconcilePhase(
() => calls.Add("spatial")),
availability);
coordinator.Begin(WorldRevealKind.Portal, 0x3032001Cu);
frame.Tick(1f / 60f);
Assert.Equal(["network", "commands"], calls);
calls.Clear();
coordinator.ObserveMaterialized();
frame.Tick(1f / 60f);
Assert.Equal(["objects", "network", "commands", "spatial"], calls);
Assert.Empty(scheduler.Ends);
Assert.False(coordinator.Snapshot.WorldViewportObserved);
}
[Fact]
public void RevealGeneration_OwnsExactDestinationReservationUntilCompletion()
{