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() { _configsHandle = Addressables.LoadAssetsAsync(_label); await _configsHandle.ToUniTask(); foreach (AudioInfoConfig 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}"); if (_clipsHandles[groupName].Count == 0) return; foreach (var handle in _clipsHandles[groupName]) Addressables.Release(handle.Value); _clipsHandles[groupName].Clear(); _eventBus.RaiseEvent(x=> x.AudioClipsUnLoaded(groupName)); } public void Dispose() { foreach (var handles in _clipsHandles) { foreach (var handle in handles.Value) { handle.Value.Release(); } } _clipsHandles.Clear(); _configsHandle.Release(); } } internal interface IAudioConfigsLoadedHandle : IGlobalSubscriber { void AudioConfigsLoaded(); } internal interface IAudioClipsEventHandle : IGlobalSubscriber { void AudioClipsLoaded(AudioNames groupName, Dictionary toDictionary); void AudioClipsUnLoaded(AudioNames groupName); public void ApplyParameter(string effectName, float value, float time, Action callback = null); } }