73 lines
3.2 KiB
C#
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;
|
|
}
|
|
}
|
|
}
|