using System; using System.Collections.Generic; using System.Linq; using Code.Infrastructure.EventBus; using Reflex.Core; using Reflex.Extensions; using Reflex.Injectors; using UnityEngine; using UnityEngine.SceneManagement; namespace Code.Infrastructure.UI { public interface IUIService { void OpenPanel(UIPanelType uiPanelType); void ClosePanel(UIPanelType uiPanelType); void TryLoadCreatePanel(UIPanelType uiPanelType, Transform parent = null); void TryRemovePanel(UIPanelType uiPanelType); void SetCanvasCamera(UnityEngine.Camera camera); UIPanel TryGetSinglePanel(UIPanelType panelType); void TryRemovePanel(UIPanel panel, Action callback = null); } public class UIService : IUIPanelLoadedHandle, IUIService { private Dictionary _loadedSinglePanels = new(); private Dictionary> _loadedMultiplePanels = new(); private EventBus.EventBus _eventBus; private IUIFactory _factory; public UIService(EventBus.EventBus eventBus, IUIFactory factory) { _eventBus = eventBus; _factory = factory; eventBus.Subscribe(this); } public void SetCanvasCamera(Camera camera) { _factory.Canvas.worldCamera = camera; _factory.Canvas.planeDistance = 0.3f; } public void OpenPanel(UIPanelType uiPanelType) { _loadedSinglePanels[uiPanelType].gameObject.SetActive(true); _loadedSinglePanels[uiPanelType].Open(); } // TODO Close event public void ClosePanel(UIPanelType uiPanelType) { _loadedSinglePanels[uiPanelType].Close(() => { _loadedSinglePanels[uiPanelType].gameObject.SetActive(false); }); } public void TryLoadCreatePanel(UIPanelType uiPanelType, Transform parent = null) => _factory.LoadPanel(uiPanelType, parent); public void UIPanelLoaded(UIPanel panel, UIPanelType panelType) { if (!_factory.CheckIsMultiple(panelType)) _loadedSinglePanels.Add(panelType, panel); else { if (!_loadedMultiplePanels.ContainsKey(panelType)) _loadedMultiplePanels.Add(panelType, new List()); _loadedMultiplePanels[panelType].Add(panel); } if (panel.InjectMeSenpai) GameObjectInjector.InjectRecursive(panel.gameObject, Container.RootContainer); // GameObjectInjector.InjectRecursive(panel.gameObject, SceneManager.GetActiveScene().GetSceneContainer()); // Скорее всего будут нужны компоненты текущей сцены if (!_factory.CheckIsMultiple(panelType)) _eventBus.RaiseEvent(ui => ui.UISinglePanelLoaded(panelType)); else _eventBus.RaiseEvent(ui => ui.UIMultiplePanelLoaded(panelType, panel)); } public void TryRemovePanel(UIPanelType uiPanelType) { _loadedSinglePanels[uiPanelType].Close(() => { _loadedSinglePanels[uiPanelType].gameObject.SetActive(false); RemovePanel(uiPanelType); }); } public void TryRemovePanel(UIPanel panel, Action callback = null) { panel.Close(() => { panel.gameObject.SetActive(false); RemovePanel(panel); callback?.Invoke(); }); } private void RemovePanel(UIPanelType panelType) { if (!_factory.CheckIsMultiple(panelType)) { _factory.ReleasePanel(_loadedSinglePanels[panelType]); _loadedSinglePanels.Remove(panelType); } else { foreach (var panel in _loadedMultiplePanels[panelType]) _factory.ReleasePanel(panel); _loadedMultiplePanels.Remove(panelType); } } private void RemovePanel(UIPanel panel) { _factory.ReleasePanel(panel); } public UIPanel TryGetSinglePanel(UIPanelType panelType) => _loadedSinglePanels.GetValueOrDefault(panelType); public List TryGetMultiplePanels(UIPanelType panelType) => _loadedMultiplePanels.GetValueOrDefault(panelType); } public interface IUIPanelLoaded : IGlobalSubscriber { void UISinglePanelLoaded(UIPanelType uiPanelType); void UIMultiplePanelLoaded(UIPanelType uiPanelType, UIPanel panel); } }