refactor(runtime): extract the live object frame
This commit is contained in:
parent
99a3e819c4
commit
4e4aac2c5a
27 changed files with 1217 additions and 371 deletions
|
|
@ -17,6 +17,20 @@ namespace AcDream.App.Tests.World;
|
|||
|
||||
public sealed class LiveEntityRuntimeTests
|
||||
{
|
||||
[Fact]
|
||||
public void RuntimeSlot_BindsExactlyOnceWithoutOwningEntityState()
|
||||
{
|
||||
var spatial = new GpuWorldState();
|
||||
var runtime = new LiveEntityRuntime(spatial, new RecordingResources());
|
||||
var slot = new LiveEntityRuntimeSlot();
|
||||
|
||||
Assert.Null(slot.Current);
|
||||
slot.Bind(runtime);
|
||||
|
||||
Assert.Same(runtime, slot.Current);
|
||||
Assert.Throws<InvalidOperationException>(() => slot.Bind(runtime));
|
||||
}
|
||||
|
||||
private sealed class RecordingResources : ILiveEntityResourceLifecycle
|
||||
{
|
||||
public int RegisterCount { get; private set; }
|
||||
|
|
@ -245,11 +259,18 @@ public sealed class LiveEntityRuntimeTests
|
|||
landblockId: 0x01010000u,
|
||||
seedCellId: 0x01010001u);
|
||||
int poseUpdates = 0;
|
||||
var runtimeSlot = new LiveEntityRuntimeSlot();
|
||||
runtimeSlot.Bind(runtime);
|
||||
var origin = new LiveWorldOriginState();
|
||||
origin.Recenter(1, 1);
|
||||
var poses = new EntityEffectPoseRegistry();
|
||||
poses.PublishMeshRefs(entity);
|
||||
poses.EffectPoseChanged += _ => poseUpdates++;
|
||||
var committer = new StaticLiveRootCommitter(
|
||||
() => runtime,
|
||||
runtimeSlot,
|
||||
shadows,
|
||||
() => (1, 1),
|
||||
_ => poseUpdates++);
|
||||
origin,
|
||||
poses);
|
||||
|
||||
body.SetFrameInCurrentCell(
|
||||
body.Position,
|
||||
|
|
@ -282,13 +303,14 @@ public sealed class LiveEntityRuntimeTests
|
|||
[Fact]
|
||||
public void StaticRootCommit_BeforeLiveRuntimeCompositionIsSafeNoOp()
|
||||
{
|
||||
LiveEntityRuntime? runtime = null;
|
||||
int poseUpdates = 0;
|
||||
var poses = new EntityEffectPoseRegistry();
|
||||
poses.EffectPoseChanged += _ => poseUpdates++;
|
||||
var committer = new StaticLiveRootCommitter(
|
||||
() => runtime,
|
||||
new LiveEntityRuntimeSlot(),
|
||||
new ShadowObjectRegistry(),
|
||||
() => (0, 0),
|
||||
_ => poseUpdates++);
|
||||
new LiveWorldOriginState(),
|
||||
poses);
|
||||
|
||||
Assert.False(committer.Commit(
|
||||
Entity(0x7F000001u, 0x70000001u),
|
||||
|
|
@ -347,26 +369,33 @@ public sealed class LiveEntityRuntimeTests
|
|||
worldOffsetY: 0f,
|
||||
landblockId: 0x01010000u,
|
||||
seedCellId: 0x01010001u);
|
||||
var runtimeSlot = new LiveEntityRuntimeSlot();
|
||||
runtimeSlot.Bind(runtime);
|
||||
var origin = new LiveWorldOriginState();
|
||||
origin.Recenter(1, 1);
|
||||
var poses = new EntityEffectPoseRegistry();
|
||||
poses.PublishMeshRefs(oldEntity);
|
||||
poses.EffectPoseChanged += _ =>
|
||||
{
|
||||
Assert.True(shadows.Suspend(oldEntity.Id));
|
||||
Assert.True(runtime.UnregisterLiveEntity(
|
||||
new DeleteObject.Parsed(guid, InstanceSequence: 1),
|
||||
isLocalPlayer: false));
|
||||
runtime.RegisterLiveEntity(Spawn(
|
||||
guid,
|
||||
instance: 2,
|
||||
positionSequence: 1,
|
||||
cell: 0x01010001u));
|
||||
runtime.MaterializeLiveEntity(
|
||||
guid,
|
||||
0x01010001u,
|
||||
id => Entity(id, guid));
|
||||
};
|
||||
var committer = new StaticLiveRootCommitter(
|
||||
() => runtime,
|
||||
runtimeSlot,
|
||||
shadows,
|
||||
() => (1, 1),
|
||||
_ =>
|
||||
{
|
||||
Assert.True(shadows.Suspend(oldEntity.Id));
|
||||
Assert.True(runtime.UnregisterLiveEntity(
|
||||
new DeleteObject.Parsed(guid, InstanceSequence: 1),
|
||||
isLocalPlayer: false));
|
||||
runtime.RegisterLiveEntity(Spawn(
|
||||
guid,
|
||||
instance: 2,
|
||||
positionSequence: 1,
|
||||
cell: 0x01010001u));
|
||||
runtime.MaterializeLiveEntity(
|
||||
guid,
|
||||
0x01010001u,
|
||||
id => Entity(id, guid));
|
||||
});
|
||||
origin,
|
||||
poses);
|
||||
|
||||
oldBody.SetFrameInCurrentCell(
|
||||
oldBody.Position,
|
||||
|
|
@ -453,7 +482,7 @@ public sealed class LiveEntityRuntimeTests
|
|||
id => Entity(id, guid))!;
|
||||
var animation = new AnimationRuntime(entity);
|
||||
runtime.SetAnimationRuntime(guid, animation);
|
||||
var view = new LiveEntityAnimationRuntimeView<AnimationRuntime>(() => runtime);
|
||||
var view = new LiveEntityAnimationRuntimeView<AnimationRuntime>(BoundSlot(runtime));
|
||||
|
||||
Assert.Equal(1, view.Count);
|
||||
Assert.Equal(entity.Id, Assert.Single(view.Keys));
|
||||
|
|
@ -489,7 +518,7 @@ public sealed class LiveEntityRuntimeTests
|
|||
id => Entity(id, guid))!;
|
||||
runtime.SetAnimationRuntime(guid, new AnimationRuntime(entity));
|
||||
}
|
||||
var view = new LiveEntityAnimationRuntimeView<AnimationRuntime>(() => runtime);
|
||||
var view = new LiveEntityAnimationRuntimeView<AnimationRuntime>(BoundSlot(runtime));
|
||||
var visited = new List<uint>();
|
||||
|
||||
foreach (KeyValuePair<uint, AnimationRuntime> pair in view)
|
||||
|
|
@ -519,7 +548,7 @@ public sealed class LiveEntityRuntimeTests
|
|||
id => Entity(id, guid))!;
|
||||
runtime.SetAnimationRuntime(guid, new AnimationRuntime(entity));
|
||||
var view = new LiveEntityAnimationRuntimeView<AnimationRuntime>(
|
||||
() => runtime);
|
||||
BoundSlot(runtime));
|
||||
var ids = new HashSet<uint>();
|
||||
|
||||
view.CopySpatialIdsTo(ids);
|
||||
|
|
@ -2803,6 +2832,13 @@ public sealed class LiveEntityRuntimeTests
|
|||
private static LoadedLandblock EmptyLandblock(uint canonicalId) =>
|
||||
new(canonicalId, new LandBlock(), Array.Empty<WorldEntity>());
|
||||
|
||||
private static LiveEntityRuntimeSlot BoundSlot(LiveEntityRuntime runtime)
|
||||
{
|
||||
var slot = new LiveEntityRuntimeSlot();
|
||||
slot.Bind(runtime);
|
||||
return slot;
|
||||
}
|
||||
|
||||
private static void ResolveParent(LiveEntityRuntime runtime, uint childGuid) =>
|
||||
runtime.ParentAttachments.Resolve(
|
||||
childGuid,
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue