diff --git a/GFramework.Core.Tests/tests/AsyncArchitectureTests.cs b/GFramework.Core.Tests/tests/AsyncArchitectureTests.cs index de86f7b..85a44c4 100644 --- a/GFramework.Core.Tests/tests/AsyncArchitectureTests.cs +++ b/GFramework.Core.Tests/tests/AsyncArchitectureTests.cs @@ -1,4 +1,4 @@ -using GFramework.Core.Abstractions.enums; +using GFramework.Core.Abstractions.enums; using GFramework.Core.Tests.architecture; using GFramework.Core.Tests.model; using GFramework.Core.Tests.system; @@ -94,7 +94,7 @@ public class AsyncArchitectureTests : ArchitectureTestsBase { a.RegisterModel(new FailingModel()); }); - await Architecture.InitializeAsync(); + Assert.ThrowsAsync(async () => await Architecture.InitializeAsync()); Assert.That( Architecture.CurrentPhase, @@ -141,7 +141,7 @@ public class AsyncArchitectureTests : ArchitectureTestsBase(async () => await Architecture.InitializeAsync()); AssertInitializationFailed(); } diff --git a/GFramework.Core.Tests/tests/SyncArchitectureTests.cs b/GFramework.Core.Tests/tests/SyncArchitectureTests.cs index 3216d38..c85142d 100644 --- a/GFramework.Core.Tests/tests/SyncArchitectureTests.cs +++ b/GFramework.Core.Tests/tests/SyncArchitectureTests.cs @@ -1,4 +1,3 @@ -using System; using GFramework.Core.Abstractions.enums; using GFramework.Core.architecture; using GFramework.Core.Tests.architecture; @@ -137,7 +136,7 @@ public class SyncArchitectureTests : ArchitectureTestsBase a.RegisterModel(new FailingModel()) ); - Architecture.Initialize(); + Assert.Throws(() => Architecture.Initialize()); AssertInitializationFailed(); } diff --git a/GFramework.Core/architecture/Architecture.cs b/GFramework.Core/architecture/Architecture.cs index d66498e..33af54b 100644 --- a/GFramework.Core/architecture/Architecture.cs +++ b/GFramework.Core/architecture/Architecture.cs @@ -134,6 +134,7 @@ public abstract class Architecture( #region Lifecycle Management + // ==================== 方案1: 早期返回 (推荐) ==================== /// /// 进入指定的架构阶段,并执行相应的生命周期管理操作 /// @@ -141,29 +142,57 @@ public abstract class Architecture( /// 当阶段转换不被允许时抛出异常 protected virtual void EnterPhase(ArchitecturePhase next) { - if (Configuration.ArchitectureProperties.StrictPhaseValidation && - (!ArchitectureConstants.PhaseTransitions.TryGetValue(CurrentPhase, out var allowed) || - !allowed.Contains(next))) - { - // 验证阶段转换是否合法 - var errorMsg = $"Invalid phase transition: {CurrentPhase} -> {next}"; - _logger.Fatal(errorMsg); - throw new InvalidOperationException(errorMsg); - } + // 验证阶段转换 + ValidatePhaseTransition(next); + // 执行阶段转换 var previousPhase = CurrentPhase; CurrentPhase = next; if (previousPhase != next) _logger.Info($"Architecture phase changed: {previousPhase} -> {next}"); + // 通知阶段变更 NotifyPhase(next); + NotifyPhaseAwareObjects(next); + } - // 通知所有架构阶段感知对象阶段变更 + /// + /// 验证阶段转换是否合法 + /// + /// 目标阶段 + /// 当阶段转换不合法时抛出 + private void ValidatePhaseTransition(ArchitecturePhase next) + { + // 不需要严格验证,直接返回 + if (!Configuration.ArchitectureProperties.StrictPhaseValidation) + return; + + // FailedInitialization 可以从任何阶段转换,直接返回 + if (next == ArchitecturePhase.FailedInitialization) + return; + + // 检查转换是否在允许列表中 + if (ArchitectureConstants.PhaseTransitions.TryGetValue(CurrentPhase, out var allowed) && + allowed.Contains(next)) + return; + + // 转换不合法,抛出异常 + var errorMsg = $"Invalid phase transition: {CurrentPhase} -> {next}"; + _logger.Fatal(errorMsg); + throw new InvalidOperationException(errorMsg); + } + + /// + /// 通知所有架构阶段感知对象阶段变更 + /// + /// 新阶段 + private void NotifyPhaseAwareObjects(ArchitecturePhase phase) + { foreach (var obj in Container.GetAll()) { - _logger.Trace($"Notifying phase-aware object {obj.GetType().Name} of phase change to {next}"); - obj.OnArchitecturePhase(next); + _logger.Trace($"Notifying phase-aware object {obj.GetType().Name} of phase change to {phase}"); + obj.OnArchitecturePhase(phase); } } @@ -232,10 +261,11 @@ public abstract class Architecture( var models = _pendingInitializableList.OfType().ToList(); var systems = _pendingInitializableList.OfType().ToList(); - // 1. 初始化工具 + // 1. 工具初始化阶段(始终进入阶段,仅在有组件时执行初始化) + EnterPhase(ArchitecturePhase.BeforeUtilityInit); + if (utilities.Count != 0) { - EnterPhase(ArchitecturePhase.BeforeUtilityInit); _logger.Info($"Initializing {utilities.Count} context utilities"); foreach (var utility in utilities) @@ -244,14 +274,16 @@ public abstract class Architecture( await InitializeComponentAsync(utility, asyncMode); } - EnterPhase(ArchitecturePhase.AfterUtilityInit); _logger.Info("All context utilities initialized"); } - // 2. 初始化模型 + EnterPhase(ArchitecturePhase.AfterUtilityInit); + + // 2. 模型初始化阶段(始终进入阶段,仅在有组件时执行初始化) + EnterPhase(ArchitecturePhase.BeforeModelInit); + if (models.Count != 0) { - EnterPhase(ArchitecturePhase.BeforeModelInit); _logger.Info($"Initializing {models.Count} models"); foreach (var model in models) @@ -260,14 +292,16 @@ public abstract class Architecture( await InitializeComponentAsync(model, asyncMode); } - EnterPhase(ArchitecturePhase.AfterModelInit); _logger.Info("All models initialized"); } - // 3. 初始化系统 + EnterPhase(ArchitecturePhase.AfterModelInit); + + // 3. 系统初始化阶段(始终进入阶段,仅在有组件时执行初始化) + EnterPhase(ArchitecturePhase.BeforeSystemInit); + if (systems.Count != 0) { - EnterPhase(ArchitecturePhase.BeforeSystemInit); _logger.Info($"Initializing {systems.Count} systems"); foreach (var system in systems) @@ -276,10 +310,11 @@ public abstract class Architecture( await InitializeComponentAsync(system, asyncMode); } - EnterPhase(ArchitecturePhase.AfterSystemInit); _logger.Info("All systems initialized"); } + EnterPhase(ArchitecturePhase.AfterSystemInit); + _pendingInitializableList.Clear(); _logger.Info("All components initialized"); } diff --git a/GFramework.Core/architecture/ArchitectureConstants.cs b/GFramework.Core/architecture/ArchitectureConstants.cs index f81d2b5..5efcfd2 100644 --- a/GFramework.Core/architecture/ArchitectureConstants.cs +++ b/GFramework.Core/architecture/ArchitectureConstants.cs @@ -1,4 +1,4 @@ -using System.Collections.Immutable; +using System.Collections.Immutable; using GFramework.Core.Abstractions.enums; namespace GFramework.Core.architecture; @@ -8,42 +8,47 @@ namespace GFramework.Core.architecture; /// public static class ArchitectureConstants { + /// + /// 定义架构阶段的线性顺序 + /// + /// + /// 架构阶段永远按照此顺序线性进行,无论是否有组件注册 + /// + public static readonly ArchitecturePhase[] PhaseOrder = + [ + ArchitecturePhase.None, + ArchitecturePhase.BeforeUtilityInit, + ArchitecturePhase.AfterUtilityInit, + ArchitecturePhase.BeforeModelInit, + ArchitecturePhase.AfterModelInit, + ArchitecturePhase.BeforeSystemInit, + ArchitecturePhase.AfterSystemInit, + ArchitecturePhase.Ready, + ArchitecturePhase.Destroying, + ArchitecturePhase.Destroyed + ]; + /// /// 定义架构阶段之间的有效转换关系 /// /// /// 键为当前架构阶段,值为从该阶段可以转换到的下一阶段数组 + /// 架构采用线性状态机模式,只允许顺序转换,但允许从任何阶段转到 FailedInitialization /// public static readonly ImmutableDictionary PhaseTransitions = new Dictionary { + // 正常线性流程 { ArchitecturePhase.None, [ArchitecturePhase.BeforeUtilityInit] }, - { - ArchitecturePhase.BeforeUtilityInit, - [ArchitecturePhase.AfterUtilityInit, ArchitecturePhase.FailedInitialization] - }, - { - ArchitecturePhase.AfterUtilityInit, - [ArchitecturePhase.BeforeModelInit, ArchitecturePhase.FailedInitialization] - }, - { - ArchitecturePhase.BeforeModelInit, [ - ArchitecturePhase.AfterModelInit, ArchitecturePhase.FailedInitialization - ] - }, - { - ArchitecturePhase.AfterModelInit, [ - ArchitecturePhase.BeforeSystemInit, ArchitecturePhase.FailedInitialization - ] - }, - { - ArchitecturePhase.BeforeSystemInit, [ - ArchitecturePhase.AfterSystemInit, ArchitecturePhase.FailedInitialization - ] - }, - { ArchitecturePhase.AfterSystemInit, [ArchitecturePhase.Ready, ArchitecturePhase.FailedInitialization] }, + { ArchitecturePhase.BeforeUtilityInit, [ArchitecturePhase.AfterUtilityInit] }, + { ArchitecturePhase.AfterUtilityInit, [ArchitecturePhase.BeforeModelInit] }, + { ArchitecturePhase.BeforeModelInit, [ArchitecturePhase.AfterModelInit] }, + { ArchitecturePhase.AfterModelInit, [ArchitecturePhase.BeforeSystemInit] }, + { ArchitecturePhase.BeforeSystemInit, [ArchitecturePhase.AfterSystemInit] }, + { ArchitecturePhase.AfterSystemInit, [ArchitecturePhase.Ready] }, { ArchitecturePhase.Ready, [ArchitecturePhase.Destroying] }, - { ArchitecturePhase.FailedInitialization, [ArchitecturePhase.Destroying] }, - { ArchitecturePhase.Destroying, [ArchitecturePhase.Destroyed] } + { ArchitecturePhase.Destroying, [ArchitecturePhase.Destroyed] }, + // 失败路径:从任何阶段都可以转到 FailedInitialization + { ArchitecturePhase.FailedInitialization, [ArchitecturePhase.Destroying] } }.ToImmutableDictionary(); } \ No newline at end of file