From d1cd0cfb05d868c9e818493a59949b050eb80493 Mon Sep 17 00:00:00 2001 From: GwWuYou <95328647+GeWuYou@users.noreply.github.com> Date: Sun, 21 Dec 2025 11:39:35 +0800 Subject: [PATCH] =?UTF-8?q?feat(architecture):=20=E5=BC=95=E5=85=A5?= =?UTF-8?q?=E6=9E=B6=E6=9E=84=E9=98=B6=E6=AE=B5=E7=AE=A1=E7=90=86=E6=9C=BA?= =?UTF-8?q?=E5=88=B6?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 新增 `ArchitecturePhase` 枚举及生命周期接口,支持在不同阶段执行相应逻辑。 实现基于阶段的状态转换控制与校验,增强架构初始化流程的可控性与扩展性。 添加模块安装接口 `IArchitectureModule` 及相关感知接口,便于插件化集成。 完善系统与模型注册限制,禁止在就绪后注册组件,提升运行时稳定性。 移除旧版补丁注册机制,统一通过生命周期钩子进行扩展。 --- GFramework.Core/architecture/Architecture.cs | 86 ++++++++++++++++--- .../architecture/ArchitectureConstants.cs | 21 +++++ .../architecture/ArchitecturePhase.cs | 61 +++++++++++++ .../architecture/IArchitectureLifecycle.cs | 15 ++++ .../architecture/IArchitectureModule.cs | 15 ++++ .../architecture/IArchitecturePhaseAware.cs | 14 +++ GFramework.Core/ioc/IocContainer.cs | 1 - .../enums/EnumExtensionsAttribute.cs | 2 +- .../architecture/AbstractArchitecture.cs | 2 +- .../architecture/ArchitectureAnchorNode.cs | 4 +- 10 files changed, 203 insertions(+), 18 deletions(-) create mode 100644 GFramework.Core/architecture/ArchitectureConstants.cs create mode 100644 GFramework.Core/architecture/ArchitecturePhase.cs create mode 100644 GFramework.Core/architecture/IArchitectureLifecycle.cs create mode 100644 GFramework.Core/architecture/IArchitectureModule.cs create mode 100644 GFramework.Core/architecture/IArchitecturePhaseAware.cs diff --git a/GFramework.Core/architecture/Architecture.cs b/GFramework.Core/architecture/Architecture.cs index 3a0816a..7344913 100644 --- a/GFramework.Core/architecture/Architecture.cs +++ b/GFramework.Core/architecture/Architecture.cs @@ -15,6 +15,41 @@ namespace GFramework.Core.architecture; /// 派生类类型,用于实现单例 public abstract class Architecture : IArchitecture where T : Architecture, new() { + public ArchitecturePhase CurrentPhase { get; private set; } + + private void EnterPhase(ArchitecturePhase next) + { + if (!ArchitectureConstants.PhaseTransitions.TryGetValue(CurrentPhase, out var allowed) || + !allowed.Contains(next)) + { + throw new InvalidOperationException( + $"Invalid phase transition: {CurrentPhase} -> {next}"); + } + + CurrentPhase = next; + NotifyPhase(next); + foreach (var obj in _mContainer.GetAll()) + { + obj.OnArchitecturePhase(next); + } + } + + private readonly List _lifecycleHooks = []; + + public void RegisterLifecycleHook(IArchitectureLifecycle hook) + { + if (CurrentPhase >= ArchitecturePhase.Ready) + throw new InvalidOperationException( + "Cannot register lifecycle hook after architecture is Ready"); + _lifecycleHooks.Add(hook); + } + + private void NotifyPhase(ArchitecturePhase phase) + { + foreach (var hook in _lifecycleHooks) + hook.OnPhase(phase, this); + } + /// /// 静态只读字段,用于延迟初始化架构实例 /// 使用Lazy确保线程安全的单例模式实现 @@ -31,23 +66,34 @@ public abstract class Architecture : IArchitecture where T : Architecture, private static readonly Lazy MArchitectureLazy = new(() => { var arch = new T(); + // == Architecture Init == + arch.EnterPhase(ArchitecturePhase.Created); + arch.EnterPhase(ArchitecturePhase.BeforeInit); // 调用用户实现的初始化 arch.Init(); + arch.EnterPhase(ArchitecturePhase.AfterInit); - // 执行注册的补丁逻辑 - OnRegisterPatch(arch); + // == Model Init == + arch.EnterPhase(ArchitecturePhase.BeforeModelInit); // 初始化所有已注册但尚未初始化的模型 foreach (var model in arch._mModels) model.Init(); - arch._mModels.Clear(); + arch.EnterPhase(ArchitecturePhase.AfterModelInit); + + // == System Init == + arch.EnterPhase(ArchitecturePhase.BeforeSystemInit); // 初始化所有已注册但尚未初始化的系统 foreach (var system in arch._mSystems) system.Init(); - arch._mSystems.Clear(); + arch.EnterPhase(ArchitecturePhase.AfterSystemInit); + + + // == Finalize == // 冻结IOC容器,不允许 anymore arch._mContainer.Freeze(); + arch.EnterPhase(ArchitecturePhase.Ready); // 发送架构初始化完成事件 arch.SendEvent(new ArchitectureEvents.ArchitectureInitializedEvent()); arch._mInited = true; @@ -68,7 +114,7 @@ public abstract class Architecture : IArchitecture where T : Architecture, /// 存储尚未初始化的系统集合,在初始化阶段统一调用Init方法 /// private readonly HashSet _mSystems = []; - + private readonly HashSet _allSystems = []; /// @@ -81,12 +127,6 @@ public abstract class Architecture : IArchitecture where T : Architecture, /// private bool _mInited; - /// - /// 注册补丁委托,允许在架构创建后执行额外逻辑 - /// - public static Action OnRegisterPatch { get; set; } = _ => { }; - - /// /// 获取架构实例的静态属性 /// @@ -102,6 +142,9 @@ public abstract class Architecture : IArchitecture where T : Architecture, /// 要注册的系统实例 public void RegisterSystem(TSystem system) where TSystem : ISystem { + if (CurrentPhase >= ArchitecturePhase.Ready) + throw new InvalidOperationException( + $"Cannot register system after Architecture is Ready"); system.SetArchitecture(this); _mContainer.RegisterPlurality(system); _allSystems.Add(system); @@ -119,6 +162,9 @@ public abstract class Architecture : IArchitecture where T : Architecture, /// 要注册的模型实例 public void RegisterModel(TModel model) where TModel : IModel { + if (CurrentPhase >= ArchitecturePhase.Ready) + throw new InvalidOperationException( + $"Cannot register system after Architecture is Ready"); model.SetArchitecture(this); _mContainer.RegisterPlurality(model); @@ -246,12 +292,17 @@ public abstract class Architecture : IArchitecture where T : Architecture, /// public void Destroy() { - // 销毁所有已注册的系统 + if (CurrentPhase >= ArchitecturePhase.Destroying) + return; + + EnterPhase(ArchitecturePhase.Destroying); + foreach (var system in _allSystems) - { system.Destroy(); - } + _allSystems.Clear(); + + EnterPhase(ArchitecturePhase.Destroyed); } @@ -293,4 +344,11 @@ public abstract class Architecture : IArchitecture where T : Architecture, query.SetArchitecture(this); return query.Do(); } + + public void InstallModule(IArchitectureModule module) + { + RegisterLifecycleHook(module); + _mContainer.RegisterPlurality(module); + module.Install(this); + } } \ No newline at end of file diff --git a/GFramework.Core/architecture/ArchitectureConstants.cs b/GFramework.Core/architecture/ArchitectureConstants.cs new file mode 100644 index 0000000..735ba1a --- /dev/null +++ b/GFramework.Core/architecture/ArchitectureConstants.cs @@ -0,0 +1,21 @@ + +using System.Collections.Immutable; + +namespace GFramework.Core.architecture; + +public static class ArchitectureConstants +{ + public static readonly ImmutableDictionary PhaseTransitions = + new Dictionary + { + { ArchitecturePhase.Created, [ArchitecturePhase.BeforeInit] }, + { ArchitecturePhase.BeforeInit, [ArchitecturePhase.AfterInit] }, + { ArchitecturePhase.AfterInit, [ArchitecturePhase.BeforeModelInit] }, + { ArchitecturePhase.BeforeModelInit, [ArchitecturePhase.AfterModelInit] }, + { ArchitecturePhase.AfterModelInit, [ArchitecturePhase.BeforeSystemInit] }, + { ArchitecturePhase.BeforeSystemInit, [ArchitecturePhase.AfterSystemInit] }, + { ArchitecturePhase.AfterSystemInit, [ArchitecturePhase.Ready] }, + { ArchitecturePhase.Ready, [ArchitecturePhase.Destroying] }, + { ArchitecturePhase.Destroying, [ArchitecturePhase.Destroyed] } + }.ToImmutableDictionary(); +} \ No newline at end of file diff --git a/GFramework.Core/architecture/ArchitecturePhase.cs b/GFramework.Core/architecture/ArchitecturePhase.cs new file mode 100644 index 0000000..fa7988e --- /dev/null +++ b/GFramework.Core/architecture/ArchitecturePhase.cs @@ -0,0 +1,61 @@ +namespace GFramework.Core.architecture; + +/// +/// 架构阶段枚举,定义了系统架构初始化和运行过程中的各个关键阶段 +/// +/// +/// 该枚举用于标记和控制系统架构组件的生命周期,确保在正确的时机执行相应的初始化和处理逻辑。 +/// 各个阶段按照时间顺序排列,从创建到准备就绪的完整流程。 +/// +public enum ArchitecturePhase +{ + + /// + /// 对象创建阶段,对应 new T() 操作完成后的状态 + /// + Created, + + /// + /// 初始化之前阶段,在 Init() 方法调用之前的状态 + /// + BeforeInit, + + /// + /// 初始化之后阶段,在 Init() 方法调用之后的状态 + /// + AfterInit, + + /// + /// 模型初始化之前阶段 + /// + BeforeModelInit, + + /// + /// 模型初始化之后阶段 + /// + AfterModelInit, + + /// + /// 系统初始化之前阶段 + /// + BeforeSystemInit, + + /// + /// 系统初始化之后阶段 + /// + AfterSystemInit, + + /// + /// 就绪阶段,完成冻结和事件处理后的最终状态 + /// + Ready, + /// + /// 正在销毁中 暂时不使用 + /// + Destroying, + /// + /// 已销毁 暂时不使用 + /// + Destroyed + +} diff --git a/GFramework.Core/architecture/IArchitectureLifecycle.cs b/GFramework.Core/architecture/IArchitectureLifecycle.cs new file mode 100644 index 0000000..2d88f90 --- /dev/null +++ b/GFramework.Core/architecture/IArchitectureLifecycle.cs @@ -0,0 +1,15 @@ +namespace GFramework.Core.architecture; + +/// +/// 架构生命周期接口,定义了架构在不同阶段的回调方法 +/// +public interface IArchitectureLifecycle +{ + /// + /// 当架构进入指定阶段时触发的回调方法 + /// + /// 当前的架构阶段 + /// 相关的架构实例 + void OnPhase(ArchitecturePhase phase, IArchitecture arch); +} + diff --git a/GFramework.Core/architecture/IArchitectureModule.cs b/GFramework.Core/architecture/IArchitectureModule.cs new file mode 100644 index 0000000..8c2bc4c --- /dev/null +++ b/GFramework.Core/architecture/IArchitectureModule.cs @@ -0,0 +1,15 @@ + +namespace GFramework.Core.architecture; + +/// +/// 架构模块接口,继承自架构生命周期接口。 +/// 定义了模块安装到架构中的标准方法。 +/// +public interface IArchitectureModule : IArchitectureLifecycle, IArchitecturePhaseAware +{ + /// + /// 将当前模块安装到指定的架构中。 + /// + /// 要安装模块的目标架构实例。 + void Install(IArchitecture architecture); +} diff --git a/GFramework.Core/architecture/IArchitecturePhaseAware.cs b/GFramework.Core/architecture/IArchitecturePhaseAware.cs new file mode 100644 index 0000000..42467e6 --- /dev/null +++ b/GFramework.Core/architecture/IArchitecturePhaseAware.cs @@ -0,0 +1,14 @@ +namespace GFramework.Core.architecture; + +/// +/// 定义架构阶段感知接口,用于在架构的不同阶段执行相应的逻辑 +/// +public interface IArchitecturePhaseAware +{ + /// + /// 当架构进入指定阶段时触发的回调方法 + /// + /// 架构阶段枚举值,表示当前所处的架构阶段 + void OnArchitecturePhase(ArchitecturePhase phase); +} + diff --git a/GFramework.Core/ioc/IocContainer.cs b/GFramework.Core/ioc/IocContainer.cs index 1d32fe9..8926d96 100644 --- a/GFramework.Core/ioc/IocContainer.cs +++ b/GFramework.Core/ioc/IocContainer.cs @@ -229,7 +229,6 @@ public class IocContainer }; } - /// /// 获取指定类型的所有实例(接口 / 抽象类推荐使用) /// diff --git a/GFramework.Generator.Attributes/generator/enums/EnumExtensionsAttribute.cs b/GFramework.Generator.Attributes/generator/enums/EnumExtensionsAttribute.cs index b62031d..c3c90a7 100644 --- a/GFramework.Generator.Attributes/generator/enums/EnumExtensionsAttribute.cs +++ b/GFramework.Generator.Attributes/generator/enums/EnumExtensionsAttribute.cs @@ -1,6 +1,6 @@ using System; -namespace GFramework.Generator.Attributes +namespace GFramework.Generator.Attributes.generator.enums { /// /// 标注在 enum 上,Source Generator 会为该 enum 生成扩展方法。 diff --git a/GFramework.Godot/architecture/AbstractArchitecture.cs b/GFramework.Godot/architecture/AbstractArchitecture.cs index 80bfc21..9c26d27 100644 --- a/GFramework.Godot/architecture/AbstractArchitecture.cs +++ b/GFramework.Godot/architecture/AbstractArchitecture.cs @@ -9,7 +9,7 @@ namespace GFramework.Godot.architecture; /// 架构的具体类型,必须继承自Architecture且能被实例化 public abstract class AbstractArchitecture : Architecture where T : Architecture, new() { - private const string ArchitectureName = "__GFrameworkArchitectureAnchor"; + private const string ArchitectureName = "__GFramework__Architecture__Anchor"; /// /// 初始化架构,按顺序注册模型、系统和工具 /// diff --git a/GFramework.Godot/architecture/ArchitectureAnchorNode.cs b/GFramework.Godot/architecture/ArchitectureAnchorNode.cs index 0a9037d..59e739c 100644 --- a/GFramework.Godot/architecture/ArchitectureAnchorNode.cs +++ b/GFramework.Godot/architecture/ArchitectureAnchorNode.cs @@ -18,14 +18,16 @@ public partial class ArchitectureAnchorNode : Node { _onExit = onExit; } - + /// /// 当节点从场景树中移除时调用此方法 /// 执行绑定的退出回调并清理引用 /// public override void _ExitTree() { + // 执行退出回调 _onExit?.Invoke(); + // 清理引用 _onExit = null; } }