-
-
Save Syjgin/c686d1e4261f4bb725c530c8a523946e to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
using System; | |
using System.Collections.Generic; | |
using System.Linq; | |
using Components; | |
using PlatformMode; | |
namespace Dialogues.PopupQueue | |
{ | |
public class PopupQueue | |
{ | |
private readonly Stack<IPopupQueueElement> _visibleElements = new(); | |
private readonly Queue<IPopupQueueElement> _elementsToDisplay = new(); | |
private GameScene _currentMode; | |
private PopupQueueOperation _lastOperation; | |
private readonly Dictionary<PopupQueueElementType, bool> _elementExists = new(); | |
public PopupQueueElementType Init(GameScene scene) //необязательно, просто в нашем случае окна ведут себя по-разному в зависимости от текущей сцены | |
{ | |
_visibleElements.Clear(); | |
_elementsToDisplay.Clear(); | |
_elementExists.Clear(); | |
foreach (var popupType in (PopupQueueElementType[]) Enum.GetValues(typeof(PopupQueueElementType))) | |
{ | |
_elementExists[popupType] = false; | |
} | |
_currentMode = scene; | |
switch (_currentMode) | |
{ | |
case GameScene.Menu: | |
ShowMainMenu(); | |
return PopupQueueElementType.MainMenuPopup; | |
case GameScene.Flying: | |
return PopupQueueElementType.NoPopup; | |
case GameScene.Platform: | |
return PopupQueueElementType.Platform; | |
default: | |
return PopupQueueElementType.NoPopup; | |
} | |
} | |
public bool TryCloseCurrentElement(bool force = false) | |
{ | |
return TryEnqueueElement(new NoPopupQueueElement(force)); | |
} | |
public bool TryEnqueueElement(IPopupQueueElement element) | |
{ | |
if (!IsElementAllowedHere(element.ElementType)) //опять же, способ добавить специфичную для сцены логику, но не обязательно | |
return false; | |
var isElementDenied = GetCurrentElement().DenyNextElementTypes.Contains(element.ElementType) && !element.IsIgnoreDenyElements; | |
switch (element.OpenOperation) | |
{ | |
case PopupQueueOperation.OverlapPrevious: | |
if (_elementExists[element.ElementType]) | |
return false; | |
if (isElementDenied) | |
{ | |
_elementsToDisplay.Enqueue(element); | |
return false; | |
} | |
Enqueue(element.OpenOperation, element); | |
return true; | |
case PopupQueueOperation.HidePrevious: | |
if (_elementExists[element.ElementType]) | |
return false; | |
if (isElementDenied) | |
{ | |
return false; | |
} | |
Enqueue(element.OpenOperation, element); | |
return true; | |
case PopupQueueOperation.MergePrevious: | |
if (isElementDenied) | |
{ | |
_elementsToDisplay.Enqueue(element); | |
return false; | |
} | |
if (GetCurrentElement().ElementType == element.ElementType) | |
{ | |
_visibleElements.Pop(); | |
} | |
Enqueue(element.OpenOperation, element); | |
return true; | |
case PopupQueueOperation.BringFromForeground: | |
if (isElementDenied) | |
return false; | |
switch (_currentMode) | |
{ | |
case GameScene.Menu: | |
if (_visibleElements.Peek().ElementType == PopupQueueElementType.MainMenuPopup) | |
{ | |
return false; | |
} | |
break; | |
case GameScene.Flying: | |
if (_visibleElements.Count == 0) | |
{ | |
ShowMainMenu(); | |
return true; | |
} | |
break; | |
case GameScene.Platform: | |
if (_visibleElements.Count > 0) | |
{ | |
var topElement = _visibleElements.Peek(); | |
if (topElement.ElementType == PopupQueueElementType.Platform) | |
{ | |
ShowMainMenu(); | |
return true; | |
} | |
} | |
break; | |
default: | |
break; | |
} | |
if (_visibleElements.Count > 0) | |
{ | |
var removedElement = _visibleElements.Pop(); | |
_elementExists[removedElement.ElementType] = false; | |
} | |
_lastOperation = PopupQueueOperation.BringFromForeground; | |
return true; | |
default: | |
return false; | |
} | |
} | |
public bool TryEnqueuePreviousElement() | |
{ | |
if (_elementsToDisplay.Count == 0) return false; | |
var newDisplayedElement = _elementsToDisplay.Peek(); | |
var result = TryEnqueueElement(newDisplayedElement); | |
if(result) | |
_elementsToDisplay.Dequeue(); | |
return result; | |
} | |
public PopupQueueOperation GetLastOperation() | |
{ | |
return _lastOperation; | |
} | |
public IPopupQueueElement GetCurrentElement() | |
{ | |
return _visibleElements.Count > 0 ? _visibleElements.Peek() : new NoPopupQueueElement(); | |
} | |
private bool IsElementAllowedHere(PopupQueueElementType elementType) | |
{ | |
if (elementType == PopupQueueElementType.NoPopup) | |
return true; | |
switch (_currentMode) | |
{ | |
case GameScene.Menu: | |
return elementType is PopupQueueElementType.ConfirmPopup | |
or PopupQueueElementType.MainMenuPopup or PopupQueueElementType.SavesPopup | |
or PopupQueueElementType.SettingsPopup or PopupQueueElementType.AboutPopup; | |
case GameScene.Flying: | |
return elementType != PopupQueueElementType.Platform && | |
elementType != PopupQueueElementType.Building && | |
elementType != PopupQueueElementType.AboutPopup; | |
case GameScene.Platform: | |
{ | |
var current = GetCurrentElement(); | |
switch (current) | |
{ | |
case BuildingDialogueDefinition buildingDialogueDefinition when buildingDialogueDefinition.Building.Building.BuildingType == BuildingType.Airship && elementType == PopupQueueElementType.AirshipPopup: | |
case PlatformDialogueDefinition platformDialogueDefinition when platformDialogueDefinition.Platform.CurrentBuildingId == StaticPlatform.CrewNacelle: | |
return true; | |
default: | |
return elementType != PopupQueueElementType.AboutPopup && elementType != PopupQueueElementType.AirshipPopup; | |
} | |
} | |
default: | |
throw new ArgumentOutOfRangeException(); | |
} | |
} | |
private void Enqueue(PopupQueueOperation operation, IPopupQueueElement element) | |
{ | |
var previous = GetCurrentElement(); | |
_visibleElements.Push(element); | |
_elementExists[element.ElementType] = true; | |
if (operation == PopupQueueOperation.HidePrevious && !previous.CanBeHidden) | |
{ | |
_lastOperation = PopupQueueOperation.OverlapPrevious; | |
return; | |
} | |
_lastOperation = operation; | |
} | |
private void ShowMainMenu() | |
{ | |
Enqueue(PopupQueueOperation.OverlapPrevious,new MainMenuPopupDefinition()); | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment