Files
riversong-code-showcase/Source/Riversong/Game/CommonServices/Analytics/DemoAnalyticsSystem.cs
2026-05-21 16:04:49 +02:00

89 lines
3.3 KiB
C#

using System;
using Cysharp.Threading.Tasks;
using UnityEngine;
namespace DanieleMarotta.RiversongCodeShowcase
{
[GameSystemGroup(typeof(CommonServicesSystemGroup))]
[InitializeAfter(typeof(AnalyticsInitializationSystem))]
public class DemoAnalyticsSystem : GameSystem, IInitializable, IDisposable, IUpdatable
{
private const float HeartbeatIntervalSeconds = 300;
[InjectService]
private IAnalyticsService _analyticsService;
[InjectService]
private ISignalBus _signalBus;
[InjectService]
private World _world;
private AnalyticsSessionState _sessionState = new();
public DemoAnalyticsSystem(IServiceLocator serviceLocator) : base(serviceLocator)
{
}
public UniTask InitializeAsync()
{
_signalBus.Subscribe<WorldReadySignal>(OnWorldReady);
_signalBus.Subscribe<BuildingCreatedSignal>(OnBuildingCreated);
_signalBus.Subscribe<BuildingUpgradedSignal>(OnBuildingUpgraded);
_signalBus.Subscribe<DemoCompletedSignal>(OnDemoCompleted);
return UniTask.CompletedTask;
}
public void Dispose()
{
_signalBus.Unsubscribe<WorldReadySignal>(OnWorldReady);
_signalBus.Unsubscribe<BuildingCreatedSignal>(OnBuildingCreated);
_signalBus.Unsubscribe<BuildingUpgradedSignal>(OnBuildingUpgraded);
_signalBus.Unsubscribe<DemoCompletedSignal>(OnDemoCompleted);
}
public void Update()
{
var realtimeSeconds = Time.realtimeSinceStartup;
while (_sessionState.TryAdvanceHeartbeat(realtimeSeconds, HeartbeatIntervalSeconds, out var heartbeatIndex, out var playtimeSeconds))
_analyticsService.RecordHeartbeat(_sessionState.SessionId, heartbeatIndex, playtimeSeconds, _sessionState.TotalBuildingsPlaced, _world.PopulationState.Population);
}
private void OnWorldReady(WorldReadySignal signal)
{
_sessionState.Begin(Time.realtimeSinceStartup);
_analyticsService.RecordSessionStarted(_sessionState.SessionId);
}
private void OnBuildingCreated(BuildingCreatedSignal signal)
{
var definition = signal.Building?.Definition;
if (!_sessionState.TryRecordBuildingConstruction(definition)) return;
_analyticsService.RecordBuildingConstructionCompleted(_sessionState.SessionId, definition.name);
}
private void OnBuildingUpgraded(BuildingUpgradedSignal signal)
{
var building = signal.Building;
if (!_sessionState.CanRecordHouseUpgrade(building)) return;
_analyticsService.RecordHouseUpgraded(_sessionState.SessionId, building.Definition.name, building.TierIndex, building.TierIndex + 1);
}
private void OnDemoCompleted(DemoCompletedSignal signal)
{
if (!_sessionState.TryMarkDemoCompleted()) return;
var playtimeSeconds = _sessionState.GetPlaytimeSeconds(Time.realtimeSinceStartup);
_analyticsService.RecordDemoCompleted(
_sessionState.SessionId,
playtimeSeconds,
_world.TimeState.TotalWeeks,
_world.PopulationState.Population,
_world.PopulationState.Happiness);
}
}
}