- Добавлен 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
94 lines
3.5 KiB
C#
94 lines
3.5 KiB
C#
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;
|
||
}
|
||
}
|
||
}
|