Danil Iarosh 32cfa79578 refactor: Refactor work with COM to ComSystemManager
- Добавлен ComSystemManager как новый публичный компонент COM-системы для поэтапной замены ComWrapper
- Реализовано получение роли контроллера только после успешного handshake в ComDeviceClient
- Добавлено публичное поле ControllerRole в ComDeviceClient
- Добавлен запрос роли по команде 97 и разбор ответа формата ROLE : <value> (с пробелами)
- В ComMultiManager добавлена логика выбора DefaultDeviceId по роли main_controller
- Добавлен доступ к роли устройства через GetDeviceRole(deviceId) в менеджере и фасаде
- В ComWrapper добавлены настройки роли: roleRequestCommand, roleResponsePrefix, roleRequestTimeoutMs, mainControllerRole
- Дефолтная команда запроса роли изменена на 97
- Выполнена кодовая миграция зависимостей с ComWrapper на ComSystemManager в GameManager, GlobalsManager, PaymentManager, BalanceManager, InactivityManager, COMInput, LightController, PrizeSystem
- В GlobalsManager исправлена инициализация ссылки после AddComponent<ComSystemManager>(), чтобы исключить NullReference
2026-02-20 14:59:16 +03:00

94 lines
3.5 KiB
C#
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
namespace RR.Common.Controls
{
/// <summary>
/// Строитель последовательности световых эффектов.
/// Создаётся через <see cref="LightController.SetLight(LightMode,int)"/>.
/// <example><code>
/// SetLight(LightMode.VerticalWave, 3).Then(LightMode.DiagonalWave, 3).Loop();
/// SetLight(LightMode.VerticalWave, 3).Then(LightMode.Off);
/// SetLight(LightMode.Rainbow, 5);
/// </code></example>
/// </summary>
public class LightSequence
{
private readonly struct Step
{
public readonly LightMode Mode;
public readonly int DurationSeconds;
public Step(LightMode mode, int durationSeconds) { Mode = mode; DurationSeconds = durationSeconds; }
}
private readonly List<Step> _steps = new();
private readonly LightController _controller;
private bool _looping;
private Coroutine _coroutine;
internal LightSequence(LightController controller, LightMode firstMode, int firstDuration)
{
_controller = controller;
_steps.Add(new Step(firstMode, firstDuration));
}
/// <summary>Добавляет следующий эффект с временем по умолчанию.</summary>
public LightSequence Then(LightMode mode) => Then(mode, _controller.DefaultDuration);
/// <summary>Добавляет следующий эффект с указанным временем.</summary>
public LightSequence Then(LightMode mode, int durationSeconds)
{
_steps.Add(new Step(mode, durationSeconds));
return this;
}
/// <summary>
/// Зацикливает последовательность. Для остановки — <see cref="LightController.StopSequence"/>.
/// </summary>
public LightSequence Loop()
{
_looping = true;
Play();
return this;
}
/// <summary>Запускает последовательность один раз.</summary>
public LightSequence Play()
{
Stop();
_coroutine = _controller.StartCoroutine(RunSequence());
return this;
}
/// <summary>Останавливает выполнение последовательности.</summary>
public void Stop()
{
if (_coroutine == null) return;
_controller.StopCoroutine(_coroutine);
_coroutine = null;
}
/// <summary>Возвращает <c>true</c>, если последовательность сейчас выполняется.</summary>
public bool IsPlaying => _coroutine != null;
// ReSharper disable once IteratorNeverReturns — цикл намеренно бесконечный при _looping=true
private IEnumerator RunSequence()
{
do
{
foreach (Step step in _steps)
{
_controller.SendCommand(step.Mode, step.DurationSeconds);
if (step.Mode != LightMode.Off && step.DurationSeconds > 0)
yield return new WaitForSeconds(step.DurationSeconds);
}
}
while (_looping);
_coroutine = null;
}
}
}