refactor(streaming): compose landblock presentation transaction
Own render, physics, DAT-static presentation, and retained static-resource rebinds behind retryable receipts so a failed publication resumes its exact unfinished suffix without replaying retail create-time defaults. Co-authored-by: Codex <noreply@openai.com>
This commit is contained in:
parent
e1110f7e54
commit
ea0da8c8ae
15 changed files with 1744 additions and 89 deletions
|
|
@ -78,7 +78,7 @@ internal sealed class RetailStaticAnimatingObjectScheduler : ILiveStaticPartFram
|
|||
|
||||
internal int Count => _owners.Count;
|
||||
|
||||
public void Register(WorldEntity entity, ScriptActivationInfo info)
|
||||
public bool Register(WorldEntity entity, ScriptActivationInfo info)
|
||||
{
|
||||
ArgumentNullException.ThrowIfNull(entity);
|
||||
ArgumentNullException.ThrowIfNull(info);
|
||||
|
|
@ -86,13 +86,13 @@ internal sealed class RetailStaticAnimatingObjectScheduler : ILiveStaticPartFram
|
|||
|| info.Setup is not { } setup
|
||||
|| info.DefaultAnimationId == 0)
|
||||
{
|
||||
return;
|
||||
return false;
|
||||
}
|
||||
|
||||
if (_owners.TryGetValue(entity.Id, out Owner? retained))
|
||||
{
|
||||
if (ReferenceEquals(retained.Entity, entity))
|
||||
return;
|
||||
return true;
|
||||
throw new InvalidOperationException(
|
||||
$"DAT-static animation owner 0x{entity.Id:X8} is already registered.");
|
||||
}
|
||||
|
|
@ -110,7 +110,7 @@ internal sealed class RetailStaticAnimatingObjectScheduler : ILiveStaticPartFram
|
|||
new MotionTable(),
|
||||
_animationLoader);
|
||||
if (!sequencer.HasCurrentNode)
|
||||
return;
|
||||
return false;
|
||||
}
|
||||
|
||||
int partCount = setup.Parts.Count;
|
||||
|
|
@ -131,6 +131,63 @@ internal sealed class RetailStaticAnimatingObjectScheduler : ILiveStaticPartFram
|
|||
SurfaceOverrides = surfaces,
|
||||
PartAvailable = available,
|
||||
});
|
||||
return true;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Rebinds the retained retail static-animation workset member to a fresh
|
||||
/// landblock snapshot without reconstructing its PartArray sequencer or
|
||||
/// restarting Setup.DefaultAnimation.
|
||||
/// </summary>
|
||||
public void Rebind(WorldEntity entity, ScriptActivationInfo info)
|
||||
{
|
||||
ArgumentNullException.ThrowIfNull(entity);
|
||||
ArgumentNullException.ThrowIfNull(info);
|
||||
if (!_owners.TryGetValue(entity.Id, out Owner? owner))
|
||||
{
|
||||
throw new InvalidOperationException(
|
||||
$"DAT-static animation owner 0x{entity.Id:X8} is not registered.");
|
||||
}
|
||||
if (ReferenceEquals(owner.Entity, entity))
|
||||
return;
|
||||
if (entity.ServerGuid != 0
|
||||
|| !info.UsesStaticAnimationWorkset
|
||||
|| info.Setup is null
|
||||
|| info.DefaultAnimationId == 0)
|
||||
{
|
||||
throw new InvalidOperationException(
|
||||
$"DAT-static animation owner 0x{entity.Id:X8} cannot be rebound to incompatible Setup data.");
|
||||
}
|
||||
|
||||
int partCount = owner.Setup.Parts.Count;
|
||||
uint[] gfxIds = BuildPartGfxIds(owner.Setup, entity);
|
||||
bool[] available = new bool[partCount];
|
||||
if (info.PartAvailability is { } supplied)
|
||||
{
|
||||
for (int i = 0; i < partCount && i < supplied.Count; i++)
|
||||
available[i] = supplied[i];
|
||||
}
|
||||
|
||||
// Compose publishes the owner's retained lists directly. Detach the
|
||||
// displaced immutable snapshot before those lists continue advancing
|
||||
// under the replacement entity.
|
||||
WorldEntity displaced = owner.Entity;
|
||||
if (ReferenceEquals(displaced.MeshRefs, owner.MeshRefs))
|
||||
displaced.MeshRefs = owner.MeshRefs.ToArray();
|
||||
if (ReferenceEquals(displaced.IndexedPartTransforms, owner.PartPoses)
|
||||
|| ReferenceEquals(displaced.IndexedPartAvailable, owner.PartAvailable))
|
||||
{
|
||||
displaced.SetIndexedPartPoses(
|
||||
owner.PartPoses.ToArray(),
|
||||
owner.PartAvailable.ToArray());
|
||||
}
|
||||
|
||||
owner.Entity = entity;
|
||||
owner.PartGfxIds = gfxIds;
|
||||
owner.SurfaceOverrides = MatchSurfaceOverrides(entity, gfxIds, available);
|
||||
owner.PartAvailable = available;
|
||||
owner.HasPreparedLivePartFrames = false;
|
||||
owner.PreparedLivePartFrames.Clear();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue