fix(streaming): preserve portal destination ownership
Detach old-world spatial ownership atomically, prioritize destination retirement dependencies, and reveal the viewport at the retail transition edge. Give private paperdoll views independent mesh ownership and retain dormant ACE entities so portal revisits preserve server objects without extending active GPU lifetimes.
This commit is contained in:
parent
2c848d4167
commit
823936ec31
57 changed files with 2551 additions and 324 deletions
|
|
@ -15,7 +15,8 @@ public sealed class WorldRevealCoordinatorTests
|
|||
|
||||
public WorldRevealCoordinator Build(
|
||||
List<string>? logs = null,
|
||||
IWorldRevealStreamingScheduler? streaming = null) => new(
|
||||
IWorldRevealStreamingScheduler? streaming = null,
|
||||
IWorldRevealRenderResourceScheduler? renderResources = null) => new(
|
||||
isRenderNeighborhoodReady: (_, _) => RenderReady,
|
||||
isSpawnCellReady: _ => CollisionReady,
|
||||
isTerrainNeighborhoodReady: (_, _) => CollisionReady,
|
||||
|
|
@ -28,7 +29,8 @@ public sealed class WorldRevealCoordinatorTests
|
|||
},
|
||||
isSpawnClaimUnhydratable: _ => false,
|
||||
log: logs is null ? null : new Action<string>(logs.Add),
|
||||
streaming: streaming);
|
||||
streaming: streaming,
|
||||
renderResources: renderResources);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
|
|
@ -152,6 +154,47 @@ public sealed class WorldRevealCoordinatorTests
|
|||
Assert.Equal(1, audio.ResumeCalls);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void PortalViewportReveal_ReopensWorldWithoutCompletingProtocolTail()
|
||||
{
|
||||
var availability = new WorldGenerationAvailabilityState();
|
||||
var world = new GpuWorldState(availability: availability);
|
||||
var audio = new RecordingAudioQuiescence();
|
||||
var quiescence = new WorldGenerationQuiescence(
|
||||
availability,
|
||||
new SelectionState(),
|
||||
world,
|
||||
audio);
|
||||
var scheduler = new RecordingDestinationScheduler();
|
||||
var coordinator = new WorldRevealCoordinator(
|
||||
isRenderNeighborhoodReady: (_, _) => true,
|
||||
isSpawnCellReady: _ => true,
|
||||
isTerrainNeighborhoodReady: (_, _) => true,
|
||||
areCompositeTexturesReady: () => true,
|
||||
prepareCompositeTextures: (_, _) => { },
|
||||
invalidateCompositeTextures: () => { },
|
||||
isSpawnClaimUnhydratable: _ => false,
|
||||
quiescence: quiescence,
|
||||
streaming: scheduler);
|
||||
long generation = coordinator.Begin(
|
||||
WorldRevealKind.Portal,
|
||||
0x3032001Cu);
|
||||
|
||||
coordinator.RevealWorldViewport();
|
||||
coordinator.RevealWorldViewport();
|
||||
|
||||
Assert.True(availability.IsWorldAvailable);
|
||||
Assert.False(coordinator.Snapshot.Completed);
|
||||
Assert.Equal(1, audio.ResumeCalls);
|
||||
Assert.Equal([generation], scheduler.Ends);
|
||||
|
||||
coordinator.Complete();
|
||||
|
||||
Assert.True(coordinator.Snapshot.Completed);
|
||||
Assert.Equal(1, audio.ResumeCalls);
|
||||
Assert.Equal([generation], scheduler.Ends);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void RevealGeneration_OwnsExactDestinationReservationUntilCompletion()
|
||||
{
|
||||
|
|
@ -176,6 +219,28 @@ public sealed class WorldRevealCoordinatorTests
|
|||
Assert.Equal([second], scheduler.Ends);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void RevealGeneration_OwnsRenderUploadProfileUntilViewportRelease()
|
||||
{
|
||||
var state = new State();
|
||||
var resources = new RecordingRenderResourceScheduler();
|
||||
WorldRevealCoordinator coordinator =
|
||||
state.Build(renderResources: resources);
|
||||
|
||||
long first = coordinator.Begin(
|
||||
WorldRevealKind.Portal,
|
||||
0x11340021u);
|
||||
long second = coordinator.Begin(
|
||||
WorldRevealKind.Portal,
|
||||
0x20210123u);
|
||||
|
||||
Assert.Equal([first, second], resources.Begins);
|
||||
coordinator.RevealWorldViewport();
|
||||
coordinator.Complete();
|
||||
|
||||
Assert.Equal([second], resources.Ends);
|
||||
}
|
||||
|
||||
private sealed class RecordingAudioQuiescence : AcDream.App.Audio.IWorldAudioQuiescence
|
||||
{
|
||||
public int SuspendCalls { get; private set; }
|
||||
|
|
@ -201,4 +266,17 @@ public sealed class WorldRevealCoordinatorTests
|
|||
public void EndDestinationReservation(long revealGeneration) =>
|
||||
Ends.Add(revealGeneration);
|
||||
}
|
||||
|
||||
private sealed class RecordingRenderResourceScheduler
|
||||
: IWorldRevealRenderResourceScheduler
|
||||
{
|
||||
public List<long> Begins { get; } = [];
|
||||
public List<long> Ends { get; } = [];
|
||||
|
||||
public void BeginDestinationReveal(long revealGeneration) =>
|
||||
Begins.Add(revealGeneration);
|
||||
|
||||
public void EndDestinationReveal(long revealGeneration) =>
|
||||
Ends.Add(revealGeneration);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue