feat(physics): port retail complete object frame pipeline
Restore the named-retail object update order across local, remote, static, projectile, animation, shadow, teleport, and effect lifetimes. Separate authoritative root commits from spatial rebucketing, preserve per-owner hook/FIFO ordering, and remove update-path allocations with exact lifecycle and residency gates. Add deterministic conformance, adversarial lifetime, GUID-reuse, pending-cell, quaternion, timestamp, and allocation coverage. Release build is warning-free and all 6,446 tests pass with five intentional skips; retail, architecture, and adversarial reviews are clean. Co-authored-by: OpenAI Codex <codex@openai.com>
This commit is contained in:
parent
31a0889f08
commit
f961d70023
77 changed files with 12513 additions and 1871 deletions
|
|
@ -260,6 +260,193 @@ public sealed class EntityScriptActivatorTests
|
|||
Assert.Equal(new Vector3(5, 5, 5), p.Recording.Calls[0].Pos);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void DatStaticAnimationOwner_RegistersAndUnregistersExactlyOnce()
|
||||
{
|
||||
var p = BuildPipeline();
|
||||
int registerCount = 0;
|
||||
int unregisterCount = 0;
|
||||
WorldEntity? registeredEntity = null;
|
||||
ScriptActivationInfo info = new(
|
||||
ScriptId: 0,
|
||||
PartTransforms: Array.Empty<Matrix4x4>(),
|
||||
DefaultAnimationId: 0x03000001u,
|
||||
UsesStaticAnimationWorkset: true);
|
||||
var activator = new EntityScriptActivator(
|
||||
p.Runner,
|
||||
p.Sink,
|
||||
p.Poses,
|
||||
_ => info,
|
||||
registerDatStaticAnimationOwner: (entity, actual) =>
|
||||
{
|
||||
registerCount++;
|
||||
registeredEntity = entity;
|
||||
Assert.Same(info, actual);
|
||||
},
|
||||
unregisterDatStaticAnimationOwner: ownerId =>
|
||||
{
|
||||
unregisterCount++;
|
||||
Assert.Equal(0x40A9B420u, ownerId);
|
||||
});
|
||||
WorldEntity entity = MakeDatStatic(0x40A9B420u, Vector3.One);
|
||||
|
||||
activator.OnCreate(entity);
|
||||
activator.OnCreate(entity);
|
||||
activator.OnRemove(entity);
|
||||
activator.OnRemove(entity);
|
||||
|
||||
Assert.Equal(1, registerCount);
|
||||
Assert.Equal(1, unregisterCount);
|
||||
Assert.Same(entity, registeredEntity);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void LiveNonStaticEntity_DoesNotEnterStaticAnimationWorkset()
|
||||
{
|
||||
var p = BuildPipeline();
|
||||
int registerCount = 0;
|
||||
var activator = new EntityScriptActivator(
|
||||
p.Runner,
|
||||
p.Sink,
|
||||
p.Poses,
|
||||
_ => new ScriptActivationInfo(
|
||||
ScriptId: 0,
|
||||
PartTransforms: Array.Empty<Matrix4x4>(),
|
||||
DefaultAnimationId: 0x03000001u),
|
||||
registerDatStaticAnimationOwner: (_, _) => registerCount++);
|
||||
|
||||
activator.OnCreate(MakeEntity(0x70000420u, Vector3.Zero));
|
||||
|
||||
Assert.Equal(0, registerCount);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void LivePhysicsStaticEntity_EntersAndLeavesStaticAnimationWorkset()
|
||||
{
|
||||
var p = BuildPipeline();
|
||||
int registerCount = 0;
|
||||
int unregisterCount = 0;
|
||||
var activator = new EntityScriptActivator(
|
||||
p.Runner,
|
||||
p.Sink,
|
||||
p.Poses,
|
||||
_ => new ScriptActivationInfo(
|
||||
ScriptId: 0,
|
||||
PartTransforms: Array.Empty<Matrix4x4>(),
|
||||
DefaultAnimationId: 0x03000001u,
|
||||
UsesStaticAnimationWorkset: true),
|
||||
registerDatStaticAnimationOwner: (_, _) => registerCount++,
|
||||
unregisterDatStaticAnimationOwner: _ => unregisterCount++);
|
||||
WorldEntity entity = MakeEntity(0x70000421u, Vector3.Zero);
|
||||
|
||||
activator.OnCreate(entity);
|
||||
activator.OnRemove(entity);
|
||||
|
||||
Assert.Equal(1, registerCount);
|
||||
Assert.Equal(1, unregisterCount);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void DatStaticActivation_RetriesOnlyIncompleteAcquisitionStages()
|
||||
{
|
||||
var p = BuildPipeline(
|
||||
(0xAAu, BuildScript((10.0, new CreateParticleHook { EmitterInfoId = 100 }))));
|
||||
WorldEntity entity = MakeDatStatic(0x40A9B421u, Vector3.Zero);
|
||||
var setup = new DatReaderWriter.DBObjs.Setup();
|
||||
ScriptActivationInfo info = new(
|
||||
ScriptId: 0xAAu,
|
||||
PartTransforms: Array.Empty<Matrix4x4>(),
|
||||
EffectProfile: EntityEffectProfile.CreateDatStatic(setup),
|
||||
Setup: setup,
|
||||
DefaultAnimationId: 0x03000001u,
|
||||
UsesStaticAnimationWorkset: true);
|
||||
int effectAttempts = 0;
|
||||
int animationAttempts = 0;
|
||||
var activator = new EntityScriptActivator(
|
||||
p.Runner,
|
||||
p.Sink,
|
||||
p.Poses,
|
||||
_ => info,
|
||||
registerDatStaticEffectOwner: (_, _, _) =>
|
||||
{
|
||||
effectAttempts++;
|
||||
if (effectAttempts == 1)
|
||||
throw new InvalidOperationException("effect acquire fault");
|
||||
},
|
||||
registerDatStaticAnimationOwner: (_, _) =>
|
||||
{
|
||||
animationAttempts++;
|
||||
if (animationAttempts == 1)
|
||||
throw new InvalidOperationException("animation acquire fault");
|
||||
});
|
||||
|
||||
Assert.Throws<InvalidOperationException>(() => activator.OnCreate(entity));
|
||||
Assert.Equal(1, effectAttempts);
|
||||
Assert.Equal(0, animationAttempts);
|
||||
Assert.Equal(0, p.Runner.ActiveOwnerCount);
|
||||
|
||||
Assert.Throws<InvalidOperationException>(() => activator.OnCreate(entity));
|
||||
Assert.Equal(2, effectAttempts);
|
||||
Assert.Equal(1, animationAttempts);
|
||||
Assert.Equal(0, p.Runner.ActiveOwnerCount);
|
||||
|
||||
activator.OnCreate(entity);
|
||||
activator.OnCreate(entity);
|
||||
Assert.Equal(2, effectAttempts);
|
||||
Assert.Equal(2, animationAttempts);
|
||||
Assert.Equal(1, p.Runner.ActiveOwnerCount);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void DatStaticRemoval_RetriesOnlyIncompleteReleaseStages()
|
||||
{
|
||||
var p = BuildPipeline();
|
||||
WorldEntity entity = MakeDatStatic(0x40A9B422u, Vector3.Zero);
|
||||
var setup = new DatReaderWriter.DBObjs.Setup();
|
||||
ScriptActivationInfo info = new(
|
||||
ScriptId: 0,
|
||||
PartTransforms: Array.Empty<Matrix4x4>(),
|
||||
EffectProfile: EntityEffectProfile.CreateDatStatic(setup),
|
||||
Setup: setup,
|
||||
DefaultAnimationId: 0x03000001u,
|
||||
UsesStaticAnimationWorkset: true);
|
||||
int animationReleaseAttempts = 0;
|
||||
int effectReleaseAttempts = 0;
|
||||
var activator = new EntityScriptActivator(
|
||||
p.Runner,
|
||||
p.Sink,
|
||||
p.Poses,
|
||||
_ => info,
|
||||
registerDatStaticEffectOwner: (_, _, _) => { },
|
||||
unregisterDatStaticEffectOwner: _ =>
|
||||
{
|
||||
effectReleaseAttempts++;
|
||||
if (effectReleaseAttempts == 1)
|
||||
throw new InvalidOperationException("effect release fault");
|
||||
},
|
||||
registerDatStaticAnimationOwner: (_, _) => { },
|
||||
unregisterDatStaticAnimationOwner: _ =>
|
||||
{
|
||||
animationReleaseAttempts++;
|
||||
if (animationReleaseAttempts == 1)
|
||||
throw new InvalidOperationException("animation release fault");
|
||||
});
|
||||
activator.OnCreate(entity);
|
||||
|
||||
Assert.Throws<InvalidOperationException>(() => activator.OnRemove(entity));
|
||||
Assert.Equal(1, animationReleaseAttempts);
|
||||
Assert.Equal(0, effectReleaseAttempts);
|
||||
|
||||
Assert.Throws<InvalidOperationException>(() => activator.OnRemove(entity));
|
||||
Assert.Equal(2, animationReleaseAttempts);
|
||||
Assert.Equal(1, effectReleaseAttempts);
|
||||
|
||||
activator.OnRemove(entity);
|
||||
activator.OnRemove(entity);
|
||||
Assert.Equal(2, animationReleaseAttempts);
|
||||
Assert.Equal(2, effectReleaseAttempts);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void CollidingDatEntityIds_FailFastAtAllocatorBoundary()
|
||||
{
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue