refactor(runtime): acknowledge exact world host projections

This commit is contained in:
Erik 2026-07-26 18:27:41 +02:00
parent 73d0b54e38
commit 18d17d8bb1
17 changed files with 1677 additions and 72 deletions

View file

@ -338,6 +338,18 @@ public sealed class RuntimeWorldTransitStateTests
BeginPortal(first, OutdoorCell);
long secondGeneration =
second.BeginLoginReveal(OtherCell);
RuntimeWorldHostProjectionToken firstHost =
RegisterHost(first, firstGeneration, OutdoorCell);
RuntimeWorldHostProjectionToken secondHost =
RegisterHost(second, secondGeneration, OtherCell);
Assert.True(Acknowledge(
first,
firstHost,
RuntimeWorldHostAcknowledgementStage.ProjectionRegistered));
Assert.True(Acknowledge(
second,
secondHost,
RuntimeWorldHostAcknowledgementStage.ProjectionRegistered));
first.AcknowledgeDestinationReadiness(
Ready(firstGeneration, OutdoorCell));
first.AcknowledgePortalMaterialized(
@ -351,6 +363,13 @@ public sealed class RuntimeWorldTransitStateTests
Assert.False(second.IsWorldSimulationAvailable);
Assert.Equal(OtherCell, second.Snapshot.DestinationCell);
Assert.Equal(1, secondGeneration);
Assert.False(Acknowledge(
second,
firstHost,
RuntimeWorldHostAcknowledgementStage
.SimulationReleaseProjected));
Assert.Equal(1, first.Ownership.PendingHostAcknowledgementCount);
Assert.Equal(0, second.Ownership.PendingHostAcknowledgementCount);
}
[Fact]
@ -616,6 +635,195 @@ public sealed class RuntimeWorldTransitStateTests
Assert.True(state.TryQueueTeleportStart(8));
}
[Fact]
public void HostProjection_TracksExactGenerationScopedAcknowledgementSuffix()
{
var state = new RuntimeWorldTransitState();
long generation = BeginPortal(state, OutdoorCell);
RuntimeWorldHostProjectionToken host =
RegisterHost(state, generation, OutdoorCell);
Assert.Equal(
new RuntimeWorldTransitOwnershipSnapshot(
BufferedTeleportDestinationCount: 0,
PendingTeleportStartCount: 0,
ActiveTeleportCount: 1,
AcceptedTeleportDestinationCount: 0,
ActiveRevealCount: 1,
PendingDestinationReadinessCount: 1,
HostProjectionCount: 1,
PendingHostAcknowledgementCount: 1),
state.Ownership);
Assert.False(Acknowledge(
state,
host with { Generation = generation + 1 },
RuntimeWorldHostAcknowledgementStage.ProjectionRegistered));
Assert.False(Acknowledge(
state,
host with { DestinationCell = OtherCell },
RuntimeWorldHostAcknowledgementStage.ProjectionRegistered));
Assert.False(Acknowledge(
state,
host,
RuntimeWorldHostAcknowledgementStage.None));
Assert.False(Acknowledge(
state,
host,
RuntimeWorldHostAcknowledgementStage.ProjectionRegistered
| RuntimeWorldHostAcknowledgementStage
.DestinationReservationReleased));
Assert.True(Acknowledge(
state,
host,
RuntimeWorldHostAcknowledgementStage.ProjectionRegistered));
Assert.True(state.AcknowledgeDestinationReadiness(
Ready(generation, OutdoorCell)));
Assert.True(state.AcknowledgePortalMaterialized(
generation,
1,
OutdoorCell));
Assert.Equal(1, state.Ownership.PendingHostAcknowledgementCount);
Assert.True(Acknowledge(
state,
host,
RuntimeWorldHostAcknowledgementStage
.SimulationReleaseProjected));
Assert.True(state.RequireDestinationReservationRelease(host));
Assert.True(Acknowledge(
state,
host,
RuntimeWorldHostAcknowledgementStage
.DestinationReservationReleased));
Assert.True(state.AcknowledgeWorldViewportVisible(generation));
Assert.True(state.Complete(generation));
Assert.Equal(1, state.Ownership.PendingHostAcknowledgementCount);
Assert.True(Acknowledge(
state,
host,
RuntimeWorldHostAcknowledgementStage.TerminalProjected));
Assert.Equal(0, state.Ownership.HostProjectionCount);
Assert.Equal(0, state.Ownership.PendingHostAcknowledgementCount);
state.EndTeleport();
state.ResetSession();
Assert.True(state.Ownership.IsSessionIdle);
}
[Fact]
public void Cancel_ReplacesIncompleteRegistrationWithRetryableWithdrawal()
{
var state = new RuntimeWorldTransitState();
long generation = state.BeginLoginReveal(OutdoorCell);
RuntimeWorldHostProjectionToken host =
RegisterHost(state, generation, OutdoorCell);
Assert.True(state.Cancel(generation));
Assert.True(state.TryGetHostProjection(
host,
out RuntimeWorldHostProjectionSnapshot projection));
Assert.Equal(
RuntimeWorldHostAcknowledgementStage
.SimulationReleaseProjected
| RuntimeWorldHostAcknowledgementStage
.DestinationReservationReleased
| RuntimeWorldHostAcknowledgementStage.TerminalProjected,
projection.PendingAcknowledgements);
Assert.False(Acknowledge(
state,
host,
RuntimeWorldHostAcknowledgementStage.TerminalProjected));
Assert.True(Acknowledge(
state,
host,
RuntimeWorldHostAcknowledgementStage
.SimulationReleaseProjected));
Assert.True(Acknowledge(
state,
host,
RuntimeWorldHostAcknowledgementStage
.DestinationReservationReleased));
Assert.True(Acknowledge(
state,
host,
RuntimeWorldHostAcknowledgementStage.TerminalProjected));
state.ResetSession();
Assert.True(state.Ownership.IsSessionIdle);
}
[Fact]
public void Supersession_PreservesOldHostWithdrawalByExactGeneration()
{
var state = new RuntimeWorldTransitState();
long first = state.BeginLoginReveal(OutdoorCell);
RuntimeWorldHostProjectionToken firstHost =
RegisterHost(state, first, OutdoorCell);
Assert.True(Acknowledge(
state,
firstHost,
RuntimeWorldHostAcknowledgementStage.ProjectionRegistered));
long second = BeginPortal(state, OtherCell, sequence: 2);
Assert.True(state.TryGetHostProjection(
firstHost,
out RuntimeWorldHostProjectionSnapshot superseded));
Assert.True(superseded.IsSuperseding);
Assert.Equal(
RuntimeWorldHostAcknowledgementStage
.DestinationReservationReleased
| RuntimeWorldHostAcknowledgementStage.TerminalProjected,
superseded.PendingAcknowledgements);
Assert.False(Acknowledge(
state,
firstHost,
RuntimeWorldHostAcknowledgementStage.TerminalProjected));
Assert.True(Acknowledge(
state,
firstHost,
RuntimeWorldHostAcknowledgementStage
.DestinationReservationReleased));
Assert.True(Acknowledge(
state,
firstHost,
RuntimeWorldHostAcknowledgementStage.TerminalProjected));
Assert.Equal(second, state.Snapshot.Generation);
Assert.Equal(0, state.Ownership.HostProjectionCount);
}
[Fact]
public void ResetSession_RejectsUnacknowledgedHostProjection()
{
var state = new RuntimeWorldTransitState();
long generation = state.BeginLoginReveal(OutdoorCell);
RuntimeWorldHostProjectionToken host =
RegisterHost(state, generation, OutdoorCell);
InvalidOperationException error =
Assert.Throws<InvalidOperationException>(state.ResetSession);
Assert.Contains("hosts=1", error.Message);
Assert.Equal(generation, state.Snapshot.Generation);
Assert.True(state.Cancel(generation));
Assert.True(Acknowledge(
state,
host,
RuntimeWorldHostAcknowledgementStage
.SimulationReleaseProjected));
Assert.True(Acknowledge(
state,
host,
RuntimeWorldHostAcknowledgementStage
.DestinationReservationReleased));
Assert.True(Acknowledge(
state,
host,
RuntimeWorldHostAcknowledgementStage.TerminalProjected));
state.ResetSession();
}
private static long BeginPortal(
RuntimeWorldTransitState state,
uint cell,
@ -633,6 +841,25 @@ public sealed class RuntimeWorldTransitStateTests
return generation;
}
private static RuntimeWorldHostProjectionToken RegisterHost(
RuntimeWorldTransitState state,
long generation,
uint cell)
{
Assert.True(state.TryRegisterHostProjection(
generation,
cell,
out RuntimeWorldHostProjectionToken host));
return host;
}
private static bool Acknowledge(
RuntimeWorldTransitState state,
RuntimeWorldHostProjectionToken host,
RuntimeWorldHostAcknowledgementStage stage) =>
state.AcknowledgeHostProjection(
new RuntimeWorldHostAcknowledgement(host, stage));
private static RuntimeTeleportDestination Destination(
uint cell,
ushort sequence,