96 lines
3.2 KiB
C#
96 lines
3.2 KiB
C#
using System;
|
|
|
|
namespace AibisDream
|
|
{
|
|
public enum GameSessionPhase
|
|
{
|
|
MainMenu,
|
|
Starting,
|
|
Transitioning,
|
|
Restoring,
|
|
Playing,
|
|
ReturningToMenu
|
|
}
|
|
|
|
/// <summary>
|
|
/// 单次游戏会话的纯状态模型。它不执行流程,也不发送全局事件。
|
|
/// </summary>
|
|
public sealed class GameSession
|
|
{
|
|
public GameSessionPhase Phase { get; private set; } = GameSessionPhase.MainMenu;
|
|
public TalkSceneSO CurrentTalkScene { get; private set; }
|
|
public bool IsPaused { get; private set; }
|
|
public bool IsDialogueActive { get; private set; }
|
|
|
|
public bool IsActive => Phase != GameSessionPhase.MainMenu;
|
|
|
|
public bool IsBusy => Phase is GameSessionPhase.Starting
|
|
or GameSessionPhase.Transitioning
|
|
or GameSessionPhase.Restoring
|
|
or GameSessionPhase.ReturningToMenu;
|
|
|
|
public bool CanPause => Phase == GameSessionPhase.Playing && !IsPaused;
|
|
public bool CanResume => Phase == GameSessionPhase.Playing && IsPaused;
|
|
public bool CanAdvanceDialogue => Phase == GameSessionPhase.Playing && IsDialogueActive && !IsPaused;
|
|
|
|
internal bool TryTransitionTo(GameSessionPhase next, out string error)
|
|
{
|
|
if (Phase == next)
|
|
{
|
|
error = null;
|
|
return true;
|
|
}
|
|
|
|
if (!IsTransitionAllowed(Phase, next))
|
|
{
|
|
error = $"Illegal game session transition: {Phase} -> {next}";
|
|
return false;
|
|
}
|
|
|
|
Phase = next;
|
|
error = null;
|
|
return true;
|
|
}
|
|
|
|
internal void SetCurrentTalkScene(TalkSceneSO scene)
|
|
{
|
|
CurrentTalkScene = scene;
|
|
}
|
|
|
|
internal void SetPaused(bool paused)
|
|
{
|
|
IsPaused = paused;
|
|
}
|
|
|
|
internal void SetDialogueActive(bool active)
|
|
{
|
|
IsDialogueActive = active;
|
|
}
|
|
|
|
internal void ResetRuntimeState()
|
|
{
|
|
CurrentTalkScene = null;
|
|
IsPaused = false;
|
|
IsDialogueActive = false;
|
|
}
|
|
|
|
private static bool IsTransitionAllowed(GameSessionPhase current, GameSessionPhase next)
|
|
{
|
|
return current switch
|
|
{
|
|
GameSessionPhase.MainMenu => next is GameSessionPhase.Starting or GameSessionPhase.Restoring,
|
|
GameSessionPhase.Starting => next is GameSessionPhase.Playing or GameSessionPhase.ReturningToMenu,
|
|
GameSessionPhase.Transitioning => next is GameSessionPhase.Playing or GameSessionPhase.ReturningToMenu,
|
|
GameSessionPhase.Restoring => next is GameSessionPhase.Playing
|
|
or GameSessionPhase.MainMenu
|
|
or GameSessionPhase.ReturningToMenu,
|
|
GameSessionPhase.Playing => next is GameSessionPhase.Transitioning
|
|
or GameSessionPhase.Restoring
|
|
or GameSessionPhase.ReturningToMenu,
|
|
GameSessionPhase.ReturningToMenu => next == GameSessionPhase.MainMenu,
|
|
_ => throw new ArgumentOutOfRangeException(nameof(current), current, null)
|
|
};
|
|
}
|
|
}
|
|
}
|