Refine UI stack and add Ashwick keypad puzzle
This commit is contained in:
@@ -1,5 +1,6 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Threading;
|
||||
using BriarQueen.Data.Identifiers;
|
||||
using BriarQueen.Framework.Coordinators.Events;
|
||||
using BriarQueen.Framework.Events.UI;
|
||||
@@ -34,6 +35,7 @@ namespace BriarQueen.Framework.Managers.UI
|
||||
|
||||
private readonly Dictionary<WindowType, IUIWindow> _windows = new();
|
||||
private readonly Stack<IUIWindow> _windowStack = new();
|
||||
private readonly SemaphoreSlim _windowTransitionGate = new(1, 1);
|
||||
|
||||
private bool _disposed;
|
||||
|
||||
@@ -43,6 +45,8 @@ namespace BriarQueen.Framework.Managers.UI
|
||||
private IPopup _infoPopup;
|
||||
private IPopup _tutorialPopup;
|
||||
private IScreenFader _screenFader;
|
||||
private IUIOverlayHost _mainMenuOverlayHost;
|
||||
private IUIOverlayHost _activeSettingsOverlayHost;
|
||||
|
||||
[Inject]
|
||||
public UIManager(
|
||||
@@ -155,11 +159,33 @@ namespace BriarQueen.Framework.Managers.UI
|
||||
_screenFader = screenFader;
|
||||
}
|
||||
|
||||
public void RegisterMainMenuOverlayHost(IUIOverlayHost host)
|
||||
{
|
||||
_mainMenuOverlayHost = host;
|
||||
}
|
||||
|
||||
public void UnregisterMainMenuOverlayHost(IUIOverlayHost host)
|
||||
{
|
||||
if (!ReferenceEquals(_mainMenuOverlayHost, host))
|
||||
return;
|
||||
|
||||
if (ReferenceEquals(_activeSettingsOverlayHost, host))
|
||||
_activeSettingsOverlayHost = null;
|
||||
|
||||
_mainMenuOverlayHost = null;
|
||||
}
|
||||
|
||||
private IUIWindow GetWindow(WindowType windowType)
|
||||
{
|
||||
return _windows.TryGetValue(windowType, out var window) ? window : null;
|
||||
}
|
||||
|
||||
public bool IsWindowOpen(WindowType windowType)
|
||||
{
|
||||
var target = GetWindow(windowType);
|
||||
return target != null && _windowStack.Contains(target);
|
||||
}
|
||||
|
||||
private async UniTask ApplyHudVisibility(bool visible)
|
||||
{
|
||||
if (_disposed || _hudContainer == null)
|
||||
@@ -197,7 +223,7 @@ namespace BriarQueen.Framework.Managers.UI
|
||||
private void ToggleSettingsWindow(UIToggleSettingsWindow eventData)
|
||||
{
|
||||
if (eventData.Show)
|
||||
OpenWindow(WindowType.SettingsWindow);
|
||||
OpenSettingsWindow(eventData.Source).Forget();
|
||||
else
|
||||
CloseWindow(WindowType.SettingsWindow);
|
||||
}
|
||||
@@ -208,9 +234,15 @@ namespace BriarQueen.Framework.Managers.UI
|
||||
return;
|
||||
|
||||
if (eventData.Shown)
|
||||
OpenWindow(WindowType.CodexWindow);
|
||||
{
|
||||
if (!IsWindowOpen(WindowType.CodexWindow))
|
||||
OpenWindow(WindowType.CodexWindow);
|
||||
}
|
||||
else
|
||||
CloseWindow(WindowType.CodexWindow);
|
||||
{
|
||||
if (IsWindowOpen(WindowType.CodexWindow))
|
||||
CloseWindow(WindowType.CodexWindow);
|
||||
}
|
||||
}
|
||||
|
||||
private void OnCodexChangedEvent(CodexChangedEvent eventData)
|
||||
@@ -300,32 +332,94 @@ namespace BriarQueen.Framework.Managers.UI
|
||||
OpenWindowInternal(windowType).Forget();
|
||||
}
|
||||
|
||||
private async UniTask OpenSettingsWindow(SettingsOpenSource source)
|
||||
{
|
||||
await _windowTransitionGate.WaitAsync();
|
||||
try
|
||||
{
|
||||
if (_disposed)
|
||||
return;
|
||||
|
||||
var window = GetWindow(WindowType.SettingsWindow);
|
||||
if (window == null)
|
||||
{
|
||||
Debug.LogError("[UIManager] Window of type SettingsWindow not registered.");
|
||||
return;
|
||||
}
|
||||
|
||||
if (_windowStack.Contains(window))
|
||||
return;
|
||||
|
||||
_activeSettingsOverlayHost = null;
|
||||
|
||||
var openingSettingsOverPause =
|
||||
source == SettingsOpenSource.PauseMenu &&
|
||||
ActiveWindow?.WindowType == WindowType.PauseMenuWindow &&
|
||||
ActiveWindow is IUIOverlayHost;
|
||||
|
||||
var openingSettingsOverMainMenu =
|
||||
source == SettingsOpenSource.MainMenu &&
|
||||
_mainMenuOverlayHost != null;
|
||||
|
||||
if (openingSettingsOverPause)
|
||||
{
|
||||
_activeSettingsOverlayHost = (IUIOverlayHost)ActiveWindow;
|
||||
await _activeSettingsOverlayHost.SuspendForOverlay();
|
||||
}
|
||||
else if (openingSettingsOverMainMenu)
|
||||
{
|
||||
_activeSettingsOverlayHost = _mainMenuOverlayHost;
|
||||
await _activeSettingsOverlayHost.SuspendForOverlay();
|
||||
}
|
||||
else if (ActiveWindow != null)
|
||||
{
|
||||
await ActiveWindow.Hide();
|
||||
}
|
||||
|
||||
_windowStack.Push(window);
|
||||
await window.Show();
|
||||
|
||||
NotifyWindowStateChanged(window.WindowType, true);
|
||||
NotifyUIStackChanged();
|
||||
}
|
||||
finally
|
||||
{
|
||||
_windowTransitionGate.Release();
|
||||
}
|
||||
}
|
||||
|
||||
private async UniTask OpenWindowInternal(WindowType windowType)
|
||||
{
|
||||
if (_disposed)
|
||||
return;
|
||||
|
||||
var window = GetWindow(windowType);
|
||||
|
||||
if (window == null)
|
||||
await _windowTransitionGate.WaitAsync();
|
||||
try
|
||||
{
|
||||
Debug.LogError($"[UIManager] Window of type {windowType} not registered.");
|
||||
return;
|
||||
}
|
||||
if (_disposed)
|
||||
return;
|
||||
|
||||
if (ActiveWindow == window)
|
||||
return;
|
||||
|
||||
if (ActiveWindow != null)
|
||||
{
|
||||
var window = GetWindow(windowType);
|
||||
|
||||
await ActiveWindow.Hide();
|
||||
if (window == null)
|
||||
{
|
||||
Debug.LogError($"[UIManager] Window of type {windowType} not registered.");
|
||||
return;
|
||||
}
|
||||
|
||||
if (_windowStack.Contains(window))
|
||||
return;
|
||||
|
||||
if (ActiveWindow != null)
|
||||
await ActiveWindow.Hide();
|
||||
|
||||
_windowStack.Push(window);
|
||||
await window.Show();
|
||||
|
||||
NotifyWindowStateChanged(window.WindowType, true);
|
||||
NotifyUIStackChanged();
|
||||
}
|
||||
finally
|
||||
{
|
||||
_windowTransitionGate.Release();
|
||||
}
|
||||
|
||||
_windowStack.Push(window);
|
||||
await window.Show();
|
||||
|
||||
NotifyUIStackChanged();
|
||||
}
|
||||
|
||||
public void CloseWindow(WindowType windowType)
|
||||
@@ -335,27 +429,45 @@ namespace BriarQueen.Framework.Managers.UI
|
||||
|
||||
private async UniTask CloseWindowInternal(WindowType windowType)
|
||||
{
|
||||
if (_disposed || _windowStack.Count == 0)
|
||||
return;
|
||||
|
||||
var target = GetWindow(windowType);
|
||||
if (target == null)
|
||||
return;
|
||||
|
||||
while (_windowStack.Count > 0)
|
||||
await _windowTransitionGate.WaitAsync();
|
||||
try
|
||||
{
|
||||
var current = _windowStack.Pop();
|
||||
if (current != null)
|
||||
await current.Hide();
|
||||
if (_disposed || _windowStack.Count == 0)
|
||||
return;
|
||||
|
||||
if (current == target)
|
||||
break;
|
||||
var target = GetWindow(windowType);
|
||||
if (target == null || !_windowStack.Contains(target))
|
||||
return;
|
||||
|
||||
while (_windowStack.Count > 0)
|
||||
{
|
||||
var current = _windowStack.Pop();
|
||||
if (current != null)
|
||||
{
|
||||
await current.Hide();
|
||||
NotifyWindowStateChanged(current.WindowType, false);
|
||||
}
|
||||
|
||||
if (current == target)
|
||||
break;
|
||||
}
|
||||
|
||||
if (target.WindowType == WindowType.SettingsWindow && _activeSettingsOverlayHost != null)
|
||||
{
|
||||
await _activeSettingsOverlayHost.ResumeFromOverlay();
|
||||
_activeSettingsOverlayHost = null;
|
||||
}
|
||||
else if (ActiveWindow != null)
|
||||
{
|
||||
await ActiveWindow.Show();
|
||||
}
|
||||
|
||||
NotifyUIStackChanged();
|
||||
}
|
||||
finally
|
||||
{
|
||||
_windowTransitionGate.Release();
|
||||
}
|
||||
|
||||
if (ActiveWindow != null)
|
||||
await ActiveWindow.Show();
|
||||
|
||||
NotifyUIStackChanged();
|
||||
}
|
||||
|
||||
public void CloseTopWindow()
|
||||
@@ -380,18 +492,38 @@ namespace BriarQueen.Framework.Managers.UI
|
||||
|
||||
private async UniTask CloseTopWindowInternal()
|
||||
{
|
||||
if (_disposed || _windowStack.Count == 0)
|
||||
return;
|
||||
await _windowTransitionGate.WaitAsync();
|
||||
try
|
||||
{
|
||||
if (_disposed || _windowStack.Count == 0)
|
||||
return;
|
||||
|
||||
var top = _windowStack.Pop();
|
||||
var top = _windowStack.Pop();
|
||||
|
||||
if (top != null)
|
||||
await top.Hide();
|
||||
if (top != null)
|
||||
{
|
||||
await top.Hide();
|
||||
NotifyWindowStateChanged(top.WindowType, false);
|
||||
}
|
||||
|
||||
if (ActiveWindow != null)
|
||||
await ActiveWindow.Show();
|
||||
if (top != null &&
|
||||
top.WindowType == WindowType.SettingsWindow &&
|
||||
_activeSettingsOverlayHost != null)
|
||||
{
|
||||
await _activeSettingsOverlayHost.ResumeFromOverlay();
|
||||
_activeSettingsOverlayHost = null;
|
||||
}
|
||||
else if (ActiveWindow != null)
|
||||
{
|
||||
await ActiveWindow.Show();
|
||||
}
|
||||
|
||||
NotifyUIStackChanged();
|
||||
NotifyUIStackChanged();
|
||||
}
|
||||
finally
|
||||
{
|
||||
_windowTransitionGate.Release();
|
||||
}
|
||||
}
|
||||
|
||||
public void ResetUIState()
|
||||
@@ -401,44 +533,71 @@ namespace BriarQueen.Framework.Managers.UI
|
||||
|
||||
public async UniTask ResetUIStateAsync()
|
||||
{
|
||||
while (_windowStack.Count > 0)
|
||||
await _windowTransitionGate.WaitAsync();
|
||||
try
|
||||
{
|
||||
var window = _windowStack.Pop();
|
||||
if (window != null)
|
||||
var shouldResumeSettingsHost = false;
|
||||
|
||||
while (_windowStack.Count > 0)
|
||||
{
|
||||
var window = _windowStack.Pop();
|
||||
if (window == null)
|
||||
continue;
|
||||
|
||||
if (window.WindowType == WindowType.SettingsWindow && _activeSettingsOverlayHost != null)
|
||||
shouldResumeSettingsHost = true;
|
||||
|
||||
try
|
||||
{
|
||||
await window.Hide();
|
||||
NotifyWindowStateChanged(window.WindowType, false);
|
||||
}
|
||||
catch
|
||||
{
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (_tutorialPopup != null)
|
||||
if (shouldResumeSettingsHost)
|
||||
{
|
||||
try
|
||||
{
|
||||
await _activeSettingsOverlayHost.ResumeFromOverlay();
|
||||
}
|
||||
catch
|
||||
{
|
||||
}
|
||||
}
|
||||
|
||||
_activeSettingsOverlayHost = null;
|
||||
|
||||
if (_tutorialPopup != null)
|
||||
{
|
||||
try
|
||||
{
|
||||
await _tutorialPopup.Hide();
|
||||
}
|
||||
catch
|
||||
{
|
||||
}
|
||||
}
|
||||
|
||||
if (_infoPopup != null)
|
||||
{
|
||||
try
|
||||
{
|
||||
await _infoPopup.Hide();
|
||||
}
|
||||
catch
|
||||
{
|
||||
}
|
||||
}
|
||||
|
||||
NotifyUIStackChanged();
|
||||
}
|
||||
finally
|
||||
{
|
||||
try
|
||||
{
|
||||
await _tutorialPopup.Hide();
|
||||
}
|
||||
catch
|
||||
{
|
||||
}
|
||||
_windowTransitionGate.Release();
|
||||
}
|
||||
|
||||
if (_infoPopup != null)
|
||||
{
|
||||
try
|
||||
{
|
||||
await _infoPopup.Hide();
|
||||
}
|
||||
catch
|
||||
{
|
||||
}
|
||||
}
|
||||
|
||||
NotifyUIStackChanged();
|
||||
}
|
||||
|
||||
private void ResetUIStateHard()
|
||||
@@ -462,11 +621,18 @@ namespace BriarQueen.Framework.Managers.UI
|
||||
faderComponent.gameObject.SetActive(false);
|
||||
|
||||
_windowStack.Clear();
|
||||
_activeSettingsOverlayHost = null;
|
||||
_mainMenuOverlayHost = null;
|
||||
}
|
||||
|
||||
private void NotifyUIStackChanged()
|
||||
{
|
||||
_eventCoordinator.Publish(new UIStackChangedEvent(_windowStack.Count > 0));
|
||||
}
|
||||
|
||||
private void NotifyWindowStateChanged(WindowType windowType, bool isOpen)
|
||||
{
|
||||
_eventCoordinator.Publish(new UIWindowStateChangedEvent(windowType, isOpen));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user