using System; using Cysharp.Threading.Tasks; using UnityEngine; namespace DanieleMarotta.RiversongCodeShowcase { public class BuildingStorageVisualizationSystem : GameSystem, IInitializable, IDisposable, IUpdatable { private const int StackProductCount = 10; [InjectService] private IEntityCache _entityCache; [InjectService] private IPoolingService _poolingService; [InjectService] private IProductCatalog _productCatalog; [InjectService] private IBuildingVisualizationCollection _buildingVisualizations; [InjectService] private ISignalBus _signalBus; public BuildingStorageVisualizationSystem(IServiceLocator serviceLocator) : base(serviceLocator) { } public UniTask InitializeAsync() { _signalBus.Subscribe(OnBuildingDeleted); return UniTask.CompletedTask; } public void Dispose() { _signalBus.Unsubscribe(OnBuildingDeleted); } public void Update() { foreach (var storehouse in _entityCache.GetStorageBuildings()) UpdateStorehouse(storehouse); } private void UpdateStorehouse(Building storehouse) { if (!_buildingVisualizations.TryGetVisualization(storehouse.Id, out var buildingVisualization)) return; var storageVisualization = buildingVisualization.GetComponent(); if (storageVisualization.SlotCount <= 0) return; ReleaseProductVisualizations(storageVisualization); ref var storage = ref storehouse.GetStorageRW(); var slotIndex = 0; foreach (var (productHandle, amount) in storage) { var product = _productCatalog.GetProduct(productHandle); var poolKey = ((GameObject)product.ProductStackVisualization.Asset).GetInstanceID(); var amountLeft = amount; while (amountLeft > 0) { var productVisualization = _poolingService.Get(poolKey); storageVisualization.SetProductVisualization(slotIndex, productVisualization); if (++slotIndex >= storageVisualization.SlotCount) return; amountLeft -= StackProductCount; } } } private void OnBuildingDeleted(BuildingDeletedSignal signal) { if (!signal.Building.Definition.IsStorage) return; _buildingVisualizations.TryGetVisualization(signal.Building.Id, out var buildingVisualization); var storageVisualization = buildingVisualization.GetComponent(); ReleaseProductVisualizations(storageVisualization); } private void ReleaseProductVisualizations(BuildingStorageVisualization storageVisualization) { for (var i = 0; i < storageVisualization.SlotCount; i++) { if (!storageVisualization.TryGetProductVisualization(i, out var productVisualization)) return; _poolingService.Release(productVisualization); } } } }