fix(animation): harden presentation phase handoffs

Own every borrowed PartArray frame across callbacks, version presentation state across appearance rebinding, reject recursive phase consumption, and preserve static MotionDone when only a stale visual pose is discarded.
This commit is contained in:
Erik 2026-07-21 10:01:25 +02:00
parent a2fd61684a
commit 833520253a
10 changed files with 657 additions and 140 deletions

View file

@ -248,10 +248,9 @@ public sealed class AnimationSequencer
// allocation instead of one `new PartTransform[partCount]` per Advance()
// call (every animated entity, every tick, including idle NPCs on a
// breathe cycle). BuildBlendedFrame/BuildIdentityFrame overwrite every
// slot before returning this array, so the values are bit-identical to
// the old fresh-array version; callers (GameWindow.TickAnimations)
// consume the returned IReadOnlyList<PartTransform> synchronously within
// the same loop iteration and never cache it across Advance() calls.
// authored slot before returning this view. The view is borrowed only for
// the producing call: App schedulers copy its authored prefix into their
// incarnation-owned handoff buffer before any callback or later phase.
private readonly PartTransform[] _partTransformScratch;
private readonly PartTransformBuffer _partTransformView;