using System; using System.Collections.Generic; using System.Linq; using System.Threading.Tasks; namespace DDD { public class UiManager : Singleton, IManager, IEventHandler, IEventHandler { private readonly Dictionary _popupUIs = new(); private readonly Stack _popupStack = new(); private InputActionMaps _previousActionMap = InputActionMaps.None; private readonly object _uiPauseRequester = new(); public void PreInit() { EventBus.Register(this); EventBus.Register(this); } public Task Init() { return Task.CompletedTask; } public void PostInit() { } private void OnDestroy() { EventBus.Unregister(this); EventBus.Unregister(this); } public void RegisterPopupUI(BasePopupUi ui) { var type = ui.GetType(); _popupUIs.TryAdd(type, ui); } public void UnregisterPopupUI(BasePopupUi ui) { var type = ui.GetType(); if (_popupUIs.TryGetValue(type, out var registered) && registered == ui) { _popupUIs.Remove(type); } } public void Invoke(OpenPopupUiEvent evt) { if (_popupUIs.TryGetValue(evt.UiType, out var popup)) { if (!popup.IsOpen) { PushPopup(popup); popup.Open(); if (popup.IsBlockingTime) { var timeScaleChangeEvent = GameEvents.RequestTimeScaleChangeEvent; timeScaleChangeEvent.Requester = popup; timeScaleChangeEvent.NewTimeScale = 0f; EventBus.Broadcast(timeScaleChangeEvent); } } } } public void Invoke(ClosePopupUiEvent evt) { if (_popupUIs.TryGetValue(evt.UiType, out var popup)) { if (popup.IsOpen) { popup.Close(); PopPopup(popup); if (popup.IsBlockingTime) { var timeScaleChangeEvent = GameEvents.RequestTimeScaleChangeEvent; timeScaleChangeEvent.Requester = popup; timeScaleChangeEvent.NewTimeScale = 1f; EventBus.Broadcast(timeScaleChangeEvent); } } } } public bool IsTopPopup(BasePopupUi popup) { return _popupStack.Count > 0 && _popupStack.Peek() == popup; } public void PushPopup(BasePopupUi popup) { if (_popupStack.Contains(popup)) return; if (_popupStack.Count == 0) { _previousActionMap = InputManager.Instance.GetCurrentActionMap(); } _popupStack.Push(popup); } public void PopPopup(BasePopupUi popup) { if (_popupStack.Count == 0) return; if (_popupStack.Peek() == popup) { _popupStack.Pop(); } else { var temp = _popupStack.Reverse().Where(p => p != popup).Reverse().ToList(); _popupStack.Clear(); foreach (var p in temp) { _popupStack.Push(p); } } if (_popupStack.TryPeek(out var topPopup) && topPopup.IsOpen) { InputManager.Instance.SwitchCurrentActionMap(topPopup.InputActionMaps); } else { InputManager.Instance.SwitchCurrentActionMap(_previousActionMap); } } } }