feat(app): stage live entities before runtime placement
This commit is contained in:
parent
3f800a4aec
commit
74103f75b5
2 changed files with 187 additions and 3 deletions
|
|
@ -202,6 +202,131 @@ public sealed class LiveEntityRuntimeTests
|
|||
Assert.Equal(new[] { false, true }, visibilityEdges);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void RuntimePlacementPendingMaterialization_OwnsResourcesWithoutPublishingResidence()
|
||||
{
|
||||
const uint guid = 0x70000081u;
|
||||
const uint cell = 0x01010001u;
|
||||
var spatial = new GpuWorldState();
|
||||
spatial.AddLandblock(EmptyLandblock(0x0101FFFFu));
|
||||
var resources = new CallbackResources();
|
||||
LiveEntityRuntime runtime = LiveEntityRuntimeFixture.Create(
|
||||
spatial,
|
||||
resources);
|
||||
LiveEntityRegistrationResult registration = runtime.RegisterLiveEntity(
|
||||
Spawn(guid, instance: 1, positionSequence: 1, cell));
|
||||
RuntimeEntityRecord canonical = Assert.IsType<RuntimeEntityRecord>(
|
||||
registration.Canonical);
|
||||
uint acceptedCell = canonical.FullCellId;
|
||||
ulong spatialAuthority = canonical.SpatialAuthorityVersion;
|
||||
ulong placementCommit = canonical.PlacementCommitVersion;
|
||||
ulong clockEpoch = canonical.ObjectClockEpoch;
|
||||
bool clockActive = canonical.ObjectClock.IsActive;
|
||||
RuntimePhysicsOwnershipSnapshot physicsOwnership =
|
||||
runtime.Physics.CaptureOwnership();
|
||||
var visibilityEdges = new List<bool>();
|
||||
runtime.ProjectionVisibilityChanged += (_, visible) =>
|
||||
visibilityEdges.Add(visible);
|
||||
resources.OnRegister = entity =>
|
||||
{
|
||||
Assert.False(entity.IsDrawVisible);
|
||||
Assert.True(runtime.TryGetRecord(guid, out LiveEntityRecord current));
|
||||
Assert.False(current.IsSpatiallyProjected);
|
||||
Assert.False(current.IsSpatiallyVisible);
|
||||
Assert.False(runtime.RebucketLiveEntity(guid, cell));
|
||||
};
|
||||
|
||||
WorldEntity entity = Assert.IsType<WorldEntity>(
|
||||
runtime.MaterializeLiveEntity(
|
||||
canonical,
|
||||
cell,
|
||||
id => Entity(id, guid),
|
||||
LiveEntityProjectionKind.World,
|
||||
initializeProjection: null,
|
||||
out LiveEntityRecord? record,
|
||||
LiveEntityMaterializationResidence.AwaitRuntimePlacement));
|
||||
|
||||
Assert.NotNull(record);
|
||||
Assert.Same(entity, record!.WorldEntity);
|
||||
Assert.True(record.ResourcesRegistered);
|
||||
Assert.False(record.IsSpatiallyProjected);
|
||||
Assert.False(record.IsSpatiallyVisible);
|
||||
Assert.False(entity.IsDrawVisible);
|
||||
Assert.Equal(acceptedCell, canonical.FullCellId);
|
||||
Assert.Equal(spatialAuthority, canonical.SpatialAuthorityVersion);
|
||||
Assert.Equal(placementCommit, canonical.PlacementCommitVersion);
|
||||
Assert.Equal(clockEpoch, canonical.ObjectClockEpoch);
|
||||
Assert.Equal(clockActive, canonical.ObjectClock.IsActive);
|
||||
Assert.Equal(physicsOwnership, runtime.Physics.CaptureOwnership());
|
||||
Assert.Equal(0, runtime.SpatialRootObjectCount);
|
||||
Assert.Equal(1, resources.RegisterCount);
|
||||
Assert.Empty(spatial.Entities);
|
||||
Assert.Empty(runtime.VisibleRecords);
|
||||
Assert.Empty(visibilityEdges);
|
||||
|
||||
WorldEntity retained = Assert.IsType<WorldEntity>(
|
||||
runtime.MaterializeLiveEntity(
|
||||
canonical,
|
||||
cell,
|
||||
id => Entity(id, guid),
|
||||
LiveEntityProjectionKind.World,
|
||||
initializeProjection: null,
|
||||
out LiveEntityRecord? retainedRecord,
|
||||
LiveEntityMaterializationResidence.AwaitRuntimePlacement));
|
||||
Assert.Same(entity, retained);
|
||||
Assert.Same(record, retainedRecord);
|
||||
Assert.Equal(1, resources.RegisterCount);
|
||||
Assert.False(runtime.RebucketLiveEntity(guid, cell));
|
||||
Assert.Throws<InvalidOperationException>(() =>
|
||||
runtime.MaterializeLiveEntity(
|
||||
canonical,
|
||||
cell,
|
||||
id => Entity(id, guid),
|
||||
LiveEntityProjectionKind.World,
|
||||
initializeProjection: null,
|
||||
out _,
|
||||
LiveEntityMaterializationResidence.LegacyImmediate));
|
||||
Assert.Empty(spatial.Entities);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void LegacyMaterialization_CannotSwitchToRuntimePlacementResidence()
|
||||
{
|
||||
const uint guid = 0x70000082u;
|
||||
const uint cell = 0x01010001u;
|
||||
var spatial = new GpuWorldState();
|
||||
spatial.AddLandblock(EmptyLandblock(0x0101FFFFu));
|
||||
var resources = new RecordingResources();
|
||||
var runtime = LiveEntityRuntimeFixture.Create(spatial, resources);
|
||||
RuntimeEntityRecord canonical = Assert.IsType<RuntimeEntityRecord>(
|
||||
runtime.RegisterLiveEntity(
|
||||
Spawn(guid, instance: 1, positionSequence: 1, cell)).Canonical);
|
||||
WorldEntity entity = Assert.IsType<WorldEntity>(
|
||||
runtime.MaterializeLiveEntity(
|
||||
canonical,
|
||||
cell,
|
||||
id => Entity(id, guid),
|
||||
LiveEntityProjectionKind.World,
|
||||
initializeProjection: null,
|
||||
out LiveEntityRecord? record));
|
||||
|
||||
Assert.Throws<InvalidOperationException>(() =>
|
||||
runtime.MaterializeLiveEntity(
|
||||
canonical,
|
||||
cell,
|
||||
id => Entity(id, guid),
|
||||
LiveEntityProjectionKind.World,
|
||||
initializeProjection: null,
|
||||
out _,
|
||||
LiveEntityMaterializationResidence.AwaitRuntimePlacement));
|
||||
|
||||
Assert.True(record!.IsSpatiallyProjected);
|
||||
Assert.True(record.IsSpatiallyVisible);
|
||||
Assert.True(entity.IsDrawVisible);
|
||||
Assert.Single(spatial.Entities);
|
||||
Assert.Equal(1, resources.RegisterCount);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void StaticRootCommit_HiddenObjectUpdatesPoseWithoutRestoringShadow()
|
||||
{
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue