namespace TeleWave.Domain.Programming;
///
/// Состояние слота: где остановились в текущем элементе. Курсор хранит ссылку на элемент, а не
/// числовой индекс в группе, — при удалении позиции из группы он корректно переезжает на следующую,
/// а не сдвигает всё.
///
/// Состояние существует потому, что сетка эластичная: сколько единиц уйдёт за один выход слота,
/// зависит от фактических длительностей, и вычислить это арифметически от эпохи нельзя.
///
public class SlotState
{
public Guid SlotId { get; private set; }
public GroupElementKind? CurrentElementKind { get; private set; }
public Guid? CurrentElementId { get; private set; }
/// Позиция следующей единицы внутри текущего элемента.
public int NextUnitIndex { get; private set; }
private SlotState() { }
public static SlotState Create(Guid slotId) => new() { SlotId = slotId, NextUnitIndex = 0 };
/// Продолжить текущий элемент со следующей единицы.
public void Advance(int nextUnitIndex) => NextUnitIndex = Math.Max(0, nextUnitIndex);
/// Перейти к другому элементу, начав его с указанной единицы.
public void MoveTo(GroupElementKind kind, Guid elementId, int nextUnitIndex = 0)
{
CurrentElementKind = kind;
CurrentElementId = elementId;
NextUnitIndex = Math.Max(0, nextUnitIndex);
}
/// Забыть текущий элемент — например, когда он исчез из группы.
public void Reset()
{
CurrentElementKind = null;
CurrentElementId = null;
NextUnitIndex = 0;
}
}