ProjectDDD/Assets/_DDD/_Scripts/GameUi/BaseUi/PopupUis/PopupUiState.cs
2025-08-21 16:44:47 +09:00

186 lines
5.5 KiB
C#

using System;
using System.Collections.Generic;
using System.Linq;
using Sirenix.OdinInspector;
using UnityEngine;
namespace DDD
{
public class UiState : SerializedScriptableObject, IEventHandler<OpenPopupUiEvent>, IEventHandler<ClosePopupUiEvent>
{
private readonly Dictionary<Type, BaseUi> _uis = new();
private readonly Dictionary<Type, BasePopupUi> _popupUis = new();
private readonly Stack<BasePopupUi> _popupUiStack = new();
private InputActionMaps _previousActionMap = InputActionMaps.None;
private UiData _uiData => GameData.Instance.UiData;
public void OnEnable()
{
EventBus.Register<OpenPopupUiEvent>(this);
EventBus.Register<ClosePopupUiEvent>(this);
_uis.Clear();
_popupUis.Clear();
_popupUiStack.Clear();
}
private void OnDisable()
{
EventBus.Unregister<OpenPopupUiEvent>(this);
EventBus.Unregister<ClosePopupUiEvent>(this);
}
public void RegisterUI(BaseUi ui)
{
var type = ui.GetType();
_uis.TryAdd(type, ui);
}
public void UnregisterUI(BaseUi ui)
{
var type = ui.GetType();
if (_uis.TryGetValue(type, out var registered) && registered == ui)
{
_uis.Remove(type);
}
}
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(evt);
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.ClosePanel();
PopPopup(popup);
if (popup.IsBlockingTime)
{
var timeScaleChangeEvent = GameEvents.RequestTimeScaleChangeEvent;
timeScaleChangeEvent.Requester = popup;
timeScaleChangeEvent.NewTimeScale = 1f;
EventBus.Broadcast(timeScaleChangeEvent);
}
}
}
}
public bool HasMatchingPopupUis(GameFlowState flowState)
{
return _uiData.FlowToUiMapping.Any(keyValuePair => (keyValuePair.Key & flowState) != 0);
}
public void CreateUi(BaseUi ui, Transform parent)
{
if (_uis.TryGetValue(ui.GetType(), out var registered) && registered == ui) return;
var instance = Instantiate(ui, parent);
instance.name = ui.name;
instance.CreateInitialize();
}
public void DestroyUi(BaseUi ui)
{
if (_uis.TryGetValue(ui.GetType(), out var registered) && registered == ui) return;
Destroy(ui.gameObject);
}
public bool IsTopPopup(BasePopupUi popup)
{
return _popupUiStack.Count > 0 && _popupUiStack.Peek() == popup;
}
public void PushPopup(BasePopupUi popup)
{
if (_popupUiStack.Contains(popup)) return;
if (_popupUiStack.Count == 0)
{
_previousActionMap = InputManager.Instance.GetCurrentActionMap();
}
_popupUiStack.Push(popup);
UpdatePopupCanvasGroups();
}
public void PopPopup(BasePopupUi popup)
{
if (_popupUiStack.Count == 0) return;
if (_popupUiStack.Peek() == popup)
{
_popupUiStack.Pop();
}
else
{
var temp = _popupUiStack.Reverse().Where(p => p != popup).Reverse().ToList();
_popupUiStack.Clear();
foreach (var p in temp)
{
_popupUiStack.Push(p);
}
}
if (_popupUiStack.TryPeek(out var topPopup) && topPopup.IsOpen)
{
InputManager.Instance.SwitchCurrentActionMap(topPopup.InputActionMaps);
}
else
{
InputManager.Instance.SwitchCurrentActionMap(_previousActionMap);
}
UpdatePopupCanvasGroups();
}
private void UpdatePopupCanvasGroups()
{
if (_popupUiStack.Count == 0) return;
foreach (var popupUi in _popupUiStack)
{
bool isTop = IsTopPopup(popupUi);
popupUi.SetUiInteractable(isTop);
}
}
}
}