using System; using System.Collections.Generic; using System.Linq; using Code.Infrastructure.Configs; using Code.Infrastructure.EventBus; using Cysharp.Threading.Tasks; using UnityEngine; using UnityEngine.AddressableAssets; using UnityEngine.ResourceManagement.AsyncOperations; using EventBus = Code.Infrastructure.EventBus.EventBus; namespace Code.Example.Race.Racer { public interface IRacerFactory { RacerSettingsConfig GetConfig(RacerType racerType); UniTaskVoid LoadRacer(RacerType racerType); void ReleaseRacer(RacerType racerType); } public class RacerFactory : IDisposable, IRacerFactory { private Dictionary _racerConfigs; private Dictionary> _racerPrefabsHandle = new(); private string _racerConfigsLabel; private AsyncOperationHandle> _racerConfigsHandle; private EventBus _eventBus; public RacerFactory(IConfigLocator configLocator, EventBus eventBus) { _eventBus = eventBus; _racerConfigsLabel = configLocator.TryGetManyConfigAssetReferences(); LoadConfigs().Forget(); } private async UniTaskVoid LoadConfigs() { _racerConfigsHandle = Addressables.LoadAssetsAsync(_racerConfigsLabel); await _racerConfigsHandle.ToUniTask(); _racerConfigs = _racerConfigsHandle.Result.ToDictionary(x => x.racerData.type); _eventBus.RaiseEvent(x => x.RacerFactoryInitialized()); } public RacerSettingsConfig GetConfig(RacerType racerType) => _racerConfigs[racerType]; public async UniTaskVoid LoadRacer(RacerType racerType) { if (_racerPrefabsHandle.ContainsKey(racerType)) { _eventBus.RaiseEvent(x => x.RacerLoaded(racerType, null)); return; } UnityEngine.Debug.LogWarning($"Racer loaded {racerType}"); _racerPrefabsHandle.Add(racerType, Addressables.LoadAssetAsync(_racerConfigs[racerType].prefabReference)); await _racerPrefabsHandle[racerType].ToUniTask(); var racer = _racerPrefabsHandle[racerType].Result.GetComponent(); racer.SetData(_racerConfigs[racerType].racerData); _eventBus.RaiseEvent(x => x.RacerLoaded(racerType, racer)); } public void ReleaseRacer(RacerType racerType) { _racerPrefabsHandle[racerType].Release(); _racerPrefabsHandle.Remove(racerType); } public void Dispose() { UnityEngine.Debug.LogWarning($"Racers released"); foreach (var prefab in _racerPrefabsHandle) prefab.Value.Release(); _racerPrefabsHandle.Clear(); _racerConfigsHandle.Release(); } } public interface IRacerFactoryInitializedHandle : IGlobalSubscriber { public void RacerFactoryInitialized(); } public interface IRacerLoadedHandle : IGlobalSubscriber { public void RacerLoaded(RacerType type, Racer racer); } }