Files
TeleWave/backend/src/TeleWave.Application/Programming/Templates/SlotStrategy.cs
T

73 lines
3.2 KiB
C#

using System.Text.Json;
using System.Text.Json.Serialization;
namespace TeleWave.Application.Programming.Templates;
/// <summary>Как слот выбирает элемент группы.</summary>
public enum SlotStrategyType
{
/// <summary>Элементы группы по порядку позиций.</summary>
Sequential = 0,
/// <summary>Случайный элемент, не показанный последние N дней.</summary>
RandomWithCooldown = 1,
/// <summary>Всегда один и тот же элемент.</summary>
Fixed = 2,
}
/// <summary>Что делать, когда остывание отсекло всех кандидатов.</summary>
public enum CooldownFallback
{
/// <summary>Взять элемент, не игравший дольше всех.</summary>
OldestFirst = 0,
/// <summary>Проигнорировать остывание на этот выход.</summary>
IgnoreCooldown = 1,
}
/// <summary>
/// Стратегия выбора элемента внутри слота. Отвечает только за выбор элемента: единицы внутри элемента
/// всегда идут по порядку от курсора — сериал не должен прыгать по сериям.
///
/// Размер блока живёт на слоте отдельно и ортогонален стратегии: любую можно скомбинировать
/// с «одна единица», «четыре подряд» или «пока не наберётся два часа».
/// </summary>
public sealed record SlotStrategy(
SlotStrategyType Type = SlotStrategyType.Sequential,
/// <summary>Начинать группу заново, дойдя до конца (иначе слот останавливается).</summary>
bool RestartOnEnd = true,
/// <summary>Дней остывания для <see cref="SlotStrategyType.RandomWithCooldown"/>.</summary>
int CooldownDays = 0,
CooldownFallback Fallback = CooldownFallback.OldestFirst,
/// <summary>Закреплённый элемент для <see cref="SlotStrategyType.Fixed"/>.</summary>
Guid? FixedElementId = null
)
{
private static readonly JsonSerializerOptions Options = new()
{
PropertyNamingPolicy = JsonNamingPolicy.CamelCase,
DefaultIgnoreCondition = JsonIgnoreCondition.WhenWritingNull,
Converters = { new JsonStringEnumConverter() },
};
public string ToJson() => JsonSerializer.Serialize(this, Options);
/// <summary>Разбирает сохранённую стратегию. Повреждённый JSON — как отсутствие стратегии:
/// слот получит поведение по умолчанию, а не уронит генерацию всего канала.</summary>
public static SlotStrategy? FromJson(string? json)
{
if (string.IsNullOrWhiteSpace(json))
return null;
try
{
return JsonSerializer.Deserialize<SlotStrategy>(json, Options);
}
catch (JsonException)
{
return null;
}
}
}