Danro-Jump/Assets/Scripts/Runtime/Settings/Installers/ServiceSettingsInstaller.cs
Danil Iarosh d39d160d92 Implement physical prize dispensing, service stats, and QR screen timeout
- Добавлен асинхронный процесс аппаратной выдачи физических призов (хоппер и витрина) в GameplayHudController.
- Реализована блокировка выдачи по 10-секундному таймауту датчика хоппера с гарантированной отправкой команды отключения двигателя '300'.
- Реализован автоматический таймаут неактивности на экране QR-кода с последующим переходом в главное меню.
- Расширен сервис статистики PrizeSessionStateService новыми долгосрочными счетчиками (сыгранные игры, очки, монеты, сбои связи COM, физ. выдачи и ошибки).
- Обновлен построитель сводки статистики в меню настроек для отображения новых счетчиков и списка последних 5 сессий.
- Написаны EditMode тесты для проверки инкремента счетчиков и запуска выдачи призов.
2026-06-23 10:36:13 +03:00

66 lines
3.1 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 UnityEngine;
using Zenject;
using DanroJump.Audio;
using DanroJump.Prizes;
using DanroJump.SceneFlow;
namespace DanroJump.Settings
{
/// <summary>
/// ProjectContext/SceneContext installer сервисных настроек.
/// </summary>
public sealed class ServiceSettingsInstaller : MonoInstaller
{
[SerializeField] private string databaseAddress = ServiceSettingsAddressKeys.Database;
[SerializeField] private ServiceSettingsDatabase fallbackDatabase;
[SerializeField] private GameAudioSettings audioSettings;
[SerializeField] private string fileName = "service-settings.json";
[SerializeField] private string prizeSessionStateFileName = "prize-session-state.json";
[SerializeField] private bool loadImmediately = true;
[SerializeField] private bool bindActionsInScene = true;
/// <summary>
/// Загружает базу настроек, создает сервис и регистрирует его в DI-контейнере.
/// </summary>
public override void InstallBindings()
{
var databaseProvider = new AddressableServiceSettingsDatabaseProvider(databaseAddress, fallbackDatabase);
var database = databaseProvider.Load();
if (database == null)
{
Debug.LogError($"{nameof(ServiceSettingsInstaller)} could not load {nameof(ServiceSettingsDatabase)}.", this);
databaseProvider.Dispose();
Container.BindInterfacesAndSelfTo<SceneFlowService>().AsSingle();
return;
}
var repository = new JsonServiceSettingsRepository(fileName);
var prizeSessionRepository = new JsonPrizeSessionStateRepository(prizeSessionStateFileName);
var service = new ServiceSettingsService(database, repository);
if (loadImmediately)
{
service.Load();
}
Container.BindInstance(database).AsSingle();
Container.Bind<IServiceSettingsDatabaseProvider>().FromInstance(databaseProvider).AsSingle();
Container.Bind<System.IDisposable>().FromInstance(databaseProvider).AsSingle();
Container.Bind<IServiceSettingsRepository>().FromInstance(repository).AsSingle();
Container.Bind<IReadOnlyServiceSettings>().FromInstance(service).AsSingle();
Container.Bind<IServiceSettingsService>().FromInstance(service).AsSingle();
Container.Bind<IPrizeSessionStateRepository>().FromInstance(prizeSessionRepository).AsSingle();
Container.BindInterfacesAndSelfTo<PrizeSessionStateService>().AsSingle();
Container.BindInterfacesAndSelfTo<SceneFlowService>().AsSingle();
if (audioSettings != null)
{
Container.BindInstance(audioSettings).AsSingle();
}
Container.BindInterfacesAndSelfTo<GameAudioService>().AsSingle().NonLazy();
Container.BindInterfacesTo<ServiceSettingsSceneInjector>().AsSingle().WithArguments(bindActionsInScene).NonLazy();
}
}
}