129 lines
4.6 KiB
C#
129 lines
4.6 KiB
C#
using System;
|
|
using System.Collections.Generic;
|
|
using System.Linq;
|
|
using System.Threading;
|
|
using Code.Infrastructure.Configs;
|
|
using Code.Infrastructure.EventBus;
|
|
using Cysharp.Threading.Tasks;
|
|
using UnityEngine;
|
|
using UnityEngine.AddressableAssets;
|
|
using UnityEngine.Audio;
|
|
using UnityEngine.Pool;
|
|
using UnityEngine.ResourceManagement.AsyncOperations;
|
|
using Object = UnityEngine.Object;
|
|
|
|
namespace Code.Infrastructure.Audio
|
|
{
|
|
public interface IAudioSourcePool
|
|
{
|
|
AudioSource GetSource(AudioSourceType sourceType);
|
|
void ReleaseSource(AudioSource source);
|
|
}
|
|
|
|
public class AudioSourcePool : IAudioSourcePool, IDisposable
|
|
{
|
|
// The pool holds plain GameObjects (you can swap this for any component type).
|
|
private IObjectPool<AudioSource> _pool;
|
|
private GameObject _sourcePrefab;
|
|
|
|
private Dictionary<AudioSourceType, AudioSourceSettingsConfig> _settings;
|
|
|
|
public AudioSourcePool(Dictionary<AudioSourceType, AudioSourceSettingsConfig> settings) => _settings = settings;
|
|
|
|
private string _configsLabel;
|
|
private AsyncOperationHandle<IList<AudioSourceSettingsConfig>> _handles;
|
|
private AssetReference _sourcePrefabConfigReference;
|
|
private AsyncOperationHandle<AudioSourcePrefabConfig> _prefabConfigHandle;
|
|
private AsyncOperationHandle<GameObject> _prefabHandle;
|
|
private EventBus.EventBus _eventBus;
|
|
|
|
public AudioSourcePool(IConfigLocator configLocator, EventBus.EventBus eventBus)
|
|
{
|
|
_eventBus = eventBus;
|
|
|
|
_configsLabel = configLocator.TryGetManyConfigAssetReferences<AudioSourceSettingsConfig>();
|
|
_sourcePrefabConfigReference = configLocator.TryGetConfigAssetReference<AudioSourcePrefabConfig>();
|
|
|
|
LoadConfigs().Forget();
|
|
}
|
|
|
|
private async UniTaskVoid LoadConfigs()
|
|
{
|
|
_prefabConfigHandle = Addressables.LoadAssetAsync<AudioSourcePrefabConfig>(_sourcePrefabConfigReference);
|
|
_handles = Addressables.LoadAssetsAsync<AudioSourceSettingsConfig>(_configsLabel);
|
|
|
|
await UniTask.WhenAll(
|
|
_prefabConfigHandle.ToUniTask(),
|
|
_handles.ToUniTask());
|
|
|
|
_prefabHandle = Addressables.LoadAssetAsync<GameObject>(_prefabConfigHandle.Result.sourcePrefab);
|
|
|
|
_settings = _handles.Result.ToDictionary(x => x.sourceType);
|
|
|
|
await _prefabHandle.ToUniTask();
|
|
|
|
_pool = new ObjectPool<AudioSource>(
|
|
createFunc: CreateItem,
|
|
// actionOnGet: OnGet,
|
|
actionOnRelease: OnRelease,
|
|
actionOnDestroy: OnDestroyItem,
|
|
collectionCheck: true, // helps catch double-release mistakes
|
|
defaultCapacity: 10,
|
|
maxSize: 20
|
|
);
|
|
|
|
_eventBus.RaiseEvent<IAudioSourcePoolInitializedHandle>(x => x.AudioSourcePoolInitialized());
|
|
}
|
|
// Creates a new pooled GameObject the first time (and whenever the pool needs more).
|
|
private AudioSource CreateItem()
|
|
{
|
|
var audioSource = Object.Instantiate(_prefabHandle.Result).GetComponent<AudioSource>();
|
|
audioSource.name = "PooledAudioSource";
|
|
Object.DontDestroyOnLoad(audioSource);
|
|
return audioSource;
|
|
}
|
|
|
|
// Called when an item is taken from the pool.
|
|
private void OnGet(AudioSource source)
|
|
{
|
|
//source.gameObject.SetActive(true);
|
|
}
|
|
|
|
// Called when an item is returned to the pool.
|
|
private void OnRelease(AudioSource source)
|
|
{
|
|
source.Stop();
|
|
source.resource = null;
|
|
//source.gameObject.SetActive(false);
|
|
}
|
|
|
|
// Called when the pool decides to destroy an item (e.g., above max size).
|
|
private void OnDestroyItem(AudioSource source)
|
|
{
|
|
Object.Destroy(source.gameObject);
|
|
}
|
|
|
|
public AudioSource GetSource(AudioSourceType sourceType)
|
|
{
|
|
var source = _pool.Get();
|
|
|
|
source.spatialBlend = _settings[sourceType].spatialBlend;
|
|
|
|
return source;
|
|
}
|
|
|
|
public void ReleaseSource(AudioSource source) => _pool.Release(source);
|
|
|
|
public void Dispose()
|
|
{
|
|
Addressables.Release(_handles);
|
|
Addressables.Release(_prefabConfigHandle);
|
|
Addressables.Release(_sourcePrefab);
|
|
}
|
|
}
|
|
|
|
public interface IAudioSourcePoolInitializedHandle : IGlobalSubscriber
|
|
{
|
|
void AudioSourcePoolInitialized();
|
|
}
|
|
} |