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; namespace Code.Infrastructure.Audio { public interface IAudioFactory { UniTaskVoid LoadAudioClips(AudioNames groupName); void ReleaseAudios(AudioNames groupName); } public class AudioFactory : IAudioFactory, IDisposable { private string _label; private Dictionary> _audioInfos = new(); private Dictionary>> _clipsHandles = new(); private AsyncOperationHandle> _configsHandle; private EventBus.EventBus _eventBus; public AudioFactory(IConfigLocator configLocator, EventBus.EventBus eventBus) { _eventBus = eventBus; _label = configLocator.TryGetManyConfigAssetReferences(); for (var i = 0; i < typeof(AudioNames).GetEnumValues().Length; i++) { _audioInfos.Add((AudioNames)i, new Dictionary()); _clipsHandles.Add((AudioNames)i, new Dictionary>()); } LoadConfigs().Forget(); } private async UniTaskVoid LoadConfigs() { if ((await Addressables.LoadResourceLocationsAsync(_label).Task).Count != 0) { _configsHandle = Addressables.LoadAssetsAsync(_label); await _configsHandle.ToUniTask(); foreach (var config in _configsHandle.Result) _audioInfos[config.GroupName].Add(config.id, config.fileReference); } _eventBus.RaiseEvent(ui => ui.AudioConfigsLoaded()); } public async UniTaskVoid LoadAudioClips(AudioNames groupName) { UnityEngine.Debug.LogWarning($"Audios loaded {groupName}"); foreach (var audioInfo in _audioInfos[groupName]) if (!_clipsHandles[groupName].ContainsKey(audioInfo.Key)) _clipsHandles[groupName] .Add(audioInfo.Key, Addressables.LoadAssetAsync(audioInfo.Value)); else _clipsHandles[groupName][audioInfo.Key] = Addressables.LoadAssetAsync(audioInfo.Value); foreach (var handle in _clipsHandles[groupName]) await handle.Value.ToUniTask(); _eventBus.RaiseEvent(ui => ui.AudioClipsLoaded(groupName, _clipsHandles[groupName].ToDictionary( x => x.Key, x => x.Value.Result))); } public void ReleaseAudios(AudioNames groupName) { UnityEngine.Debug.LogWarning($"Audios unloaded {groupName}"); _eventBus.RaiseEvent(x => x.AudioClipsUnLoaded(groupName)); foreach (var handle in _clipsHandles) Addressables.Release(handle.Value); } public void Dispose() { foreach (var handles in _clipsHandles) { foreach (var handle in handles.Value) { handle.Value.Release(); } } if (_configsHandle.IsValid()) _configsHandle.Release(); } } internal interface IAudioConfigsLoadedHandle : IGlobalSubscriber { void AudioConfigsLoaded(); } internal interface IAudioClipsEventHandle : IGlobalSubscriber { void AudioClipsLoaded(AudioNames groupName, Dictionary toDictionary); void AudioClipsUnLoaded(AudioNames groupName); } }