using System; namespace AibisDream { public enum GameSessionPhase { MainMenu, Starting, Transitioning, Restoring, Playing, ReturningToMenu } /// /// 单次游戏会话的纯状态模型。它不执行流程,也不发送全局事件。 /// 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) }; } } }