docs(core): 更新文档说明架构与平台无关性及新特性

- 更新 Architecture 包文档,强调与 Godot 解耦设计
- 修改 IArchitecture 接口方法参数命名规范
- 添加架构阶段感知接口 IArchitecturePhaseAware 说明
- 补充架构模块接口 IArchitectureModule 和异步初始化接口说明
- 更新架构初始化流程描述,增加模块安装系统介绍
- 修订使用示例,展示依赖注入而非单例访问模式
- 更新 Logging 包文档结构,重新组织核心接口和类说明
- 添加日志工厂提供程序和解析器使用说明
- 修正 Property 包文档中的比较器使用说明
- 更新主 README 强调平台无关性和模块化设计
- 修订架构图和数据流向说明,体现阶段式生命周期管理
- [skip ci]
This commit is contained in:
GeWuYou 2026-01-10 12:45:12 +08:00
parent 8c8555985d
commit 4c5e3e01a3
7 changed files with 1528 additions and 1320 deletions

View File

@ -0,0 +1,521 @@
# GFramework.Core.Abstractions 抽象层
> GFramework 框架的接口定义模块,提供所有核心组件的抽象契约
## 概述
GFramework.Core.Abstractions 是 GFramework 框架的抽象层定义模块包含了框架中所有核心组件的接口Interface、枚举Enum和配置类Class。该模块采用
`netstandard2.0` 作为目标框架,确保了广泛的兼容性和可移植性。
本模块遵循以下设计原则:
- **接口隔离**:每个接口职责单一,便于实现和测试
- **依赖倒置**:上层模块依赖抽象接口,而非具体实现
- **组合优于继承**:通过接口组合获得能力,而非通过继承获得
- **类型安全**:充分利用泛型系统确保类型安全
本模块的包 ID 为 `GeWuYou.GFramework.Core.Abstractions`,遵循命名空间 `GFramework.Core.Abstractions` 下的所有定义。
## 目录结构
```
GFramework.Core.Abstractions/
├── architecture/ # 架构核心接口
│ ├── IArchitecture.cs
│ ├── IArchitectureConfiguration.cs
│ ├── IArchitectureContext.cs
│ ├── IArchitectureLifecycle.cs
│ ├── IArchitectureModule.cs
│ ├── IArchitecturePhaseAware.cs
│ ├── IArchitectureServices.cs
│ └── IAsyncInitializable.cs
├── command/ # 命令模式接口
│ ├── ICommand.cs
│ ├── ICommandBus.cs
│ └── ICommandInput.cs
├── controller/ # 控制器接口
│ └── IController.cs
├── enums/ # 枚举定义
│ └── ArchitecturePhase.cs
├── environment/ # 环境接口
│ └── IEnvironment.cs
├── events/ # 事件系统接口
│ ├── IEasyEvent.cs
│ ├── ITypeEventSystem.cs
│ ├── IUnRegister.cs
│ └── IUnRegisterList.cs
├── ioc/ # 依赖注入容器接口
│ └── IIocContainer.cs
├── logging/ # 日志系统接口
│ ├── ILogger.cs
│ ├── ILoggerFactory.cs
│ ├── ILoggerFactoryProvider.cs
│ └── LogLevel.cs
├── model/ # 模型接口
│ └── IModel.cs
├── properties/ # 配置类
│ ├── ArchitectureProperties.cs
│ └── LoggerProperties.cs
├── property/ # 可绑定属性接口
│ ├── IBindableProperty.cs
│ └── IReadonlyBindableProperty.cs
├── query/ # 查询模式接口
│ ├── IQuery.cs
│ ├── IQueryBus.cs
│ └── IQueryInput.cs
├── rule/ # 规则接口
│ ├── IContextAware.cs
│ └── ILogAware.cs
├── system/ # 系统接口
│ └── ISystem.cs
└── utility/ # 工具接口
├── IContextUtility.cs
└── IUtility.cs
```
## 模块说明
### 1. architecture架构核心
架构模块是整个框架的核心,定义了应用架构的生命周期管理和组件注册机制。该模块包含以下接口:
#### [`IArchitecture`](architecture/IArchitecture.cs)
架构接口是整个应用的核心管理器,负责管理系统、模型和工具类的注册与获取。它继承自 [
`IAsyncInitializable`](architecture/IAsyncInitializable.cs) 接口,支持异步初始化。该接口提供了注册系统([
`RegisterSystem<T>`](architecture/IArchitecture.cs#L39))、注册模型([
`RegisterModel<T>`](architecture/IArchitecture.cs#L46))、注册工具([
`RegisterUtility<T>`](architecture/IArchitecture.cs#L53))的方法,以及安装模块([
`InstallModule`](architecture/IArchitecture.cs#L59))和注册生命周期钩子([
`RegisterLifecycleHook`](architecture/IArchitecture.cs#L65))的功能。
#### [`IArchitectureContext`](architecture/IArchitectureContext.cs)
架构上下文接口提供了对已注册组件的访问能力,是组件之间通信的桥梁。通过该接口,可以获取系统([
`GetSystem<TSystem>`](architecture/IArchitectureContext.cs#L22))、模型([
`GetModel<TModel>`](architecture/IArchitectureContext.cs#L29))和工具([
`GetUtility<TUtility>`](architecture/IArchitectureContext.cs#L36))实例。同时,该接口还支持发送命令([
`SendCommand`](architecture/IArchitectureContext.cs#L42))、发送查询([
`SendQuery`](architecture/IArchitectureContext.cs#L58))和发送事件([
`SendEvent`](architecture/IArchitectureContext.cs#L64))等横切操作。
#### [`IArchitectureConfiguration`](architecture/IArchitectureConfiguration.cs)
架构配置接口定义了框架的配置选项,包括日志配置([`LoggerProperties`](architecture/IArchitectureConfiguration.cs#L13)
)和架构配置([`ArchitectureProperties`](architecture/IArchitectureConfiguration.cs#L18)
)。通过该接口,可以在运行时调整框架的行为,如设置日志级别、启用延迟注册等。
#### [`IArchitectureLifecycle`](architecture/IArchitectureLifecycle.cs)
架构生命周期接口定义了架构在不同阶段的回调方法。当架构进入特定阶段时,会通知所有注册的生命周期监听器。该接口主要用于模块化架构的阶段感知。
#### [`IArchitectureModule`](architecture/IArchitectureModule.cs)
架构模块接口继承自 [`IArchitectureLifecycle`](architecture/IArchitectureLifecycle.cs) 和 [
`IArchitecturePhaseAware`](architecture/IArchitecturePhaseAware.cs) 接口,定义了模块安装到架构的标准方法([
`Install`](architecture/IArchitectureModule.cs#L13))。通过模块化机制,可以将复杂功能封装为可插拔的模块。
#### [`IArchitecturePhaseAware`](architecture/IArchitecturePhaseAware.cs)
架构阶段感知接口允许组件在架构的不同阶段执行相应的逻辑。该接口提供了 [
`OnArchitecturePhase`](architecture/IArchitecturePhaseAware.cs#L14) 方法,当架构进入指定阶段时会被调用。
#### [`IArchitectureServices`](architecture/IArchitectureServices.cs)
架构服务接口定义了框架核心服务组件,继承自 [`IContextAware`](rule/IContextAware.cs) 接口。该接口提供了依赖注入容器([
`Container`](architecture/IArchitectureServices.cs#L18))、类型事件系统([
`TypeEventSystem`](architecture/IArchitectureServices.cs#L24))、命令总线([
`CommandBus`](architecture/IArchitectureServices.cs#L29))和查询总线([
`QueryBus`](architecture/IArchitectureServices.cs#L34))的访问能力。
#### [`IAsyncInitializable`](architecture/IAsyncInitializable.cs)
异步初始化接口定义了组件的异步初始化方法([`InitializeAsync`](architecture/IAsyncInitializable.cs#L14)
)。该接口用于需要执行异步初始化操作的组件,如加载资源、建立网络连接等。
### 2. command命令模式
命令模块实现了命令查询职责分离模式CQRS中的命令部分用于封装写操作。该模块包含以下接口
#### [`ICommand`](command/ICommand.cs)
命令接口定义了无返回值命令的基本契约,继承自 [`IContextAware`](rule/IContextAware.cs) 接口。该接口提供了命令执行方法([
`Execute`](command/ICommand.cs#L15)),用于执行具体的业务逻辑。带返回值的命令由泛型接口 [
`ICommand<TResult>`](command/ICommand.cs#L23) 定义,同样继承自 [`IContextAware`](rule/IContextAware.cs) 接口。
#### [`ICommandBus`](command/ICommandBus.cs)
命令总线接口负责命令的发送和执行调度。该接口提供了发送无返回值命令([`Send`](command/ICommandBus.cs#L12)
)和发送带返回值命令([`Send<TResult>`](command/ICommandBus.cs#L20))的方法。
#### [`ICommandInput`](command/ICommandInput.cs)
命令输入接口是命令模式中输入数据的标记接口,不包含任何成员定义。该接口用于规范化命令的输入参数类型。
### 3. controller控制器
控制器模块定义了表现层与业务逻辑层之间的桥梁接口。
#### [`IController`](controller/IController.cs)
控制器接口是 MVC 架构中控制层的抽象定义。该接口作为标记接口使用,不包含任何方法定义,但实现该接口的类通常会获得访问架构上下文的能力,从而可以发送命令、查询数据、注册事件等。
### 4. enums枚举定义
枚举模块定义了框架中使用的枚举类型。
#### [`ArchitecturePhase`](enums/ArchitecturePhase.cs)
架构阶段枚举定义了系统架构初始化和运行过程中的各个关键阶段。按照初始化流程,依次包括:`None`(无效阶段)、`BeforeUtilityInit`
(工具类初始化之前)、`AfterUtilityInit`(工具类初始化之后)、`BeforeModelInit`(模型初始化之前)、`AfterModelInit`(模型初始化之后)、
`BeforeSystemInit`(系统初始化之前)、`AfterSystemInit`(系统初始化之后)、`Ready`(就绪阶段),以及销毁相关阶段:`Destroying`
(正在销毁中)、`Destroyed`(已销毁)、`FailedInitialization`(初始化失败)。
### 5. environment环境接口
环境模块定义了应用程序运行环境的抽象接口。
#### [`IEnvironment`](environment/IEnvironment.cs)
环境接口提供了获取应用程序运行环境相关信息的能力。该接口支持根据键值获取配置值([
`Get<T>`](environment/IEnvironment.cs#L20))、尝试获取环境值([`TryGet`](environment/IEnvironment.cs#L29)
)、获取必需的环境值([`GetRequired<T>`](environment/IEnvironment.cs#L37)),以及注册键值对([
`Register`](environment/IEnvironment.cs#L44))和初始化环境([`Initialize`](environment/IEnvironment.cs#L49))。
### 6. events事件系统
事件模块实现了框架的事件驱动通信机制,支持类型安全和松耦合的组件通信。
#### [`ITypeEventSystem`](events/ITypeEventSystem.cs)
类型事件系统接口是基于类型的事件发布-订阅机制的抽象定义。该接口支持发送无参事件([
`Send<T>`](events/ITypeEventSystem.cs#L14))、发送带参事件([`Send<T>`](events/ITypeEventSystem.cs#L21))、注册事件监听器([
`Register<T>`](events/ITypeEventSystem.cs#L29))和注销事件监听器([`UnRegister<T>`](events/ITypeEventSystem.cs#L36))。
#### [`IEasyEvent`](events/IEasyEvent.cs)
简单事件接口定义了基础的事件注册功能([`Register`](events/IEasyEvent.cs#L15))。该接口用于简单的无参事件场景。
#### [`IUnRegister`](events/IUnRegister.cs)
注销接口提供了事件监听器的注销功能([`UnRegister`](events/IUnRegister.cs#L11))。所有事件注册方法的返回值都实现了该接口,用于在适当时机取消事件监听。
#### [`IUnRegisterList`](events/IUnRegisterList.cs)
统一注销接口提供了管理多个注销句柄的能力。该接口维护了一个注销对象列表([`UnregisterList`](events/IUnRegisterList.cs#L13)
),可以在批量注销时统一处理。
### 7. ioc依赖注入
IoC 模块实现了控制反转和依赖注入机制,用于管理组件的生命周期和依赖关系。
#### [`IIocContainer`](ioc/IIocContainer.cs)
依赖注入容器接口是框架的核心服务接口之一,继承自 [`IContextAware`](rule/IContextAware.cs)
接口。该接口提供了丰富的服务注册和解析方法,包括注册单例([`RegisterSingleton<T>`](ioc/IIocContainer.cs#L22)
)、注册多个实例([`RegisterPlurality`](ioc/IIocContainer.cs#L30))、注册系统([`RegisterSystem`](ioc/IIocContainer.cs#L36)
)、注册类型([`Register`](ioc/IIocContainer.cs#L43))等。在解析方面,支持获取单个实例([`Get<T>`](ioc/IIocContainer.cs#L62)
)、获取必需实例([`GetRequired<T>`](ioc/IIocContainer.cs#L70))、获取所有实例([`GetAll<T>`](ioc/IIocContainer.cs#L77)
)和获取排序后的实例([`GetAllSorted<T>`](ioc/IIocContainer.cs#L85))。此外,还提供了检查([
`Contains`](ioc/IIocContainer.cs#L96))、清空([`Clear`](ioc/IIocContainer.cs#L108))和冻结([
`Freeze`](ioc/IIocContainer.cs#L113))等实用方法。
### 8. logging日志系统
日志模块提供了完整的日志记录抽象,支持多级别日志输出。
#### [`LogLevel`](logging/LogLevel.cs)
日志级别枚举定义了日志消息的严重程度等级,包括:`Trace`(跟踪级别,用于详细的程序执行流程信息)、`Debug`(调试级别,用于调试过程中的详细信息)、
`Info`(信息级别,用于一般性的程序运行信息)、`Warning`(警告级别,用于表示可能的问题或异常情况)、`Error`
(错误级别,用于表示错误但程序仍可继续运行的情况)、`Fatal`(致命级别,用于表示严重的错误导致程序无法继续运行)。
#### [`ILogger`](logging/ILogger.cs)
日志记录器接口是框架日志系统的核心接口,提供了完整的日志记录能力。该接口支持以下功能:
- **级别启用检查**:提供了各个日志级别的是否启用检查方法,如 [`IsTraceEnabled`](logging/ILogger.cs#L22)、[
`IsDebugEnabled`](logging/ILogger.cs#L28)、[`IsInfoEnabled`](logging/ILogger.cs#L34)、[
`IsWarnEnabled`](logging/ILogger.cs#L40)、[`IsErrorEnabled`](logging/ILogger.cs#L46)、[
`IsFatalEnabled`](logging/ILogger.cs#L52),以及通用的 [`IsEnabledForLevel`](logging/ILogger.cs#L59) 方法。
- **日志记录方法**:每个日志级别都有多种重载形式,支持简单消息、格式化消息和异常记录。格式化为 `Trace``Debug``Info`
`Warn``Error``Fatal` 六个级别,每个级别都提供了 `msg``format+arg``format+arg1+arg2``format+params``msg+exception`
等多种调用方式。
- **获取日志记录器名称**:通过 [`Name`](logging/ILogger.cs#L14) 方法获取日志记录器的名称。
#### [`ILoggerFactory`](logging/ILoggerFactory.cs)
日志工厂接口用于创建日志记录器实例([`GetLogger`](logging/ILoggerFactory.cs#L14))。该接口支持指定日志记录器名称和最小日志级别。
#### [`ILoggerFactoryProvider`](logging/ILoggerFactoryProvider.cs)
日志工厂提供者接口扩展了日志工厂的功能,支持动态设置最小日志级别([`MinLevel`](logging/ILoggerFactoryProvider.cs#L11)
)和创建日志记录器([`CreateLogger`](logging/ILoggerFactoryProvider.cs#L18))。
### 9. model模型接口
模型模块定义了数据层的抽象接口。
#### [`IModel`](model/IModel.cs)
模型接口继承自 [`IContextAware`](rule/IContextAware.cs) 和 [
`IArchitecturePhaseAware`](architecture/IArchitecturePhaseAware.cs)
接口,定义了模型组件的基本行为。该接口提供了模型初始化方法([`Init`](model/IModel.cs#L14)),用于执行模型相关的初始化逻辑。
### 10. properties配置类
配置模块定义了框架使用的配置选项类。
#### [`LoggerProperties`](properties/LoggerProperties.cs)
日志配置选项类用于配置日志系统的相关参数,包含日志工厂提供程序属性([
`LoggerFactoryProvider`](properties/LoggerProperties.cs#L14))。
#### [`ArchitectureProperties`](properties/ArchitectureProperties.cs)
架构选项配置类用于定义架构行为的相关配置选项,包含两个属性:`AllowLateRegistration`(允许延迟注册开关,控制是否允许在初始化完成后进行组件注册)和
`StrictPhaseValidation`(严格阶段验证开关,控制是否启用严格的阶段验证机制)。
### 11. property可绑定属性
可绑定属性模块实现了响应式数据绑定机制,支持数据变化的自动通知。
#### [`IReadonlyBindableProperty<T>`](property/IReadonlyBindableProperty.cs)
只读可绑定属性接口继承自 [`IEasyEvent`](events/IEasyEvent.cs)
接口,提供了属性值的读取和变更监听功能。该接口支持获取当前值([`Value`](property/IReadonlyBindableProperty.cs#L15)
)、注册带初始值的回调([`RegisterWithInitValue`](property/IReadonlyBindableProperty.cs#L22))、取消注册回调([
`UnRegister`](property/IReadonlyBindableProperty.cs#L28))和注册回调([
`Register`](property/IReadonlyBindableProperty.cs#L35))。
#### [`IBindableProperty<T>`](property/IBindableProperty.cs)
可绑定属性接口继承自只读可绑定属性接口,提供了可读写的属性绑定功能。该接口在只读接口的基础上增加了属性值的设置能力([
`Value`](property/IBindableProperty.cs#L12) 的 setter以及不触发事件的设置方法[
`SetValueWithoutEvent`](property/IBindableProperty.cs#L18))。
### 12. query查询模式
查询模块实现了命令查询职责分离模式CQRS中的查询部分用于封装读操作。
#### [`IQuery<TResult>`](query/IQuery.cs)
查询接口继承自 [`IContextAware`](rule/IContextAware.cs) 接口,定义了执行查询操作的契约。该接口提供了查询执行方法([
`Do`](query/IQuery.cs#L15)),返回指定类型的结果。
#### [`IQueryBus`](query/IQueryBus.cs)
查询总线接口负责查询的发送和执行调度。该接口提供了发送查询并返回结果的方法([`Send<TResult>`](query/IQueryBus.cs#L14))。
#### [`IQueryInput`](query/IQueryInput.cs)
查询输入接口是查询模式中输入数据的标记接口,不包含任何成员定义。
### 13. rule规则接口
规则模块定义了框架组件需要遵循的约束和规则接口。
#### [`IContextAware`](rule/IContextAware.cs)
上下文感知接口允许实现类设置和获取架构上下文。该接口提供了设置上下文([`SetContext`](rule/IContextAware.cs#L14)
)和获取上下文([`GetContext`](rule/IContextAware.cs#L20)的方法。框架中大多数核心组件如命令、查询、系统、模型、工具、IoC
容器等)都实现了该接口,以获得访问架构服务的能力。
#### [`ILogAware`](rule/ILogAware.cs)
日志感知接口允许实现类设置和使用日志记录器。该接口提供了设置日志记录器的方法([`SetLogger`](rule/ILogAware.cs#L14))。
### 14. system系统接口
系统模块定义了业务逻辑层的抽象接口。
#### [`ISystem`](system/ISystem.cs)
系统接口继承自 [`IContextAware`](rule/IContextAware.cs) 和 [
`IArchitecturePhaseAware`](architecture/IArchitecturePhaseAware.cs)
接口,定义了系统组件的基本行为。该接口提供了系统初始化方法([`Init`](system/ISystem.cs#L16))和系统销毁方法([
`Destroy`](system/ISystem.cs#L22)),用于管理系统的生命周期。
### 15. utility工具接口
工具模块定义了无状态工具类的抽象接口。
#### [`IUtility`](utility/IUtility.cs)
工具接口是所有工具类实现的基础接口,作为标记接口使用,不包含任何成员定义。该接口定义了通用工具类的基本契约。
#### [`IContextUtility`](utility/IContextUtility.cs)
上下文工具接口继承自 [`IUtility`](utility/IUtility.cs) 和 [`IContextAware`](rule/IContextAware.cs)
接口,提供了具有上下文感知能力的工具功能。该接口在工具接口的基础上增加了初始化方法([
`Init`](utility/IContextUtility.cs#L14))。
## 接口继承关系图
```
IArchitecture
└── IAsyncInitializable
IArchitectureModule
├── IArchitectureLifecycle
└── IArchitecturePhaseAware
IArchitectureServices
└── IContextAware
ICommand
└── IContextAware
ICommand<TResult>
└── IContextAware
IIocContainer
└── IContextAware
IQuery<TResult>
└── IContextAware
IModel
├── IContextAware
└── IArchitecturePhaseAware
ISystem
├── IContextAware
└── IArchitecturePhaseAware
IContextUtility
├── IUtility
└── IContextAware
IReadonlyBindableProperty<T>
└── IEasyEvent
IBindableProperty<T>
└── IReadonlyBindableProperty<T>
```
## 核心能力接口
框架中的组件通过实现特定的接口来获得相应的能力。这些能力接口主要分为以下几类:
### 上下文感知能力
通过实现 [`IContextAware`](rule/IContextAware.cs) 接口组件可以获得设置和获取架构上下文的能力从而访问框架提供的各种服务。命令、查询、系统、模型、工具、IoC
容器等核心组件都实现了该接口。
### 日志能力
通过实现 [`ILogAware`](rule/ILogAware.cs) 接口,组件可以获得使用日志记录器的能力。该接口提供了设置日志记录器的方法,使组件可以输出日志信息。
### 阶段感知能力
通过实现 [`IArchitecturePhaseAware`](architecture/IArchitecturePhaseAware.cs)
接口,组件可以在架构的不同阶段执行相应的逻辑。该接口提供了 [
`OnArchitecturePhase`](architecture/IArchitecturePhaseAware.cs#L14) 方法,当架构进入指定阶段时会被调用。
## 使用指南
### 实现框架组件
当需要实现框架的组件时,通常需要实现相应的接口并遵循框架的生命周期约定:
```csharp
// 实现系统组件
public class CombatSystem : ISystem
{
public void Init()
{
// 系统初始化逻辑
}
public void Destroy()
{
// 系统销毁逻辑
}
}
// 实现模型组件
public class PlayerModel : IModel
{
public void Init()
{
// 模型初始化逻辑
}
}
// 实现工具组件
public class StorageUtility : IUtility
{
// 工具类方法
}
// 实现命令
public class AttackCommand : ICommand
{
public void Execute()
{
// 命令执行逻辑
}
}
// 实现查询
public class GetPlayerInfoQuery : IQuery<PlayerInfo>
{
public PlayerInfo Do()
{
// 查询执行逻辑
}
}
```
### 访问框架服务
通过实现 [`IContextAware`](rule/IContextAware.cs) 接口,组件可以获得访问框架服务的能力:
```csharp
public class MySystem : ISystem
{
private IArchitectureContext _context;
public void SetContext(IArchitectureContext context)
{
_context = context;
}
public IArchitectureContext GetContext()
{
return _context;
}
private void SomeMethod()
{
// 获取其他组件
var playerModel = _context.GetModel<PlayerModel>();
// 发送命令
_context.SendCommand(new AttackCommand());
// 发送查询
var health = _context.SendQuery(new GetHealthQuery());
// 发送事件
_context.SendEvent(new GameEvent());
// 注册事件监听
_context.RegisterEvent<EnemySpawnedEvent>(OnEnemySpawned);
}
}
```
## 相关文档
- [GFramework.Core](../GFramework.Core/README.md) - 核心框架实现模块
- [GFramework.Godot](../GFramework.Godot/README.md) - Godot 平台集成模块
- [架构模块文档](architecture/README.md) - 架构接口详细说明
- [控制器模块文档](controller/README.md) - 控制器使用说明
---
**版本**: 1.0.0
**许可证**: Apache 2.0

View File

@ -2,8 +2,9 @@
## 概述 ## 概述
Controller 包定义了控制器Controller的接口规范。控制器是 MVC 架构中的 C Controller 包定义了控制器Controller的接口规范。控制器是 MVC 架构中的 C 层,负责处理用户交互、协调视图和模型,是连接表现层和业务层的桥梁。
负责处理用户交互、协调视图和模型是连接表现层和业务层的桥梁。在本框架中Controller 通常对应 Godot 的节点脚本。
**注意**本框架使用依赖注入模式Controller 通过构造函数或属性注入获取架构实例,而非使用全局单例。
## 核心接口 ## 核心接口
@ -33,51 +34,53 @@ Controller 包定义了控制器Controller的接口规范。控制器是 M
## 使用示例 ## 使用示例
### 基础控制器实现 ### 基础控制器实现(依赖注入模式)
```csharp ```csharp
using Godot; using GFramework.Core.architecture;
using GFramework.framework.controller;
using GFramework.framework.architecture;
// Godot 节点控制器 // 通过依赖注入获取架构
public partial class PlayerController : Node, IController public class PlayerController : IController
{ {
private IUnRegisterList _unregisterList = new UnRegisterList(); private readonly IArchitecture _architecture;
private readonly IUnRegisterList _unregisterList = new UnRegisterList();
// 实现架构获取 // 通过构造函数注入架构
public IArchitecture GetArchitecture() => GameArchitecture.Interface; public PlayerController(IArchitecture architecture)
{
_architecture = architecture;
}
public override void _Ready() public void Initialize()
{ {
// 获取模型 // 获取模型
var playerModel = this.GetModel<PlayerModel>(); var playerModel = _architecture.GetModel<PlayerModel>();
// 监听模型变化 // 监听模型变化
playerModel.Health.RegisterWithInitValue(OnHealthChanged) playerModel.Health.RegisterWithInitValue(OnHealthChanged)
.AddToUnregisterList(_unregisterList); .AddToUnregisterList(_unregisterList);
// 注册事件 // 注册事件
this.RegisterEvent<PlayerLevelUpEvent>(OnPlayerLevelUp) _architecture.RegisterEvent<PlayerLevelUpEvent>(OnPlayerLevelUp)
.AddToUnregisterList(_unregisterList); .AddToUnregisterList(_unregisterList);
} }
// 处理用户输入 // 处理用户输入
public override void _Process(double delta) public void ProcessInput(double delta)
{ {
if (Input.IsActionJustPressed("attack")) if (Input.IsActionJustPressed("attack"))
{ {
// 发送命令 // 发送命令
this.SendCommand(new AttackCommand()); _architecture.SendCommand(new AttackCommand());
} }
if (Input.IsActionJustPressed("use_item")) if (Input.IsActionJustPressed("use_item"))
{ {
// 发送查询 // 发送查询
var inventory = this.SendQuery(new GetInventoryQuery()); var inventory = _architecture.SendQuery(new GetInventoryQuery());
if (inventory.HasItem("potion")) if (inventory.HasItem("potion"))
{ {
this.SendCommand(new UseItemCommand("potion")); _architecture.SendCommand(new UseItemCommand("potion"));
} }
} }
} }
@ -94,7 +97,7 @@ public partial class PlayerController : Node, IController
ShowLevelUpEffect(); ShowLevelUpEffect();
} }
public override void _ExitTree() public void Cleanup()
{ {
// 清理事件注册 // 清理事件注册
_unregisterList.UnRegisterAll(); _unregisterList.UnRegisterAll();
@ -109,15 +112,16 @@ public partial class PlayerController : Node, IController
```csharp ```csharp
// UI 面板控制器 // UI 面板控制器
public partial class MainMenuController : Control, IController public class MainMenuController : IController
{ {
[Inject] private IArchitecture _architecture;
[Inject] private IUISystem _uiSystem;
[Export] private Button _startButton; [Export] private Button _startButton;
[Export] private Button _settingsButton; [Export] private Button _settingsButton;
[Export] private Button _quitButton; [Export] private Button _quitButton;
public IArchitecture GetArchitecture() => GameArchitecture.Interface; public void Initialize()
public override void _Ready()
{ {
// 绑定按钮事件 // 绑定按钮事件
_startButton.Pressed += OnStartButtonPressed; _startButton.Pressed += OnStartButtonPressed;
@ -125,30 +129,29 @@ public partial class MainMenuController : Control, IController
_quitButton.Pressed += OnQuitButtonPressed; _quitButton.Pressed += OnQuitButtonPressed;
// 获取模型更新 UI // 获取模型更新 UI
var gameModel = this.GetModel<GameModel>(); var gameModel = _architecture.GetModel<GameModel>();
UpdateUI(gameModel); UpdateUI(gameModel);
} }
private void OnStartButtonPressed() private void OnStartButtonPressed()
{ {
// 通过命令启动游戏 // 通过命令启动游戏
this.SendCommand<StartGameCommand>(); _architecture.SendCommand<StartGameCommand>();
} }
private void OnSettingsButtonPressed() private void OnSettingsButtonPressed()
{ {
// 查询当前设置 // 查询当前设置
var settings = this.SendQuery(new GetSettingsQuery()); var settings = _architecture.SendQuery(new GetSettingsQuery());
// 打开设置面板 // 打开设置面板
var uiSystem = this.GetSystem<UISystem>(); _uiSystem.OpenSettingsPanel(settings);
uiSystem.OpenSettingsPanel(settings);
} }
private void OnQuitButtonPressed() private void OnQuitButtonPressed()
{ {
// 发送退出命令 // 发送退出命令
this.SendCommand<QuitGameCommand>(); _architecture.SendCommand<QuitGameCommand>();
} }
private void UpdateUI(GameModel model) { /* UI 更新逻辑 */ } private void UpdateUI(GameModel model) { /* UI 更新逻辑 */ }
@ -159,25 +162,26 @@ public partial class MainMenuController : Control, IController
```csharp ```csharp
// 战斗控制器 // 战斗控制器
public partial class CombatController : Node, IController public class CombatController : IController
{ {
[Inject] protected IArchitecture _architecture;
private IUnRegisterList _unregisterList = new UnRegisterList(); private IUnRegisterList _unregisterList = new UnRegisterList();
private PlayerModel _playerModel; private PlayerModel _playerModel;
private CombatSystem _combatSystem; private CombatSystem _combatSystem;
public IArchitecture GetArchitecture() => GameArchitecture.Interface; [PostConstruct]
public void Init()
public override void _Ready()
{ {
// 缓存常用引用 // 缓存常用引用
_playerModel = this.GetModel<PlayerModel>(); _playerModel = _architecture.GetModel<PlayerModel>();
_combatSystem = this.GetSystem<CombatSystem>(); _combatSystem = _architecture.GetSystem<CombatSystem>();
// 注册多个事件 // 注册多个事件
this.RegisterEvent<EnemySpawnedEvent>(OnEnemySpawned) _architecture.RegisterEvent<EnemySpawnedEvent>(OnEnemySpawned)
.AddToUnregisterList(_unregisterList); .AddToUnregisterList(_unregisterList);
this.RegisterEvent<CombatEndedEvent>(OnCombatEnded) _architecture.RegisterEvent<CombatEndedEvent>(OnCombatEnded)
.AddToUnregisterList(_unregisterList); .AddToUnregisterList(_unregisterList);
// 监听模型状态 // 监听模型状态
@ -188,7 +192,7 @@ public partial class CombatController : Node, IController
private void OnEnemySpawned(EnemySpawnedEvent e) private void OnEnemySpawned(EnemySpawnedEvent e)
{ {
// 进入战斗状态 // 进入战斗状态
this.SendCommand(new EnterCombatCommand(e.Enemy)); _architecture.SendCommand(new EnterCombatCommand(e.Enemy));
} }
private void OnCombatEnded(CombatEndedEvent e) private void OnCombatEnded(CombatEndedEvent e)
@ -196,26 +200,25 @@ public partial class CombatController : Node, IController
if (e.Victory) if (e.Victory)
{ {
// 查询奖励 // 查询奖励
var rewards = this.SendQuery(new CalculateRewardsQuery(e.Enemy)); var rewards = _architecture.SendQuery(new CalculateRewardsQuery(e.Enemy));
// 发放奖励 // 发放奖励
this.SendCommand(new GiveRewardsCommand(rewards)); _architecture.SendCommand(new GiveRewardsCommand(rewards));
} }
else else
{ {
// 处理失败 // 处理失败
this.SendCommand<GameOverCommand>(); _architecture.SendCommand<GameOverCommand>();
} }
} }
private void OnCombatStateChanged(CombatState state) private void OnCombatStateChanged(CombatState state)
{ {
// 根据战斗状态更新 UI // 根据战斗状态更新 UI
var uiSystem = this.GetSystem<UISystem>(); _architecture.GetSystem<UISystem>().UpdateCombatUI(state);
uiSystem.UpdateCombatUI(state);
} }
public override void _ExitTree() public void Cleanup()
{ {
_unregisterList.UnRegisterAll(); _unregisterList.UnRegisterAll();
} }
@ -267,107 +270,74 @@ public partial class CombatController : Node, IController
### 事件注销 ### 事件注销
```csharp ```csharp
public partial class MyController : Node, IController public class MyController : IController
{ {
[Inject] private IArchitecture _architecture;
// 使用 UnRegisterList 统一管理 // 使用 UnRegisterList 统一管理
private IUnRegisterList _unregisterList = new UnRegisterList(); private IUnRegisterList _unregisterList = new UnRegisterList();
public override void _Ready() public void Initialize()
{ {
// 所有事件注册都添加到列表 // 所有事件注册都添加到列表
this.RegisterEvent<GameEvent>(OnGameEvent) _architecture.RegisterEvent<GameEvent>(OnGameEvent)
.AddToUnregisterList(_unregisterList); .AddToUnregisterList(_unregisterList);
this.GetModel<PlayerModel>().Health.Register(OnHealthChanged) _architecture.GetModel<PlayerModel>().Health.Register(OnHealthChanged)
.AddToUnregisterList(_unregisterList); .AddToUnregisterList(_unregisterList);
} }
public override void _ExitTree() public void Cleanup()
{ {
// 节点销毁时统一注销所有事件 // 统一注销所有事件
_unregisterList.UnRegisterAll(); _unregisterList.UnRegisterAll();
} }
} }
``` ```
### Godot 特定的生命周期
```csharp
public partial class GameController : Node, IController
{
public IArchitecture GetArchitecture() => GameArchitecture.Interface;
// 节点进入场景树
public override void _Ready()
{
// 初始化控制器
InitializeController();
}
// 每帧更新
public override void _Process(double delta)
{
// 处理实时输入
HandleInput();
}
// 物理帧更新
public override void _PhysicsProcess(double delta)
{
// 处理物理相关输入
}
// 节点即将退出场景树
public override void _ExitTree()
{
// 清理资源
CleanupController();
}
}
```
## 最佳实践 ## 最佳实践
1. **一个控制器对应一个视图** 1. **使用依赖注入获取依赖**
- 每个 Godot 场景/节点有对应的控制器 - 通过构造函数注入 `IArchitecture`
- 避免一个控制器管理多个不相关的视图 - 使用 `[Inject]` 属性标记注入字段
2. **使用依赖注入获取依赖** 2. **保持控制器轻量**
- 通过 `GetModel()``GetSystem()` 获取依赖
- 不要在构造函数中获取,应在 `_Ready()`
3. **保持控制器轻量**
- 复杂逻辑放在 Command、Query、System 中 - 复杂逻辑放在 Command、Query、System 中
- 控制器只做协调和转发 - 控制器只做协调和转发
4. **合理使用缓存** 3. **合理使用缓存**
- 频繁使用的 Model、System 可以缓存引用 - 频繁使用的 Model、System 可以缓存引用
- 平衡性能和内存占用 - 平衡性能和内存占用
5. **统一管理事件注销** 4. **统一管理事件注销**
- 使用 `IUnRegisterList` 统一管理 - 使用 `IUnRegisterList` 统一管理
- 在 `_ExitTree()` 中统一注销 - 在 `Cleanup()` 中统一注销
6. **命名规范** 5. **命名规范**
- 控制器类名:`XxxController` - 控制器类名:`XxxController`
- 继承 Godot 节点:`Node``Control``Node2D` - 使用 `[Inject]` 或构造函数注入获取架构
## 常见模式 ## 常见模式
### 数据绑定模式 ### 数据绑定模式
```csharp ```csharp
public partial class ScoreController : Label, IController public class ScoreController : IController
{ {
public IArchitecture GetArchitecture() => GameArchitecture.Interface; [Inject] private IArchitecture _architecture;
public override void _Ready() public void Initialize()
{ {
// 绑定模型数据到 UI // 绑定模型数据到 UI
this.GetModel<GameModel>() _architecture.GetModel<GameModel>()
.Score .Score
.RegisterWithInitValue(score => Text = $"Score: {score}") .RegisterWithInitValue(score => UpdateDisplay(score))
.UnRegisterWhenNodeExitTree(this); .AddToUnregisterList(_unregisterList);
}
private void UpdateDisplay(int score)
{
// 更新分数显示
} }
} }
``` ```
@ -375,11 +345,12 @@ public partial class ScoreController : Label, IController
### 状态机模式 ### 状态机模式
```csharp ```csharp
public partial class PlayerStateController : Node, IController public class PlayerStateController : IController
{ {
[Inject] private IArchitecture _architecture;
private Dictionary<PlayerState, Action> _stateHandlers; private Dictionary<PlayerState, Action> _stateHandlers;
public override void _Ready() public void Initialize()
{ {
_stateHandlers = new Dictionary<PlayerState, Action> _stateHandlers = new Dictionary<PlayerState, Action>
{ {
@ -388,10 +359,10 @@ public partial class PlayerStateController : Node, IController
{ PlayerState.Attacking, HandleAttackingState } { PlayerState.Attacking, HandleAttackingState }
}; };
this.GetModel<PlayerModel>() _architecture.GetModel<PlayerModel>()
.State .State
.Register(OnStateChanged) .Register(OnStateChanged)
.UnRegisterWhenNodeExitTree(this); .AddToUnregisterList(_unregisterList);
} }
private void OnStateChanged(PlayerState state) private void OnStateChanged(PlayerState state)
@ -401,6 +372,31 @@ public partial class PlayerStateController : Node, IController
} }
``` ```
## 与 Godot 集成
在 Godot 项目中,可以使用 GFramework.Godot 提供的扩展:
```csharp
using GFramework.Godot;
public partial class GodotPlayerController : Node, IController
{
[Inject] private IArchitecture _architecture;
public override void _Ready()
{
// 使用 Godot 特定的自动注销扩展
_architecture.RegisterEvent<PlayerDiedEvent>(OnPlayerDied)
.UnRegisterWhenNodeExitTree(this);
_architecture.GetModel<PlayerModel>()
.Health
.RegisterWithInitValue(OnHealthChanged)
.UnRegisterWhenNodeExitTree(this);
}
}
```
## 相关包 ## 相关包
- [`architecture`](../architecture/README.md) - 提供架构访问能力 - [`architecture`](../architecture/README.md) - 提供架构访问能力
@ -409,4 +405,9 @@ public partial class PlayerStateController : Node, IController
- [`events`](../events/README.md) - 控制器注册事件监听变化 - [`events`](../events/README.md) - 控制器注册事件监听变化
- [`model`](../model/README.md) - 控制器读取模型数据 - [`model`](../model/README.md) - 控制器读取模型数据
- [`system`](../system/README.md) - 控制器调用系统服务 - [`system`](../system/README.md) - 控制器调用系统服务
- [`extensions`](../extensions/README.md) - 提供便捷的扩展方法 - [`extensions`](../extensions/README.md) - 提供便捷的扩展方法
- **GFramework.Godot** - Godot 特定的控制器扩展
---
**许可证**: Apache 2.0

File diff suppressed because it is too large Load Diff

View File

@ -4,9 +4,11 @@
Architecture 包是整个框架的核心,提供了基于 MVC 架构模式的应用程序架构基础。它实现了依赖注入IoC容器、组件生命周期管理以及命令、查询、事件的统一调度机制。 Architecture 包是整个框架的核心,提供了基于 MVC 架构模式的应用程序架构基础。它实现了依赖注入IoC容器、组件生命周期管理以及命令、查询、事件的统一调度机制。
## 核心类 **注意**:本框架的 Core 模块与 Godot 解耦Godot 相关集成在 GFramework.Godot 包中实现。
### 1. [`IArchitecture`](IArchitecture.cs) ## 核心接口
### [`IArchitecture`](IArchitecture.cs)
架构接口,定义了框架的核心功能契约。 架构接口,定义了框架的核心功能契约。
@ -21,18 +23,18 @@ Architecture 包是整个框架的核心,提供了基于 MVC 架构模式的
**核心方法:** **核心方法:**
```csharp ```csharp
// 注册组件 // 组件注册
void RegisterSystem<T>(T system) where T : ISystem; void RegisterSystem<TSystem>(TSystem system) where TSystem : ISystem;
void RegisterModel<T>(T model) where T : IModel; void RegisterModel<TModel>(TModel model) where TModel : IModel;
void RegisterUtility<T>(T utility) where T : IUtility; void RegisterUtility<TUtility>(TUtility utility) where TUtility : IUtility;
// 获取组件 // 组件获取
T GetSystem<T>() where T : class, ISystem; T GetSystem<T>() where T : class, ISystem;
T GetModel<T>() where T : class, IModel; T GetModel<T>() where T : class, IModel;
T GetUtility<T>() where T : class, IUtility; T GetUtility<T>() where T : class, IUtility;
// 命令处理 // 命令处理
void SendCommand<T>(T command) where T : ICommand; void SendCommand(ICommand command);
TResult SendCommand<TResult>(ICommand<TResult> command); TResult SendCommand<TResult>(ICommand<TResult> command);
// 查询处理 // 查询处理
@ -45,32 +47,94 @@ IUnRegister RegisterEvent<T>(Action<T> onEvent);
void UnRegisterEvent<T>(Action<T> onEvent); void UnRegisterEvent<T>(Action<T> onEvent);
``` ```
### 2. [`Architecture<T>`](Architecture.cs) ### [`IArchitecturePhaseAware`](IArchitecturePhaseAware.cs)
架构基类,实现了 [`IArchitecture`](IArchitecture.cs) 接口,提供完整的架构功能实现。 架构阶段感知接口,允许组件监听架构阶段变化。
**核心方法:**
```csharp
void OnArchitecturePhase(ArchitecturePhase phase);
```
### [`IArchitectureModule`](IArchitectureModule.cs)
架构模块接口,支持模块化架构扩展。
**核心方法:**
```csharp
void Install(IArchitecture architecture);
```
### [`IAsyncInitializable`](IAsyncInitializable.cs)
异步初始化接口,支持组件异步初始化。
**核心方法:**
```csharp
Task InitializeAsync();
```
## 核心类
### [`Architecture`](Architecture.cs)
架构基类,实现了 `IArchitecture` 接口,提供完整的架构功能实现。
**特性:** **特性:**
- **单例模式**:使用泛型和 `Lazy<T>` 确保全局唯一实例 - **阶段式生命周期管理**
- **线程安全**:采用 `LazyThreadSafetyMode.ExecutionAndPublication` 保证多线程安全 支持多个架构阶段BeforeUtilityInit、AfterUtilityInit、BeforeModelInit、AfterModelInit、BeforeSystemInit、AfterSystemInit、Ready、Destroying、Destroyed
- **生命周期管理**:自动管理 System 和 Model 的初始化顺序 - **模块安装系统**:支持通过 `InstallModule` 扩展架构功能
- **IoC 容器**:内置依赖注入容器,管理所有组件实例 - **异步初始化**:支持同步和异步两种初始化方式
- **事件系统**:集成类型化事件系统,支持类型安全的事件通信 - **IoC 容器集成**:内置依赖注入容器
- **事件系统集成**:集成类型化事件系统
- **与平台无关**Core 模块不依赖 Godot可以在任何 .NET 环境中使用
**架构阶段:**
```csharp
public enum ArchitecturePhase
{
None = 0, // 初始阶段
BeforeUtilityInit = 1, // 工具初始化前
AfterUtilityInit = 2, // 工具初始化后
BeforeModelInit = 3, // 模型初始化前
AfterModelInit = 4, // 模型初始化后
BeforeSystemInit = 5, // 系统初始化前
AfterSystemInit = 6, // 系统初始化后
Ready = 7, // 就绪状态
FailedInitialization = 8, // 初始化失败
Destroying = 9, // 正在销毁
Destroyed = 10 // 已销毁
}
```
**初始化流程:** **初始化流程:**
1. 创建架构实例 1. 创建架构实例(传入配置或使用默认配置)
2. 调用用户自定义的 `Init()` 方法 2. 调用用户自定义的 `Init()` 方法
3. 执行注册的补丁逻辑(`OnRegisterPatch` 3. 初始化上下文工具Context Utility
4. 初始化所有已注册的 Model 4. 初始化所有注册的 Model
5. 初始化所有已注册的 System 5. 初始化所有注册的 System
6. 标记初始化完成 6. 冻结 IOC 容器
7. 进入 Ready 阶段
**销毁流程:**
1. 进入 Destroying 阶段
2. 发送 `ArchitectureDestroyingEvent` 事件
3. 销毁所有 System
4. 进入 Destroyed 阶段
5. 发送 `ArchitectureDestroyedEvent` 事件
**使用示例:** **使用示例:**
```csharp ```csharp
// 1. 定义你的架构 // 1. 定义你的架构(继承 Architecture 基类)
public class GameArchitecture : Architecture<GameArchitecture> public class GameArchitecture : Architecture
{ {
protected override void Init() protected override void Init()
{ {
@ -88,26 +152,39 @@ public class GameArchitecture : Architecture<GameArchitecture>
} }
} }
// 2. 在其他地方使用架构 // 2. 创建并初始化架构
var architecture = new GameArchitecture();
architecture.Initialize();
// 或者异步初始化
// var architecture = new GameArchitecture();
// await architecture.InitializeAsync();
// 3. 通过依赖注入使用架构
// 在 Controller 或其他组件中注入架构实例
public class GameController : IController public class GameController : IController
{ {
private IArchitecture _architecture; private readonly IArchitecture _architecture;
public IArchitecture GetArchitecture() => GameArchitecture.Interface; // 通过构造函数注入架构
public GameController(IArchitecture architecture)
{
_architecture = architecture;
}
public void Start() public void Start()
{ {
// 获取 Model // 获取 Model
var playerModel = this.GetModel<PlayerModel>(); var playerModel = _architecture.GetModel<PlayerModel>();
// 发送命令 // 发送命令
this.SendCommand<StartGameCommand>(); _architecture.SendCommand(new StartGameCommand());
// 发送查询 // 发送查询
var score = this.SendQuery(new GetScoreQuery()); var score = _architecture.SendQuery(new GetScoreQuery());
// 注册事件 // 注册事件
this.RegisterEvent<PlayerDiedEvent>(OnPlayerDied); _architecture.RegisterEvent<PlayerDiedEvent>(OnPlayerDied);
} }
private void OnPlayerDied(PlayerDiedEvent e) private void OnPlayerDied(PlayerDiedEvent e)
@ -120,51 +197,113 @@ public class GameController : IController
**高级特性:** **高级特性:**
```csharp ```csharp
// 动态扩展架构(补丁系统) // 1. 使用自定义配置
Architecture<GameArchitecture>.OnRegisterPatch += arch => var config = new ArchitectureConfiguration();
var architecture = new GameArchitecture(configuration: config);
// 2. 模块安装
var module = new GameModule();
architecture.InstallModule(module);
// 3. 监听架构阶段变化
public class GamePhaseListener : IArchitecturePhaseAware
{ {
// 在架构初始化完成前注入额外逻辑 public void OnArchitecturePhase(ArchitecturePhase phase)
arch.RegisterSystem(new DebugSystem()); {
switch (phase)
{
case ArchitecturePhase.Ready:
GD.Print("架构已就绪,可以开始游戏了");
break;
case ArchitecturePhase.Destroying:
GD.Print("架构正在销毁");
break;
}
}
}
// 4. 生命周期钩子
public class LifecycleHook : IArchitectureLifecycle
{
public void OnPhase(ArchitecturePhase phase, IArchitecture architecture)
{
GD.Print($"架构阶段变化: {phase}");
}
}
```
### [`ArchitectureConfiguration`](ArchitectureConfiguration.cs)
架构配置类,用于配置架构的行为。
**使用示例:**
```csharp
var config = new ArchitectureConfiguration
{
// 严格阶段验证
StrictPhaseValidation = true,
// 允许延迟注册
AllowLateRegistration = false
}; };
// 在运行时动态注册组件(初始化后) var architecture = new GameArchitecture(configuration: config);
var newSystem = new DynamicSystem();
GameArchitecture.Interface.RegisterSystem(newSystem);
// newSystem.Init() 会被立即调用
``` ```
### [`ArchitectureServices`](ArchitectureServices.cs)
架构服务类管理命令总线、查询总线、IOC容器和类型事件系统。
### [`ArchitectureContext`](ArchitectureContext.cs)
架构上下文类,提供对架构服务的访问。
### [`GameContext`](GameContext.cs)
游戏上下文类,管理架构上下文与类型的绑定关系。
## 设计模式 ## 设计模式
### 单例模式 ### 1. 依赖注入
通过泛型约束和 `Lazy<T>` 实现类型安全的单例。 通过构造函数注入或容器解析获取架构实例。
### 依赖注入IoC ### 2. 依赖注入IoC
使用内置 IoC 容器管理组件生命周期和依赖关系。 使用内置 IoC 容器管理组件生命周期和依赖关系。
### 命令模式 ### 3. 命令模式
通过 [`ICommand`](../command/ICommand.cs) 封装所有用户操作。 通过 `ICommand` 封装所有用户操作。
### 查询模式CQRS ### 4. 查询模式CQRS
通过 [`IQuery<T>`](../query/IQuery.cs) 分离查询和命令操作。 通过 `IQuery<T>` 分离查询和命令操作。
### 观察者模式 ### 5. 观察者模式
通过事件系统实现组件间的松耦合通信。 通过事件系统实现组件间的松耦合通信。
### 6. 阶段式生命周期管理
通过 `ArchitecturePhase` 枚举和生命周期钩子管理架构状态。
### 7. 组合优于继承
通过接口组合获得不同能力,而不是深层继承链。
## 最佳实践 ## 最佳实践
1. **保持架构类简洁**:只在 `Init()` 中注册组件,不要包含业务逻辑 1. **保持架构类简洁**:只在 `Init()` 中注册组件,不要包含业务逻辑
2. **合理划分职责** 2. **合理划分职责**
- Model数据和状态 - Model数据和状态
- System业务逻辑和规则 - System业务逻辑和规则
- Utility无状态的工具方法 - Utility无状态的工具方法
3. **使用接口访问**:通过 `Interface` 属性访问架构,便于测试 3. **使用依赖注入**:通过构造函数注入架构实例,便于测试
4. **事件命名规范**:使用过去式命名事件类,如 `PlayerDiedEvent` 4. **事件命名规范**:使用过去式命名事件类,如 `PlayerDiedEvent`
5. **避免循环依赖**System 不应直接引用 System应通过事件通信 5. **避免循环依赖**System 不应直接引用 System应通过事件通信
6. **使用模块扩展**:通过 `IArchitectureModule` 实现架构的可扩展性
7. **Core 模块与平台解耦**GFramework.Core 不包含 Godot 相关代码Godot 集成在单独模块中
## 相关包 ## 相关包
@ -175,7 +314,8 @@ GameArchitecture.Interface.RegisterSystem(newSystem);
- [`model`](../model/README.md) - 数据模型 - [`model`](../model/README.md) - 数据模型
- [`system`](../system/README.md) - 业务系统 - [`system`](../system/README.md) - 业务系统
- [`utility`](../utility/README.md) - 工具类 - [`utility`](../utility/README.md) - 工具类
- **GFramework.Godot** - Godot 特定集成GodotNode 扩展、GodotLogger 等)
--- ---
**许可证**: Apache 2.0 **许可证**: Apache 2.0

View File

@ -1,305 +1,309 @@
# GFramework.Core 日志系统 # Logging 包使用说明
## 概述 ## 概述
GFramework.Core 提供了一个灵活、可配置的日志系统,支持多级别、多类别和多种输出方式的日志记录。默认日志级别为 `Info` Logging 包提供了灵活的日志系统,支持多级别日志记录。默认日志级别为 `Info`,确保框架的关键操作都能被记录下来。
,确保框架的关键操作都能被记录下来。
## 主要特性 ## 核心接口
- **多级别日志支持**: Trace、Debug、Info、Warning、Error、Fatal ### [`ILogger`](ILogger.cs)
- **类别化日志**: 支持按模块分类记录日志
- **可配置输出**: 支持控制台输出和文件输出
- **彩色控制台输出**: 提供不同级别的颜色区分
- **灵活的级别控制**: 可全局设置或按类别设置不同的日志级别
## 快速开始 日志记录器接口,定义了日志记录的基本功能。
### 1. 基本配置 **核心方法:**
```csharp ```csharp
using GFramework.Core.logging; // 日志级别检查
bool IsTraceEnabled();
bool IsDebugEnabled();
bool IsInfoEnabled();
bool IsWarnEnabled();
bool IsErrorEnabled();
bool IsFatalEnabled();
// 快速配置(推荐) // 记录日志
Log.Configure( void Trace(string msg);
minLevel: LogLevel.Info, // 默认级别为Info void Trace(string format, object arg);
enableConsole: true, // 启用控制台输出 void Trace(string format, object arg1, object arg2);
useColors: true, // 使用彩色输出 void Trace(string format, params object[] arguments);
enableFile: false, // 不启用文件输出 void Trace(string msg, Exception t);
logFilePath: null // 无文件输出
);
// 或者使用详细的配置 void Debug(string msg);
var config = new LogConfig void Debug(string format, object arg);
void Debug(string format, object arg1, object arg2);
void Debug(string format, params object[] arguments);
void Debug(string msg, Exception t);
void Info(string msg);
void Info(string format, object arg);
void Info(string format, object arg1, object arg2);
void Info(string format, params object[] arguments);
void Info(string msg, Exception t);
void Warn(string msg);
void Warn(string format, object arg);
void Warn(string format, object arg1, object arg2);
void Warn(string format, params object[] arguments);
void Warn(string msg, Exception t);
void Error(string msg);
void Error(string format, object arg);
void Error(string format, object arg1, object arg2);
void Error(string format, params object[] arguments);
void Error(string msg, Exception t);
void Fatal(string msg);
void Fatal(string format, object arg);
void Fatal(string format, object arg1, object arg2);
void Fatal(string format, params object[] arguments);
void Fatal(string msg, Exception t);
// 获取日志器名称
string Name();
```
### [`ILoggerFactory`](ILoggerFactory.cs)
日志工厂接口,用于创建日志记录器实例。
**核心方法:**
```csharp
ILogger GetLogger(string name, LogLevel minLevel = LogLevel.Info);
```
### [`ILoggerFactoryProvider`](ILoggerFactory.cs)
日志工厂提供程序接口,用于获取日志工厂。
**核心方法:**
```csharp
ILoggerFactory GetLoggerFactory();
ILogger CreateLogger(string name);
```
### [`LogLevel`](LogLevel.cs)
日志级别枚举。
```csharp
public enum LogLevel
{ {
DefaultMinLevel = LogLevel.Info, Trace = 0, // 最详细的跟踪信息
EnableConsole = true, Debug = 1, // 调试信息
UseColors = true, Info = 2, // 一般信息(默认级别)
EnableFile = true, Warning = 3, // 警告信息
LogFilePath = "logs/gframework.log" Error = 4, // 错误信息
}; Fatal = 5 // 致命错误
}
// 设置特定模块的日志级别
config.SetCategoryLevel("Architecture", LogLevel.Debug);
config.SetCategoryLevel("IOC", LogLevel.Debug);
config.SetCategoryLevel("Event", LogLevel.Info);
Log.Initialize(config);
``` ```
### 2. 使用日志记录 ## 核心类
#### 基本使用示例 ### [`AbstractLogger`](AbstractLogger.cs)
抽象日志基类,封装了日志级别判断、格式化与异常处理逻辑。平台日志器只需实现 `Write` 方法即可。
**使用示例:**
```csharp ```csharp
// 使用全局日志实例 public class CustomLogger : AbstractLogger
Log.Info("应用程序启动");
Log.Warn("这是一个警告");
Log.Error("这是一个错误信息");
// 创建特定类别的日志记录器
var userLogger = Log.CreateLogger("UserService");
userLogger.Info("用户服务初始化完成", new { ServiceVersion = "1.0" });
var dbLogger = Log.CreateLogger("Database");
dbLogger.Debug("连接数据库", new { Server = "localhost", Database = "MyApp" });
dbLogger.Info("数据库连接成功");
```
#### 详细使用示例
```csharp
// 创建特定类别的日志记录器
var logger = Log.CreateLogger("MyModule");
logger.Debug("调试信息:连接数据库");
logger.Info("用户登录成功", new { UserId = 123, UserName = "张三" });
logger.Warn("连接超时,正在重试", new { RetryCount = 2 });
logger.Error("数据库连接失败", ex, new { DatabaseUrl = "localhost:1433" });
logger.Fatal("系统发生严重错误", new { SystemState = "Critical" });
```
#### 框架组件日志示例
```csharp
// 在架构中使用
var architecture = ExampleArchitecture.Instance;
architecture.RegisterSystem(new ExampleSystem());
architecture.RegisterModel(new ExampleModel());
architecture.RegisterUtility(new ExampleUtility());
// 在系统中使用
public class ExampleSystem : AbstractSystem
{ {
protected override void OnInit() public CustomLogger(string? name = null, LogLevel minLevel = LogLevel.Info)
: base(name, minLevel)
{ {
Log.CreateLogger("System").Info("ExampleSystem 初始化完成");
} }
protected override void OnDestroy() protected override void Write(LogLevel level, string message, Exception? exception)
{ {
Log.CreateLogger("System").Info("ExampleSystem 销毁"); // 自定义日志输出逻辑
var logMessage = $"[{DateTime.Now:yyyy-MM-dd HH:mm:ss}] [{level}] {message}";
if (exception != null)
logMessage += $"\n{exception}";
Console.WriteLine(logMessage);
} }
} }
// 在模型中使用
public class ExampleModel : AbstractModel
{
protected override void OnInit()
{
Log.CreateLogger("Model").Info("ExampleModel 初始化完成");
}
}
// 在工具中使用
public class ExampleUtility : IUtility
{
public void DoSomething()
{
Log.CreateLogger("Utility").Debug("ExampleUtility 执行操作");
}
}
// 在事件中使用
architecture.RegisterEvent<ExampleEvent>(evt =>
{
Log.CreateLogger("EventListener").Info($"收到事件: {evt.Message}");
});
``` ```
### 3. 高级配置 ### [`ConsoleLogger`](ConsoleLogger.cs)
控制台日志记录器实现,支持彩色输出。
**使用示例:**
```csharp ```csharp
// 创建自定义配置的日志记录器 // 创建控制台日志记录器
var config = new LogConfig var logger = new ConsoleLogger("MyLogger", LogLevel.Debug);
{
DefaultMinLevel = LogLevel.Warning, // 默认只显示Warning及以上
EnableConsole = true,
UseColors = true,
EnableFile = true,
LogFilePath = "logs/app-{yyyy-MM-dd}.log"
};
// 为不同模块设置不同的日志级别 // 记录不同级别的日志
config.SetCategoryLevel("Architecture", LogLevel.Info); // 架构信息 logger.Info("应用程序启动");
config.SetCategoryLevel("IOC", LogLevel.Debug); // IOC详细日志 logger.Debug("调试信息");
config.SetCategoryLevel("Event", LogLevel.Info); // 事件日志 logger.Warn("警告信息");
config.SetCategoryLevel("System", LogLevel.Info); // 系统日志 logger.Error("错误信息");
config.SetCategoryLevel("Database", LogLevel.Debug); // 数据库日志 logger.Fatal("致命错误");
config.SetCategoryLevel("Network", LogLevel.Trace); // 网络日志(最详细)
Log.Initialize(config);
// 演示不同级别的日志记录
var networkLogger = Log.CreateLogger("Network");
networkLogger.Trace("网络请求开始", new { Url = "https://api.example.com/users", Method = "GET" });
networkLogger.Debug("添加请求头", new { Headers = new[] { "Authorization: Bearer xxx", "Content-Type: application/json" } });
networkLogger.Info("网络请求完成", new { StatusCode = 200, ResponseTime = "120ms" });
var userServiceLogger = Log.CreateLogger("UserService");
userServiceLogger.Debug("查询用户信息", new { UserId = 123 });
userServiceLogger.Info("用户登录成功", new { UserId = 123, UserName = "张三", LoginTime = DateTime.Now });
``` ```
### 4. 异常日志记录 **输出格式:**
```csharp
var serviceLogger = Log.CreateLogger("UserService");
try
{
// 模拟业务逻辑中的异常
throw new InvalidOperationException("用户数据验证失败");
}
catch (Exception ex)
{
serviceLogger.Error("用户注册失败", ex, new
{
Operation = "UserRegistration",
UserEmail = "user@example.com",
ValidationErrors = new[] { "邮箱格式无效", "密码强度不足" }
});
}
// 演示Fatal级别的使用
try
{
throw new SystemException("数据库连接完全中断");
}
catch (Exception ex)
{
serviceLogger.Fatal("系统发生致命错误", ex, new
{
ErrorCode = "DB_CONNECTION_FAILED",
RetryAttempts = 3,
LastRetryTime = DateTime.Now.AddMinutes(-5)
});
}
```
### 5. 生产环境配置
```csharp
// 生产环境推荐配置
var productionConfig = new LogConfig
{
DefaultMinLevel = LogLevel.Info, // 只记录Info及以上级别
EnableConsole = false, // 生产环境通常不输出到控制台
UseColors = false,
EnableFile = true, // 启用文件日志
LogFilePath = "logs/production-{yyyy-MM-dd}.log"
};
// 为关键模块设置更详细的日志级别
productionConfig.SetCategoryLevel("Architecture", LogLevel.Info);
productionConfig.SetCategoryLevel("Security", LogLevel.Debug); // 安全相关日志更详细
productionConfig.SetCategoryLevel("Payment", LogLevel.Debug); // 支付相关日志更详细
productionConfig.SetCategoryLevel("IOC", LogLevel.Warning); // 减少IOC调试日志
Log.Initialize(productionConfig);
var securityLogger = Log.CreateLogger("Security");
securityLogger.Info("用户登录尝试", new { UserId = 456, IpAddress = "192.168.1.100" });
securityLogger.Warn("密码错误", new { UserId = 456, FailedAttempts = 2 });
securityLogger.Info("登录成功", new { UserId = 456, SessionId = "sess_abc123" });
var paymentLogger = Log.CreateLogger("Payment");
paymentLogger.Debug("开始处理支付", new { OrderId = "ORD_789", Amount = 99.99m, Currency = "CNY" });
paymentLogger.Info("支付成功", new { OrderId = "ORD_789", TransactionId = "txn_456" });
```
## 日志级别说明
- **Trace**: 最详细的跟踪信息,用于调试复杂的执行流程
- **Debug**: 调试信息,用于开发和测试阶段
- **Info**: 一般信息,记录重要的业务流程和系统状态
- **Warning**: 警告信息,可能的问题但不中断程序执行
- **Error**: 错误信息,影响功能但不致命
- **Fatal**: 致命错误,导致程序无法继续运行
## 框架内部日志
GFramework.Core 在以下关键位置自动添加了日志记录:
### 架构模块 (Architecture)
- 架构初始化流程
- 组件注册和初始化
- 生命周期阶段变更
- 模块安装和卸载
### IOC容器 (IOC)
- 对象注册和获取
- 容器冻结操作
- 重复注册检测
### 事件系统 (Event)
- 事件发送和接收
- 事件处理器注册和注销
### 系统模块 (System)
- 系统初始化和销毁
- 组件生命周期管理
## 输出格式
### 控制台输出示例
``` ```
[2025-12-23 12:34:56.789] INFO Architecture Architecture initialized [2025-01-09 01:40:00.000] INFO [MyLogger] 应用程序启动
[2025-12-23 12:34:56.790] INFO Architecture Initializing 3 systems [2025-01-09 01:40:01.000] DEBUG [MyLogger] 调试信息
[2025-12-23 12:34:56.791] DEBUG Architecture Initializing system: GameSystem [2025-01-09 01:40:02.000] WARN [MyLogger] 警告信息
[2025-12-23 12:34:56.792] INFO Architecture System registered: GameSystem
[2025-12-23 12:34:56.793] INFO Architecture Architecture is ready - all components initialized
``` ```
### 日志输出级别颜色 **日志级别颜色:**
- **Trace**: 灰色 - **Trace**: 深灰色
- **Debug**: 青色 - **Debug**: 青色
- **Info**: 白色 - **Info**: 白色
- **Warning**: 黄色 - **Warning**: 黄色
- **Error**: 红色 - **Error**: 红色
- **Fatal**: 洋红色 - **Fatal**: 洋红色
### [`ConsoleLoggerFactory`](ConsoleLoggerFactory.cs)
控制台日志工厂,用于创建控制台日志记录器实例。
**使用示例:**
```csharp
var factory = new ConsoleLoggerFactory();
var logger = factory.GetLogger("MyModule", LogLevel.Debug);
logger.Info("日志记录器创建成功");
```
### [`ConsoleLoggerFactoryProvider`](ConsoleLoggerFactoryProvider.cs)
控制台日志工厂提供程序实现。
**使用示例:**
```csharp
var provider = new ConsoleLoggerFactoryProvider();
var factory = provider.GetLoggerFactory();
var logger = factory.GetLogger("MyApp", LogLevel.Info);
```
### [`LoggerFactoryResolver`](LoggerFactoryResolver.cs)
日志工厂提供程序解析器,用于管理和提供日志工厂提供程序实例。
**使用示例:**
```csharp
// 设置日志工厂提供程序
LoggerFactoryResolver.Provider = new ConsoleLoggerFactoryProvider();
// 设置最小日志级别
LoggerFactoryResolver.MinLevel = LogLevel.Debug;
// 获取日志记录器
var logger = LoggerFactoryResolver.Provider.CreateLogger("MyApp");
logger.Info("应用程序启动");
```
## 在架构中使用日志
### 1. 在 Architecture 中使用
```csharp
public class GameArchitecture : Architecture<GameArchitecture>
{
protected override void Init()
{
var logger = LoggerFactoryResolver.Provider.CreateLogger("GameArchitecture");
logger.Info("游戏架构初始化开始");
RegisterModel(new PlayerModel());
RegisterSystem(new GameSystem());
logger.Info("游戏架构初始化完成");
}
}
```
### 2. 在 System 中使用
```csharp
public class CombatSystem : AbstractSystem
{
protected override void OnInit()
{
var logger = LoggerFactoryResolver.Provider.CreateLogger("CombatSystem");
logger.Info("战斗系统初始化完成");
}
protected override void OnDestroy()
{
var logger = LoggerFactoryResolver.Provider.CreateLogger("CombatSystem");
logger.Info("战斗系统已销毁");
}
}
```
### 3. 在 Model 中使用
```csharp
public class PlayerModel : AbstractModel
{
protected override void OnInit()
{
var logger = LoggerFactoryResolver.Provider.CreateLogger("PlayerModel");
logger.Info("玩家模型初始化完成");
}
}
```
### 4. 自定义日志级别
```csharp
public class DebugLogger : AbstractLogger
{
public DebugLogger() : base("Debug", LogLevel.Debug)
{
}
protected override void Write(LogLevel level, string message, Exception? exception)
{
// 只输出调试及更高级别的日志
if (level >= LogLevel.Debug)
{
GD.Print($"[{level}] {message}");
if (exception != null)
GD.Print(exception);
}
}
}
```
## 日志级别说明
| 级别 | 说明 | 使用场景 |
|-------------|----------|-------------------|
| **Trace** | 最详细的跟踪信息 | 调试复杂的执行流程,记录函数调用等 |
| **Debug** | 调试信息 | 开发阶段,记录变量值、流程分支等 |
| **Info** | 一般信息 | 记录重要的业务流程和系统状态 |
| **Warning** | 警告信息 | 可能的问题但不中断程序执行 |
| **Error** | 错误信息 | 影响功能但不致命的问题 |
| **Fatal** | 致命错误 | 导致程序无法继续运行的严重错误 |
## 最佳实践 ## 最佳实践
1. **使用合适的日志级别**: 1. **使用合适的日志级别**
- 使用 `Info` 记录重要业务流程 - 使用 `Info` 记录重要业务流程
- 使用 `Debug` 记录调试信息 - 使用 `Debug` 记录调试信息
- 使用 `Warning` 记录异常情况 - 使用 `Warning` 记录异常情况
- 使用 `Error` 记录错误但不影响程序运行 - 使用 `Error` 记录错误但不影响程序运行
- 使用 `Fatal` 记录严重错误 - 使用 `Fatal` 记录严重错误
2. **提供上下文信息**: 2. **提供上下文信息**
```csharp ```csharp
Log.Info("用户登录成功", new { UserId = userId, UserName = userName }); logger.Info($"用户登录成功: UserId={userId}, UserName={userName}");
``` ```
3. **异常日志记录**: 3. **异常日志记录**
```csharp ```csharp
try try
{ {
@ -307,64 +311,45 @@ GFramework.Core 在以下关键位置自动添加了日志记录:
} }
catch (Exception ex) catch (Exception ex)
{ {
Log.Error("数据库操作失败", ex, new { Operation = "InsertUser", UserId = userId }); logger.Error("数据库操作失败", ex);
} }
``` ```
4. **分类使用日志**: 4. **分类使用日志**
```csharp ```csharp
var dbLogger = Log.CreateLogger("Database"); var dbLogger = LoggerFactoryResolver.Provider.CreateLogger("Database");
var netLogger = Log.CreateLogger("Network"); var netLogger = LoggerFactoryResolver.Provider.CreateLogger("Network");
dbLogger.Info("查询用户数据"); dbLogger.Info("查询用户数据");
netLogger.Debug("发送HTTP请求"); netLogger.Debug("发送HTTP请求");
``` ```
5. **在框架组件中合理使用日志**: 5. **在框架组件中合理使用日志**
```csharp ```csharp
// 在系统初始化时记录 // 在系统初始化时记录
protected override void OnInit() var logger = LoggerFactoryResolver.Provider.CreateLogger("System");
{ logger.Info("系统初始化完成");
Log.CreateLogger("System").Info("系统初始化完成");
}
// 在事件处理中记录
architecture.RegisterEvent<UserLoginEvent>(evt =>
{
Log.CreateLogger("Event").Info("用户登录事件", new { UserId = evt.UserId });
});
``` ```
## 配置建议 ## 注意事项
### 开发环境 1. **日志级别检查**
- 每个日志方法都会自动检查日志级别
- 如果当前级别低于最小级别,不会输出日志
```csharp 2. **格式化参数**
Log.Configure( - 支持字符串格式化参数
minLevel: LogLevel.Debug, - 支持异常信息传递
enableConsole: true,
useColors: true,
enableFile: false
);
```
### 生产环境 3. **自定义比较器**
- 在 `BindableProperty` 中可以使用 `WithComparer` 设置自定义比较器
```csharp ## 相关包
var config = new LogConfig
{
DefaultMinLevel = LogLevel.Info,
EnableConsole = false, // 生产环境通常不需要控制台输出
UseColors = false,
EnableFile = true,
LogFilePath = "logs/production-{yyyy-MM-dd}.log"
};
config.SetCategoryLevel("Architecture", LogLevel.Info); - [`architecture`](../architecture/README.md) - 架构核心,使用日志系统记录生命周期事件
config.SetCategoryLevel("IOC", LogLevel.Warning); // 减少IOC日志 - [`property`](../property/README.md) - 可绑定属性基于事件系统实现
config.SetCategoryLevel("Event", LogLevel.Info); - [`extensions`](../extensions/README.md) - 提供便捷的扩展方法
Log.Initialize(config); ---
```
通过这个日志系统你可以全面追踪GFramework.Core的执行过程快速定位问题并监控应用程序的运行状态。 **许可证**: Apache 2.0

View File

@ -2,7 +2,7 @@
## 概述 ## 概述
Property 包提供了可绑定属性BindableProperty的实现支持属性值的监听和响应式编程。这是实现 MVVM 模式和数据绑定的核心组件。 Property 包提供了可绑定属性BindableProperty的实现支持属性值的监听和响应式编程。这是实现数据绑定和响应式编程的核心组件。
## 核心接口 ## 核心接口
@ -13,10 +13,17 @@ Property 包提供了可绑定属性BindableProperty的实现支持属
**核心成员:** **核心成员:**
```csharp ```csharp
T Value { get; } // 获取属性值 // 获取属性值
IUnRegister Register(Action<T> onValueChanged); // 注册监听 T Value { get; }
IUnRegister RegisterWithInitValue(Action<T> action); // 注册并立即回调当前值
void UnRegister(Action<T> onValueChanged); // 取消监听 // 注册监听(不立即触发回调)
IUnRegister Register(Action<T> onValueChanged);
// 注册监听并立即触发回调传递当前值
IUnRegister RegisterWithInitValue(Action<T> action);
// 取消监听
void UnRegister(Action<T> onValueChanged);
``` ```
### [`IBindableProperty<T>`](IBindableProperty.cs) ### [`IBindableProperty<T>`](IBindableProperty.cs)
@ -26,8 +33,11 @@ void UnRegister(Action<T> onValueChanged); // 取消监听
**核心成员:** **核心成员:**
```csharp ```csharp
new T Value { get; set; } // 可读写的属性值 // 可读写的属性值
void SetValueWithoutEvent(T newValue); // 设置值但不触发事件 new T Value { get; set; }
// 设置值但不触发事件
void SetValueWithoutEvent(T newValue);
``` ```
## 核心类 ## 核心类
@ -42,13 +52,13 @@ void SetValueWithoutEvent(T newValue); // 设置值但不触发事件
// 创建可绑定属性 // 创建可绑定属性
var health = new BindableProperty<int>(100); var health = new BindableProperty<int>(100);
// 监听值变化 // 监听值变化(不会立即触发)
var unregister = health.Register(newValue => var unregister = health.Register(newValue =>
{ {
GD.Print($"Health changed to: {newValue}"); GD.Print($"Health changed to: {newValue}");
}); });
// 修改值(会触发监听器) // 设置值(会触发监听器)
health.Value = 50; // 输出: Health changed to: 50 health.Value = 50; // 输出: Health changed to: 50
// 取消监听 // 取消监听
@ -68,18 +78,26 @@ health.RegisterWithInitValue(value =>
// 后续值变化时也会调用 // 后续值变化时也会调用
}); });
// 2. 自定义比较器 // 2. 自定义比较器(静态方法)
BindableProperty<int>.Comparer = (a, b) => Math.Abs(a - b) < 1;
// 3. 使用实例方法设置比较器
var position = new BindableProperty<Vector3>(Vector3.Zero) var position = new BindableProperty<Vector3>(Vector3.Zero)
.WithComparer((a, b) => a.DistanceTo(b) < 0.01f); // 距离小于0.01认为相等 .WithComparer((a, b) => a.DistanceTo(b) < 0.01f); // 距离小于0.01认为相等
// 3. 链式调用
health.Value = 100;
``` ```
### [`BindablePropertyUnRegister<T>`](BindablePropertyUnRegister.cs) ### [`BindablePropertyUnRegister<T>`](BindablePropertyUnRegister.cs)
可绑定属性的注销器,负责清理监听。 可绑定属性的注销器,负责清理监听。
**使用示例:**
```csharp
var unregister = health.Register(OnHealthChanged);
// 当需要取消监听时
unregister.UnRegister();
```
## 在 Model 中使用 ## 在 Model 中使用
### 定义可绑定属性 ### 定义可绑定属性
@ -283,6 +301,26 @@ var position = new BindableProperty<Vector3>()
.WithComparer((a, b) => a.DistanceTo(b) < 0.001f); .WithComparer((a, b) => a.DistanceTo(b) < 0.001f);
``` ```
## 实现原理
### 值变化检测
```csharp
// 使用 EqualityComparer<T>.Default 进行比较
if (!EqualityComparer<T>.Default.Equals(value, MValue))
{
MValue = value;
_mOnValueChanged?.Invoke(value);
}
```
### 事件触发机制
```csharp
// 当值变化时触发所有注册的回调
_mOnValueChanged?.Invoke(value);
```
## 最佳实践 ## 最佳实践
1. **在 Model 中定义属性** - BindableProperty 主要用于 Model 层 1. **在 Model 中定义属性** - BindableProperty 主要用于 Model 层
@ -290,10 +328,14 @@ var position = new BindableProperty<Vector3>()
3. **及时注销监听** - 使用 UnRegisterList 或 UnRegisterWhenNodeExitTree 3. **及时注销监听** - 使用 UnRegisterList 或 UnRegisterWhenNodeExitTree
4. **使用 RegisterWithInitValue** - UI 绑定时立即获取初始值 4. **使用 RegisterWithInitValue** - UI 绑定时立即获取初始值
5. **避免循环依赖** - 属性监听器中修改其他属性要小心 5. **避免循环依赖** - 属性监听器中修改其他属性要小心
6. **使用自定义比较器** - 对于浮点数等需要精度控制的属性
## 相关包 ## 相关包
- [`model`](../model/README.md) - Model 中大量使用 BindableProperty - [`model`](../model/README.md) - Model 中大量使用 BindableProperty
- [`events`](../events/README.md) - BindableProperty 基于事件系统实现 - [`events`](../events/README.md) - BindableProperty 基于事件系统实现
- [`controller`](../controller/README.md) - Controller 监听属性变化更新 UI - [`extensions`](../extensions/README.md) - 提供便捷的注销扩展方法
- [`extensions`](../extensions/README.md) - 提供便捷的注销扩展方法
---
**许可证**: Apache 2.0

242
README.md
View File

@ -1,13 +1,14 @@
# GFramework # GFramework
一个专为Godot和通用游戏开发场景设计的综合性C#游戏开发框架 一个专为游戏开发场景设计的综合性C#游戏开发框架Core 模块与平台无关
本项目参考(CV)自[QFramework](https://github.com/liangxiegame/QFramework) 本项目参考(CV)自[QFramework](https://github.com/liangxiegame/QFramework)
# 为什么要有这个项目 # 为什么要有这个项目
- 原来的项目是单文件框架,我把框架拆成多个文件,方便管理 - 原来的项目是单文件框架,我把框架拆成多个文件,方便管理
- 纯粹个人自用,要使用还是请访问[QFramework](https://github.com/liangxiegame/QFramework) - 纯粹个人自用,要使用还是请访问[QFramework](https://github.com/liangxiegame/QFramework)
- 至于修改名字是因为我为了方便会发布GuGet包假设将来QFramework也要发布GuGet包那么就会冲突了 - 至于修改名字是因为我为了方便会发布NuGet包假设将来QFramework也要发布NuGet包那么就会冲突了
- Core 模块与 Godot 解耦,可以轻松移植到其他平台
## 特性 Features ## 特性 Features
@ -17,95 +18,246 @@
- **事件系统 Event System**: 类型安全的事件系统,实现松耦合 - **事件系统 Event System**: 类型安全的事件系统,实现松耦合
- **属性绑定 Property Binding**: 可绑定属性,支持响应式编程 - **属性绑定 Property Binding**: 可绑定属性,支持响应式编程
- **日志框架 Logging Framework**: 结构化日志,支持多个日志级别 - **日志框架 Logging Framework**: 结构化日志,支持多个日志级别
- **生命周期管理 Lifecycle Management**: 阶段式的架构生命周期管理
- **命令查询分离 CQRS**: 命令和查询的职责分离
### 游戏开发特性 Game Development Features ### 游戏开发特性 Game Development Features
- **资产管理 Asset Management**: 集中化资产目录系统 - **资产管理 Asset Management**: 集中化资产目录系统GFramework.Game
- **资源工厂 Resource Factory**: 工厂模式的资源创建模式 - **资源工厂 Resource Factory**: 工厂模式的资源创建模式
- **架构模式 Architecture Pattern**: 关注点分离的清晰架构 - **架构模式 Architecture Pattern**: 关注点分离的清晰架构
- **模块化 Module System**: 支持架构模块安装和扩展
### Godot集成 Godot Integration ### 平台无关 Platform Agnostic
- **Godot特定扩展 Godot-Specific Extensions**: Godot开发的扩展和工具 - **纯 .NET 实现**: Core 模块无任何平台特定依赖
- **节点扩展 Node Extensions**: Godot节点类的有用扩展 - **Godot 集成 Godot Integration**: GFramework.Godot 提供 Godot 特定功能
- **Godot日志器 Godot Logger**: Godot应用程序的专用日志系统 - **可移植 Portable**: 可以轻松移植到 Unity、.NET MAUI 等平台
## 项目 Projects ## 项目 Projects
### 核心项目 Core Projects ### 核心项目 Core Projects
- **GFramework.Core**: 核心框架功能 | 项目 | 说明 |
- **GFramework.Game**: 游戏特定抽象和系统 |----------------------------------|--------------------------------|
- **GFramework.Godot**: Godot特定实现 | **GFramework.Core** | 核心框架功能,包含架构、事件、命令、查询等(平台无关) |
| **GFramework.Core.Abstractions** | 核心接口定义 |
| **GFramework.Game** | 游戏特定抽象和系统 |
| **GFramework.Game.Abstractions** | 游戏抽象接口定义 |
| **GFramework.Godot** | Godot特定实现Node扩展、GodotLogger等 |
### 源代码生成器 Source Generators ### 源代码生成器 Source Generators
- **GFramework.SourceGenerators**: 自动代码生成的代码生成器 | 项目 | 说明 |
- **GFramework.Godot.SourceGenerators**: Godot特定的代码生成器 |---------------------------------------|---------------|
- **GFramework.SourceGenerators.Abstractions**: 源代码生成器的抽象 | **GFramework.SourceGenerators** | 通用源代码生成器 |
- **GFramework.Godot.SourceGenerators.Abstractions**: Godot特定的抽象 | **GFramework.Godot.SourceGenerators** | Godot特定的代码生成器 |
## 快速开始 Getting Started ## 快速开始 Getting Started
### 安装 Installation ### 安装 Installation
1. 安装NuGet包
```bash ```bash
# 安装核心包(平台无关)
dotnet add package GeWuYou.GFramework.Core dotnet add package GeWuYou.GFramework.Core
dotnet add package GeWuYou.GFramework.Core.Abstractions
# 安装游戏包
dotnet add package GeWuYou.GFramework.Game dotnet add package GeWuYou.GFramework.Game
dotnet add package GeWuYou.GFramework.SourceGenerators dotnet add package GeWuYou.GFramework.Game.Abstractions
# 安装Godot包仅Godot项目需要
dotnet add package GeWuYou.GFramework.Godot dotnet add package GeWuYou.GFramework.Godot
dotnet add package GeWuYou.GFramework.Godot.SourceGenerators
``` ```
### 基本使用 Basic Usage ### 基本使用 Basic Usage
```csharp ```csharp
// 创建架构实例 Create an architecture instance using GFramework.Core.architecture;
var architecture = new MyArchitecture();
// 初始化架构 Initialize the architecture // 1. 定义架构(继承 Architecture 基类)
await architecture.InitializeAsync(); public class GameArchitecture : Architecture
{
protected override void Init()
{
// 注册Model
RegisterModel(new PlayerModel());
RegisterModel(new GameModel());
// 注册System
RegisterSystem(new CombatSystem());
RegisterSystem(new UISystem());
// 注册Utility
RegisterUtility(new StorageUtility());
}
}
// 访问服务 Access services // 2. 创建并初始化架构
var service = architecture.Container.Resolve<IMyService>(); var architecture = new GameArchitecture();
architecture.Initialize();
// 3. 通过依赖注入在Controller中使用
public class PlayerController : IController
{
private readonly IArchitecture _architecture;
// 通过构造函数注入架构
public PlayerController(IArchitecture architecture)
{
_architecture = architecture;
}
public void Initialize()
{
var playerModel = _architecture.GetModel<PlayerModel>();
// 监听属性变化
playerModel.Health.RegisterWithInitValue(health =>
{
Console.WriteLine($"Health: {health}");
});
}
}
``` ```
### Godot集成 Godot Integration ### 命令和查询 Command & Query
```csharp ```csharp
// 使用Godot特定功能 Use Godot-specific features // 定义命令
[GodotLog] public class AttackCommand : AbstractCommand
public partial class MyGodotNode : Node
{ {
// 自动生成的日志器将可用 Auto-generated logger will be available protected override void OnExecute()
private readonly ILogger _log = Log.GetLogger("MyGodotNode");
public override void _Ready()
{ {
_log.Info("Node is ready!"); var playerModel = this.GetModel<PlayerModel>();
var enemyModel = this.GetModel<EnemyModel>();
// 业务逻辑
int damage = playerModel.AttackPower.Value;
enemyModel.Health.Value -= damage;
// 发送事件
this.SendEvent(new DamageDealtEvent(damage));
} }
} }
// 定义查询
public class CanAttackQuery : AbstractQuery<bool>
{
protected override bool OnDo()
{
var playerModel = this.GetModel<PlayerModel>();
return playerModel.Health.Value > 0 && !playerModel.IsStunned.Value;
}
}
// 使用命令和查询
public class CombatController : IController
{
private readonly IArchitecture _architecture;
public CombatController(IArchitecture architecture)
{
_architecture = architecture;
}
public void OnAttackButtonPressed()
{
// 先查询
if (_architecture.SendQuery(new CanAttackQuery()))
{
// 再执行命令
_architecture.SendCommand(new AttackCommand());
}
}
}
```
### 事件系统 Event System
```csharp
// 定义事件
public struct DamageDealtEvent
{
public int Damage;
public Vector3 Position;
}
// 发送事件
this.SendEvent(new DamageDealtEvent { Damage = 100, Position = position });
// 注册事件监听
this.RegisterEvent<DamageDealtEvent>(OnDamageDealt);
private void OnDamageDealt(DamageDealtEvent e)
{
ShowDamageNumber(e.Damage, e.Position);
}
``` ```
## 架构 Architecture ## 架构 Architecture
框架遵循清洁架构原则,具有以下层次: 框架遵循清洁架构原则,具有以下层次:
1. **核心层 Core Layer**: 基础抽象和接口 Fundamental abstractions and interfaces ```
2. **应用层 Application Layer**: 用例和应用服务 Use cases and application services ┌─────────────────────────────────────────┐
3. **基础设施层 Infrastructure Layer**: 外部依赖和实现 External dependencies and implementations │ View / UI │ UI 层:用户界面
4. **表示层 Presentation Layer**: UI和用户交互组件 UI and user interaction components ├─────────────────────────────────────────┤
│ Controller │ 控制层:处理用户输入
├─────────────────────────────────────────┤
│ System │ 逻辑层:业务逻辑
├─────────────────────────────────────────┤
│ Model │ 数据层:游戏状态
├─────────────────────────────────────────┤
│ Utility │ 工具层:无状态工具
├─────────────────────────────────────────┤
│ Command / Query │ 横切关注点
└─────────────────────────────────────────┘
```
## 生命周期 Lifecycle
```
初始化流程:
Init() → BeforeUtilityInit → AfterUtilityInit → BeforeModelInit → AfterModelInit → BeforeSystemInit → AfterSystemInit → Ready
销毁流程:
Destroy() → Destroying → Destroyed
```
## 平台集成 Platform Integration
### Godot 项目
```csharp
// 使用 GFramework.Godot 获取 Godot 特定功能
using GFramework.Godot;
public class GodotPlayerController : Node, IController
{
public IArchitecture GetArchitecture() => GameArchitecture.Interface;
public override void _Ready()
{
// 使用 Godot 特定的扩展方法
this.RegisterEvent<DamageDealtEvent>(OnDamageDealt)
.UnRegisterWhenNodeExitTree(this);
}
}
```
### 移植到其他平台
GFramework.Core 是纯 .NET 库,可以轻松移植到:
- Unity使用 Unity 容器替代 Godot 节点)
- .NET MAUI用于跨平台 UI 应用)
- 任何其他 .NET 应用
## 许可证 License ## 许可证 License
本项目基于Apache 2.0许可证 - 详情请参阅 [LICENSE](LICENSE) 文件。 本项目基于Apache 2.0许可证 - 详情请参阅 [LICENSE](LICENSE) 文件。
## 支持 Support
如需支持和问题,请在仓库中提交问题。
## 框架设计理念 Framework Design Philosophy ## 框架设计理念 Framework Design Philosophy
### 核心设计原则 Core Design Principles ### 核心设计原则 Core Design Principles
@ -124,17 +276,21 @@ public partial class MyGodotNode : Node
- **易于测试 Easy Testing**: 依赖注入和纯函数设计 - **易于测试 Easy Testing**: 依赖注入和纯函数设计
- **可扩展 Extensibility**: 基于接口的规则体系 - **可扩展 Extensibility**: 基于接口的规则体系
- **生命周期管理 Lifecycle Management**: 自动的注册和注销机制 - **生命周期管理 Lifecycle Management**: 自动的注册和注销机制
- **平台无关 Platform Agnostic**: Core 模块可移植到任何平台
## 技术栈 Technology Stack ## 技术栈 Technology Stack
- **.NET 6.0+**: 跨平台运行时 - **.NET 6.0+**: 跨平台运行时
- **Godot 4.x**: 游戏引擎
- **C#**: 主要编程语言 - **C#**: 主要编程语言
- **Source Generators**: 源代码生成技术 - **Source Generators**: 源代码生成技术
**Godot 集成**(可选):
- **Godot 4.x**: 游戏引擎
## 性能特性 Performance Features ## 性能特性 Performance Features
- **零GC allocations**: 使用结构体和对象池减少垃圾回收 - **零GC allocations**: 使用结构体和对象池减少垃圾回收
- **编译时生成**: 通过源代码生成器减少运行时开销 - **编译时生成**: 通过源代码生成器减少运行时开销
- **高效事件系统**: 类型安全的事件分发 - **高效事件系统**: 类型安全的事件分发
- **内存管理**: 自动生命周期管理和资源释放 - **内存管理**: 自动生命周期管理和资源释放