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.UI { public interface IUIFactory { UniTaskVoid LoadPanel(UIPanelType panelType, Transform parent = null); void ReleasePanel(UIPanel panel); Canvas Canvas { get; } bool CheckIsMultiple(UIPanelType panelType); } public class UIFactory : IDisposable, IUIFactory { private Dictionary _configs; public bool CheckIsMultiple(UIPanelType panelType) => _configs[panelType].Multiple; private AssetReference _canvasConfigReference; private string _configsLabel; private EventBus.EventBus _eventBus; private AsyncOperationHandle> _configsHandle; private AsyncOperationHandle _canvasSettingsHandle; private CanvasSettingsConfig _canvasConfig; private GameObject _canvas; public Canvas Canvas { get; private set; } public UIFactory(IConfigLocator configLocator, EventBus.EventBus eventBus) { _eventBus = eventBus; _configsLabel = configLocator.TryGetManyConfigAssetReferences(); _canvasConfigReference = configLocator.TryGetConfigAssetReference(); LoadConfigs().Forget(); } public async UniTaskVoid LoadPanel(UIPanelType panelType, Transform parent = null) { var panel = (await Addressables.InstantiateAsync(_configs[panelType].Prefab, parent ?? _canvas.transform).ToUniTask()) .GetComponent(); UnityEngine.Debug.LogWarning($"Panel loaded {panelType}"); _eventBus.RaiseEvent(ui => ui.UIPanelLoaded(panel, panelType)); } public void ReleasePanel(UIPanel panel) { Debug.LogWarning($"Panel released {panel.gameObject.name}"); Addressables.ReleaseInstance(panel.gameObject); } private async UniTaskVoid LoadConfigs() { _configsHandle = Addressables.LoadAssetsAsync(_configsLabel); _canvasSettingsHandle = Addressables.LoadAssetAsync(_canvasConfigReference); await _configsHandle.ToUniTask(); await _canvasSettingsHandle.ToUniTask(); _canvasConfig = _canvasSettingsHandle.Result; _configs = _configsHandle.Result.ToDictionary(c => c.UIPanelType); _canvas = await Addressables.InstantiateAsync(_canvasConfig.Prefab).ToUniTask(); UnityEngine.Object.DontDestroyOnLoad(_canvas); Canvas = _canvas.GetComponent(); _eventBus.RaiseEvent(ui => ui.UIInitialized()); } public void Dispose() { Addressables.Release(_configsHandle); Addressables.Release(_canvasSettingsHandle); Addressables.ReleaseInstance(_canvas); } } public interface IUIInitializedHandle : IGlobalSubscriber { void UIInitialized(); } public interface IUIPanelLoadedHandle : IGlobalSubscriber { void UIPanelLoaded(UIPanel panel, UIPanelType panelType); List TryGetMultiplePanels(UIPanelType panelType); } }