diff --git a/GFramework.Core/architecture/Architecture.cs b/GFramework.Core/architecture/Architecture.cs index 885a916..4eb7e1a 100644 --- a/GFramework.Core/architecture/Architecture.cs +++ b/GFramework.Core/architecture/Architecture.cs @@ -13,8 +13,22 @@ namespace GFramework.Core.architecture; /// 使用单例模式确保全局唯一实例,并支持命令、查询和事件机制。 /// /// 派生类类型,用于实现单例 -public abstract class Architecture : IArchitecture where T : Architecture, new() +public abstract class Architecture : IArchitecture + where T : Architecture, new() { + /// + /// 获取架构选项的虚拟属性 + /// + /// 返回IArchitectureOptions接口实例,包含架构配置选项 + /// + /// 默认实现返回FunctionalArchitectureOptions实例,其中包含两个委托: + /// 第一个委托始终返回true,第二个委托始终返回false + /// + protected virtual IArchitectureOptions Options { get; } = new FunctionalArchitectureOptions( + () => true, + () => false + ); + #region Fields and Properties /// @@ -57,7 +71,7 @@ public abstract class Architecture : IArchitecture where T : Architecture, /// 生命周期感知对象列表 /// private readonly List _lifecycleHooks = []; - + /// /// 当前架构的阶段 /// @@ -124,17 +138,18 @@ public abstract class Architecture : IArchitecture where T : Architecture, /// 当阶段转换不被允许时抛出异常 private void EnterPhase(ArchitecturePhase next) { - // 验证阶段转换是否合法 - if (!ArchitectureConstants.PhaseTransitions.TryGetValue(CurrentPhase, out var allowed) || - !allowed.Contains(next)) + if (Options.StrictPhaseValidation && + (!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()) { @@ -158,7 +173,7 @@ public abstract class Architecture : IArchitecture where T : Architecture, /// 生命周期钩子实例 public void RegisterLifecycleHook(IArchitectureLifecycle hook) { - if (CurrentPhase >= ArchitecturePhase.Ready) + if (CurrentPhase >= ArchitecturePhase.Ready && !Options.AllowLateRegistration) throw new InvalidOperationException( "Cannot register lifecycle hook after architecture is Ready"); _lifecycleHooks.Add(hook); @@ -186,7 +201,7 @@ public abstract class Architecture : IArchitecture where T : Architecture, // 进入销毁阶段并发送销毁开始事件 EnterPhase(ArchitecturePhase.Destroying); SendEvent(new ArchitectureEvents.ArchitectureDestroyingEvent()); - + // 销毁所有系统组件并清空系统列表 foreach (var system in _allSystems) system.Destroy(); @@ -225,9 +240,9 @@ public abstract class Architecture : IArchitecture where T : Architecture, /// 要注册的系统实例 public void RegisterSystem(TSystem system) where TSystem : ISystem { - if (CurrentPhase >= ArchitecturePhase.Ready) + if (CurrentPhase >= ArchitecturePhase.Ready && !Options.AllowLateRegistration) throw new InvalidOperationException( - $"Cannot register system after Architecture is Ready"); + "Cannot register system after Architecture is Ready"); system.SetArchitecture(this); _mContainer.RegisterPlurality(system); _allSystems.Add(system); @@ -245,9 +260,9 @@ public abstract class Architecture : IArchitecture where T : Architecture, /// 要注册的模型实例 public void RegisterModel(TModel model) where TModel : IModel { - if (CurrentPhase >= ArchitecturePhase.Ready) + if (CurrentPhase >= ArchitecturePhase.Ready && !Options.AllowLateRegistration) throw new InvalidOperationException( - $"Cannot register system after Architecture is Ready"); + "Cannot register system after Architecture is Ready"); model.SetArchitecture(this); _mContainer.RegisterPlurality(model); diff --git a/GFramework.Core/architecture/ArchitectureOptionsDelegates.cs b/GFramework.Core/architecture/ArchitectureOptionsDelegates.cs new file mode 100644 index 0000000..b115f5b --- /dev/null +++ b/GFramework.Core/architecture/ArchitectureOptionsDelegates.cs @@ -0,0 +1,17 @@ + +namespace GFramework.Core.architecture; + +public class ArchitectureOptionsDelegates +{ + /// + /// 架构可配置选项委托 + /// + /// 是否严格验证阶段转换 + public delegate bool StrictPhaseValidationDelegate(); + + /// + /// 架构可配置选项委托 + /// + /// 是否允许在 Ready 阶段后注册系统/模型 + public delegate bool AllowLateRegistrationDelegate(); +} \ No newline at end of file diff --git a/GFramework.Core/architecture/FunctionalArchitectureOptions.cs b/GFramework.Core/architecture/FunctionalArchitectureOptions.cs new file mode 100644 index 0000000..e27b4cf --- /dev/null +++ b/GFramework.Core/architecture/FunctionalArchitectureOptions.cs @@ -0,0 +1,26 @@ +namespace GFramework.Core.architecture; + +/// +/// 函数式架构选项实现,支持匿名实现 +/// +public class FunctionalArchitectureOptions(Func strictPhaseValidation, Func allowLateRegistration) + : IArchitectureOptions +{ + /// + /// 初始化 FunctionalArchitectureOptions 类的新实例 + /// + /// 用于确定是否启用严格阶段验证的函数 + /// 用于确定是否允许延迟注册的函数 + private readonly Func _strictPhaseValidation = strictPhaseValidation ?? throw new ArgumentNullException(nameof(strictPhaseValidation)); + private readonly Func _allowLateRegistration = allowLateRegistration ?? throw new ArgumentNullException(nameof(allowLateRegistration)); + + /// + /// 获取一个值,该值指示是否启用严格阶段验证 + /// + public bool StrictPhaseValidation => _strictPhaseValidation(); + + /// + /// 获取一个值,该值指示是否允许延迟注册 + /// + public bool AllowLateRegistration => _allowLateRegistration(); +} diff --git a/GFramework.Core/architecture/IArchitectureOptions.cs b/GFramework.Core/architecture/IArchitectureOptions.cs new file mode 100644 index 0000000..3226b70 --- /dev/null +++ b/GFramework.Core/architecture/IArchitectureOptions.cs @@ -0,0 +1,17 @@ +namespace GFramework.Core.architecture; + +/// +/// 架构可配置选项接口 +/// +public interface IArchitectureOptions +{ + /// + /// 是否严格验证阶段转换 + /// + bool StrictPhaseValidation { get; } + + /// + /// 是否允许在 Ready 阶段后注册系统/模型 + /// + bool AllowLateRegistration { get; } +} \ No newline at end of file diff --git a/GFramework.Godot/architecture/AbstractArchitecture.cs b/GFramework.Godot/architecture/AbstractArchitecture.cs index c659fb8..bd88d30 100644 --- a/GFramework.Godot/architecture/AbstractArchitecture.cs +++ b/GFramework.Godot/architecture/AbstractArchitecture.cs @@ -11,6 +11,7 @@ namespace GFramework.Godot.architecture; /// 架构的具体类型,必须继承自Architecture且能被实例化。 public abstract class AbstractArchitecture : Architecture where T : Architecture, new() { + /// /// 架构锚点节点的唯一标识名称 /// 用于在Godot场景树中创建和查找架构锚点节点