refactor(app): key live projections by runtime identity

Move materialized live-object sidecars and presentation worksets to exact RuntimeEntityKey ownership. Runtime remains the only GUID/incarnation/local-ID authority while hydration, animation, effects, lights, equipped children, renderer resources, visibility, liveness, and teardown resolve exact projection identities. Preserve synchronous callbacks, local-ID allocation order, and current rendering behavior.
This commit is contained in:
Erik 2026-07-25 21:50:58 +02:00
parent e18df84437
commit 420e5eea70
73 changed files with 2939 additions and 1715 deletions

View file

@ -355,7 +355,7 @@ public sealed class LiveEntityLifecycleStressTests
if (record.WorldEntity is { } entity)
{
cleanups.Add(() => Engine.ShadowObjects.Deregister(entity.Id));
cleanups.Add(() => _liveLights?.Forget(entity.Id));
cleanups.Add(() => _liveLights?.Forget(record));
}
LiveEntityTeardown.Run(cleanups);
});
@ -402,14 +402,8 @@ public sealed class LiveEntityLifecycleStressTests
8f + (ordinal / 12) * 6f,
10f);
WorldSession.EntitySpawn spawn = MissileSpawn(guid, generation, position);
LiveEntityRegistrationResult registration = Runtime.RegisterLiveEntity(spawn);
LiveEntityRecord record = Assert.IsType<LiveEntityRecord>(registration.Record);
Runtime.SetEffectProfile(
guid,
EntityEffectProfile.CreateLive(new Setup(), spawn.Physics!.Value));
WorldEntity entity = Assert.IsType<WorldEntity>(Runtime.MaterializeLiveEntity(
guid,
CellA,
LiveEntityRecord record = Runtime.RegisterAndMaterializeProjection(
spawn,
localId => new WorldEntity
{
Id = localId,
@ -419,7 +413,12 @@ public sealed class LiveEntityLifecycleStressTests
Rotation = Quaternion.Identity,
MeshRefs = Array.Empty<MeshRef>(),
ParentCellId = CellA,
}));
},
initializeProjection: exact =>
exact.EffectProfile = EntityEffectProfile.CreateLive(
new Setup(),
spawn.Physics!.Value));
WorldEntity entity = Assert.IsType<WorldEntity>(record.WorldEntity);
Assert.True(Effects.OnLiveEntityReady(guid));
Assert.True(Projectiles.TryBind(record, Setup, 0.0, 1, 1));
@ -520,13 +519,8 @@ public sealed class LiveEntityLifecycleStressTests
Router.Register(Effects);
WorldSession.EntitySpawn spawn = RecallSpawn(Guid, CellOne);
Runtime.RegisterLiveEntity(spawn);
Runtime.SetEffectProfile(
Guid,
EntityEffectProfile.CreateLive(new Setup(), spawn.Physics!.Value));
Entity = Runtime.MaterializeLiveEntity(
Guid,
CellOne,
LiveEntityRecord record = Runtime.RegisterAndMaterializeProjection(
spawn,
localId => new WorldEntity
{
Id = localId,
@ -536,7 +530,12 @@ public sealed class LiveEntityLifecycleStressTests
Rotation = Quaternion.Identity,
MeshRefs = Array.Empty<MeshRef>(),
ParentCellId = CellOne,
})!;
},
initializeProjection: exact =>
exact.EffectProfile = EntityEffectProfile.CreateLive(
new Setup(),
spawn.Physics!.Value));
Entity = Assert.IsType<WorldEntity>(record.WorldEntity);
Assert.True(Effects.OnLiveEntityReady(Guid));
_remote.Body.SnapToCell(CellOne, Entity.Position, Entity.Position);