using System;
namespace Luneraria.View
{
///
/// Fixed simulation tick (U2C): frame time goes into an accumulator, and whole steps of
/// LuneBalance.SimStep (0.05 s) come out. The frame rate only decides how many steps run in a
/// frame, never what a step does, so every frame rate produces the same sequence of steps.
/// Alpha is the fraction of the next step already elapsed; views interpolate with it.
///
public sealed class LuneClock
{
public readonly double Step;
/// Upper bound per frame; a stalled frame is caught up over the next frames.
public int MaxStepsPerFrame = 200;
double _accumulator;
public LuneClock(double step)
{
Step = step;
}
public double Alpha { get { return Math.Min(1.0, _accumulator / Step); } }
public void Reset()
{
_accumulator = 0.0;
}
/// Adds frame time and runs whole steps; step returns false when it has to stop.
public int Advance(double seconds, Func step)
{
if (seconds > 0.0)
_accumulator += seconds;
int count = 0;
while (_accumulator >= Step && count < MaxStepsPerFrame)
{
_accumulator -= Step;
count++;
if (!step())
{
_accumulator = 0.0;
break;
}
}
return count;
}
}
}