feat(headless): hydrate isolated collision worlds

This commit is contained in:
Erik 2026-07-27 09:25:58 +02:00
parent 9569dadb57
commit b6547ff38c
20 changed files with 1960 additions and 101 deletions

View file

@ -75,9 +75,12 @@ internal sealed class HeadlessProcessScheduler
internal HeadlessSchedulerSnapshot CaptureSnapshot()
{
int activeSessionCount = 0;
int faultedSessionCount = 0;
for (int index = 0; index < _slots.Length; index++)
{
if (!_slots[index].Session.IsPolicyComplete)
if (_slots[index].Session.IsFaulted)
faultedSessionCount++;
else if (!_slots[index].Session.IsPolicyComplete)
activeSessionCount++;
}
@ -87,6 +90,7 @@ internal sealed class HeadlessProcessScheduler
Interlocked.Read(ref _turnCount),
Interlocked.Read(ref _catchUpCollapseCount),
activeSessionCount,
faultedSessionCount,
NextDeadline());
}
@ -121,33 +125,41 @@ internal sealed class HeadlessProcessScheduler
if (session.IsPolicyComplete)
continue;
if (session.IsReconnectPending)
try
{
if (nowTimestamp < session.ReconnectDeadline)
if (session.IsReconnectPending)
{
if (nowTimestamp < session.ReconnectDeadline)
continue;
RuntimeSessionStartResult result =
session.CompletePendingReconnect(nowTimestamp);
if (result.Status
is not RuntimeSessionStartStatus.Connected)
{
throw result.Error
?? new InvalidOperationException(
$"Headless session reconnect completed with {result.Status}.");
}
slot.LastTurnTimestamp = nowTimestamp;
slot.NextDeadline = AddTicks(
nowTimestamp,
_periodTicks);
dispatched = true;
continue;
}
if (nowTimestamp < slot.NextDeadline)
continue;
RuntimeSessionStartResult result =
session.CompletePendingReconnect(nowTimestamp);
if (result.Status
is not RuntimeSessionStartStatus.Connected)
{
throw result.Error
?? new InvalidOperationException(
$"Headless session reconnect completed with {result.Status}.");
}
slot.LastTurnTimestamp = nowTimestamp;
slot.NextDeadline = AddTicks(
nowTimestamp,
_periodTicks);
DispatchSessionDue(slot, nowTimestamp);
dispatched = true;
}
catch (Exception error)
{
session.Quarantine(error);
dispatched = true;
continue;
}
if (nowTimestamp < slot.NextDeadline)
continue;
DispatchSessionDue(slot, nowTimestamp);
dispatched = true;
}
return dispatched;
}
@ -246,4 +258,5 @@ internal readonly record struct HeadlessSchedulerSnapshot(
long TurnCount,
long CatchUpCollapseCount,
int ActiveSessionCount,
int FaultedSessionCount,
long NextDeadline);