Sim speed fix: scripted poses are not drawn ahead; a step cannot reset its clock; DrawAhead.Time deleted

DrawAhead leaves a ship in a wormhole animation where the step put it. The clock is
one static instance; a zone entered inside a step ends that frame's stepping and the
clock resets between frames (SimClock.Reset throws inside Advance). DrawAhead.Time had
no consumer.

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
This commit is contained in:
Meta Vens 2026-10-08 23:39:30 +02:00
commit 257a8a4795
4 changed files with 68 additions and 14 deletions

View file

@ -16,6 +16,7 @@ public sealed class SimClock
private readonly double _period;
private double _accumulator;
private bool _advancing;
public SimClock(float step, float stepsPerRealSecond = 60)
{
@ -36,19 +37,32 @@ public sealed class SimClock
// Sim seconds since the last step, 0 <= Lead < Step.
public float Lead => (float) (_accumulator * StepsPerRealSecond * Step);
// Forgets the real time paid toward the next step (a new zone starts between steps). A step cannot do this to the
// clock that is running it.
public void Reset()
{
if (_advancing) throw new InvalidOperationException("A step cannot reset the clock that is running it.");
_accumulator = 0;
}
// Feeds real seconds (negative counts as none, one frame counts at most MaxFrameSeconds) and runs the whole
// steps they pay for. Returns how many ran.
public int Advance(float realSeconds, Action<float> step)
{
_accumulator += Math.Min(Math.Max(realSeconds, 0f), MaxFrameSeconds);
var ran = 0;
while (_accumulator >= _period)
_advancing = true;
try
{
_accumulator -= _period;
step(Step);
Steps++;
ran++;
while (_accumulator >= _period)
{
_accumulator -= _period;
step(Step);
Steps++;
ran++;
}
}
finally { _advancing = false; }
return ran;
}
}