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; } }