feat(docs): 添加 VitePress 文档生成技能系统

- 新增 .claude/skills 目录及完整的文档生成技能系统
- 添加批量 API 文档生成脚本支持模块化文档创建
- 添加 API 文档、功能指南和教程生成模板与示例
- 添加 C# XML 注释解析和代码示例生成工具
- 添加文档验证和导航更新脚本确保质量
- 更新 .gitignore 配置排除本地设置文件
This commit is contained in:
GeWuYou 2026-02-24 17:36:12 +08:00 committed by gewuyou
parent 7c71ed154e
commit bb449259d3
25 changed files with 3910 additions and 1 deletions

469
.claude/skills/README.md Normal file
View File

@ -0,0 +1,469 @@
# VitePress 文档生成 Skills 系统
为 GFramework 项目提供自动化的 VitePress 文档生成能力。
## 概述
这是一套专门为 GFramework 项目设计的文档生成 skills能够根据 C# 源代码自动生成高质量的 VitePress 文档。系统采用模块化设计,每个 skill 专注于特定的文档生成任务。
## 可用 Skills
### 1. vitepress-api-doc - API 文档生成
为单个 C# 文件生成 API 参考文档。
**用途**
- 类、接口、枚举的 API 文档
- 方法、属性、事件的详细说明
- 基于 XML 注释生成文档
**调用方式**
```bash
/vitepress-api-doc <C# 文件路径>
```
**示例**
```bash
/vitepress-api-doc GFramework.Core/architecture/Architecture.cs
```
**输出位置**`docs/zh-CN/api-reference/<模块>/<文件名>.md`
[详细文档](./vitepress-api-doc/SKILL.md)
---
### 2. vitepress-guide - 功能指南生成
生成功能模块的使用指南文档。
**用途**
- 核心功能模块的使用说明
- 设计模式和架构概念
- 最佳实践和常见问题
**调用方式**
```bash
/vitepress-guide <主题> <目标模块>
```
**示例**
```bash
/vitepress-guide "事件系统" Core
/vitepress-guide "IoC 容器" Core
```
**输出位置**`docs/zh-CN/<模块>/<主题>.md`
[详细文档](./vitepress-guide/SKILL.md)
---
### 3. vitepress-tutorial - 分步教程生成
生成分步教程文档,适合初学者学习。
**用途**
- 框架入门教程
- 功能实现教程
- 问题解决方案
**调用方式**
```bash
/vitepress-tutorial <教程主题>
```
**示例**
```bash
/vitepress-tutorial "创建第一个 System"
/vitepress-tutorial "使用事件系统"
```
**输出位置**`docs/zh-CN/tutorials/<主题>.md`
[详细文档](./vitepress-tutorial/SKILL.md)
---
### 4. vitepress-batch-api - 批量 API 文档生成
为整个模块批量生成 API 文档。
**用途**
- 初始化模块文档
- 更新整个模块的文档
- 快速生成大量文档
**调用方式**
```bash
/vitepress-batch-api <模块名>
```
**示例**
```bash
/vitepress-batch-api Core
/vitepress-batch-api Godot
```
**输出位置**`docs/zh-CN/api-reference/<模块>/`
[详细文档](./vitepress-batch-api/SKILL.md)
---
### 5. vitepress-validate - 文档验证
验证文档的质量和规范性。
**用途**
- Frontmatter 格式验证
- 内部链接有效性检查
- 代码块语法验证
- 标点符号规范检查
**调用方式**
```bash
/vitepress-validate <文件或目录路径>
```
**示例**
```bash
/vitepress-validate docs/zh-CN/api-reference/core/architecture.md
/vitepress-validate docs/zh-CN/
```
[详细文档](./vitepress-validate/SKILL.md)
---
## 快速开始
### 1. 生成单个 API 文档
```bash
# 为 Architecture 类生成文档
/vitepress-api-doc GFramework.Core/architecture/Architecture.cs
```
### 2. 批量生成模块文档
```bash
# 为整个 Core 模块生成文档
/vitepress-batch-api Core
```
### 3. 生成功能指南
```bash
# 生成事件系统使用指南
/vitepress-guide "事件系统" Core
```
### 4. 生成教程
```bash
# 生成创建 Model 的教程
/vitepress-tutorial "创建第一个 Model"
```
### 5. 验证文档
```bash
# 验证生成的文档
/vitepress-validate docs/zh-CN/api-reference/core/
```
## 工作流程
### 典型工作流程
```mermaid
graph TD
A[开始] --> B{文档类型?}
B -->|API 文档| C[/vitepress-api-doc]
B -->|功能指南| D[/vitepress-guide]
B -->|教程| E[/vitepress-tutorial]
C --> F[/vitepress-validate]
D --> F
E --> F
F --> G{验证通过?}
G -->|是| H[完成]
G -->|否| I[修复问题]
I --> F
```
### 推荐流程
1. **初始化模块文档**
```bash
/vitepress-batch-api Core
```
2. **生成功能指南**
```bash
/vitepress-guide "IoC 容器" Core
/vitepress-guide "事件系统" Core
```
3. **生成教程**
```bash
/vitepress-tutorial "创建第一个 Model"
/vitepress-tutorial "使用命令系统"
```
4. **验证所有文档**
```bash
/vitepress-validate docs/zh-CN/
```
## 目录结构
```
.claude/skills/
├── README.md # 本文件
├── _shared/ # 共享资源
│ └── scripts/ # 共享脚本
│ ├── update-vitepress-nav.sh # 更新导航配置
│ ├── parse-csharp-xml.sh # 解析 XML 注释
│ └── generate-examples.sh # 生成代码示例
├── vitepress-api-doc/ # API 文档生成
│ ├── SKILL.md # Skill 说明
│ ├── template.md # 文档模板
│ └── examples/ # 示例文档
│ ├── class-example.md
│ ├── interface-example.md
│ └── enum-example.md
├── vitepress-guide/ # 功能指南生成
│ ├── SKILL.md
│ ├── template.md
│ └── examples/
│ └── guide-example.md
├── vitepress-tutorial/ # 教程生成
│ ├── SKILL.md
│ ├── template.md
│ └── examples/
│ └── tutorial-example.md
├── vitepress-batch-api/ # 批量 API 文档生成
│ ├── SKILL.md
│ └── scripts/
│ └── batch-generate.sh
└── vitepress-validate/ # 文档验证
├── SKILL.md
└── scripts/
├── validate-frontmatter.sh
├── validate-links.sh
├── validate-code-blocks.sh
└── validate-all.sh
```
## 设计原则
### 1. 单一职责
每个 skill 专注于一个特定任务:
- `vitepress-api-doc` - 单文件 API 文档
- `vitepress-guide` - 功能指南
- `vitepress-tutorial` - 分步教程
- `vitepress-batch-api` - 批量生成
- `vitepress-validate` - 质量验证
### 2. 模块化设计
- 共享脚本放在 `_shared/scripts/`
- 每个 skill 独立维护
- 可以单独使用或组合使用
### 3. 基于源代码
- 仅使用 XML 注释,不添加 AI 补充
- 保持文档与代码同步
- 代码示例由 AI 自动生成
### 4. 质量保证
- 所有生成的文档都应通过验证
- 遵循 VitePress 规范
- 保持一致的文档风格
## 文档规范
### Frontmatter 格式
```yaml
---
title: 文档标题
description: 简短描述1-2 句话)
outline: deep # 可选
---
```
### 代码块标记
- C# 代码使用 `csharp`
- Bash 脚本使用 `bash`
- JSON 使用 `json`
- YAML 使用 `yaml`
### 泛型符号转义
在正文中使用 HTML 实体:
- `List<T>``List&lt;T&gt;`
- 代码块内保持原样
### 中文标点符号
- 中文句子使用全角标点:,。!?
- 英文句子使用半角标点:,.!?
- 代码周围使用半角符号
## 共享脚本
### update-vitepress-nav.sh
更新 VitePress 侧边栏导航配置。
**用法**
```bash
.claude/skills/_shared/scripts/update-vitepress-nav.sh <文件路径> <标题>
```
### parse-csharp-xml.sh
解析 C# XML 文档注释。
**用法**
```bash
.claude/skills/_shared/scripts/parse-csharp-xml.sh <C# 文件路径>
```
### generate-examples.sh
生成代码示例。
**用法**
```bash
.claude/skills/_shared/scripts/generate-examples.sh <类型名> <命名空间>
```
## 最佳实践
### 1. 文档生成顺序
1. 先生成 API 文档(基础)
2. 再生成功能指南(概念)
3. 最后生成教程(实践)
### 2. 保持文档同步
- 修改代码后及时更新文档
- 使用单文件生成更新特定文档
- 定期批量验证所有文档
### 3. 质量控制
- 生成后立即验证
- 修复所有错误和警告
- 确保链接有效
### 4. 版本控制
- 将生成的文档提交到 Git
- 在 PR 中包含文档更新
- 保持文档与代码版本一致
## 故障排除
### 问题:生成的文档缺少内容
**原因**:源代码缺少 XML 注释
**解决方案**
1. 在源代码中添加 XML 注释
2. 重新生成文档
### 问题:验证失败
**原因**:文档格式不符合规范
**解决方案**
1. 查看验证错误信息
2. 根据提示修复问题
3. 重新验证
### 问题:链接损坏
**原因**:文件路径错误或文件不存在
**解决方案**
1. 检查链接的目标文件是否存在
2. 修正文件路径
3. 重新验证
### 问题:批量生成速度慢
**原因**:文件数量多
**解决方案**
1. 使用 `--parallel` 选项(如果支持)
2. 分批生成
3. 仅生成修改的文件
## 扩展开发
### 添加新 Skill
1. 在 `.claude/skills/` 下创建新目录
2. 创建 `SKILL.md` 说明文档
3. 创建必要的模板和脚本
4. 在本 README 中添加说明
### 修改现有 Skill
1. 更新 `SKILL.md` 文档
2. 修改模板或脚本
3. 更新示例文档
4. 测试修改后的功能
## 贡献指南
### 报告问题
在 GitHub Issues 中报告问题,包含:
- 使用的 skill 名称
- 输入参数
- 预期结果
- 实际结果
- 错误信息
### 提交改进
1. Fork 项目
2. 创建功能分支
3. 提交修改
4. 创建 Pull Request
## 版本历史
- v1.0.0 (2025-01-XX) - 初始版本
- 5 个核心 skills
- 3 个共享脚本
- 完整的文档和示例
## 许可证
与 GFramework 项目保持一致。
## 联系方式
如有问题或建议,请通过以下方式联系:
- GitHub Issues
- 项目讨论区
---
**注意**:本 skills 系统专为 GFramework 项目设计,使用前请确保了解项目结构和文档规范。

View File

@ -0,0 +1,38 @@
#!/bin/bash
# 生成代码示例辅助脚本
# 用法: generate-examples.sh <类型> <类名>
set -e
TYPE="$1" # class/interface/enum
CLASS_NAME="$2"
if [ -z "$TYPE" ] || [ -z "$CLASS_NAME" ]; then
echo "用法: $0 <类型> <类名>"
echo "类型: class, interface, enum"
exit 1
fi
echo "生成 $CLASS_NAME 的示例代码..."
echo "类型: $TYPE"
# 注意: 此脚本仅输出提示信息
# 实际的示例代码生成由 AI 根据 API 签名和现有教程风格完成
case "$TYPE" in
class)
echo "提示: 为类生成示例,包括实例化、方法调用、属性访问"
;;
interface)
echo "提示: 为接口生成示例,包括实现类和使用方式"
;;
enum)
echo "提示: 为枚举生成示例,包括值比较和 switch 语句"
;;
*)
echo "错误: 不支持的类型: $TYPE"
exit 1
;;
esac
exit 0

View File

@ -0,0 +1,48 @@
#!/bin/bash
# 解析 C# XML 文档注释
# 用法: parse-csharp-xml.sh <C# 文件路径>
set -e
FILE_PATH="$1"
if [ -z "$FILE_PATH" ]; then
echo "用法: $0 <C# 文件路径>"
exit 1
fi
if [ ! -f "$FILE_PATH" ]; then
echo "错误: 文件不存在: $FILE_PATH"
exit 1
fi
echo "解析 C# XML 文档注释: $FILE_PATH"
# 提取 summary 标签内容
echo "=== Summary ==="
grep -A 5 "/// <summary>" "$FILE_PATH" | grep "///" | sed 's/.*\/\/\/\s*//' | sed 's/<summary>//g' | sed 's/<\/summary>//g' || echo "未找到 summary"
# 提取 param 标签内容
echo ""
echo "=== Parameters ==="
grep "/// <param" "$FILE_PATH" | sed 's/.*\/\/\/\s*//' || echo "未找到 param"
# 提取 returns 标签内容
echo ""
echo "=== Returns ==="
grep "/// <returns>" "$FILE_PATH" | sed 's/.*\/\/\/\s*//' | sed 's/<returns>//g' | sed 's/<\/returns>//g' || echo "未找到 returns"
# 提取 exception 标签内容
echo ""
echo "=== Exceptions ==="
grep "/// <exception" "$FILE_PATH" | sed 's/.*\/\/\/\s*//' || echo "未找到 exception"
# 提取 example 标签内容
echo ""
echo "=== Examples ==="
grep -A 10 "/// <example>" "$FILE_PATH" | grep "///" | sed 's/.*\/\/\/\s*//' || echo "未找到 example"
echo ""
echo "解析完成"
exit 0

View File

@ -0,0 +1,42 @@
#!/bin/bash
# 更新 VitePress 侧边栏配置
# 用法: update-vitepress-nav.sh <文档路径> <文档标题>
set -e
DOC_PATH="$1"
DOC_TITLE="$2"
CONFIG_FILE="docs/.vitepress/config.mts"
if [ -z "$DOC_PATH" ] || [ -z "$DOC_TITLE" ]; then
echo "用法: $0 <文档路径> <文档标题>"
echo "示例: $0 /zh-CN/api-reference/core/architecture.md Architecture"
exit 1
fi
if [ ! -f "$CONFIG_FILE" ]; then
echo "错误: 找不到 VitePress 配置文件: $CONFIG_FILE"
exit 1
fi
# 提取模块名称core/game/godot/source-generators
MODULE=$(echo "$DOC_PATH" | grep -oP '(?<=/zh-CN/)[^/]+' | head -1)
if [ -z "$MODULE" ]; then
echo "错误: 无法从路径中提取模块名称: $DOC_PATH"
exit 1
fi
echo "正在更新 VitePress 配置..."
echo " 模块: $MODULE"
echo " 路径: $DOC_PATH"
echo " 标题: $DOC_TITLE"
# 注意: 此脚本仅输出提示信息
# 实际的配置更新由 AI 直接编辑 config.mts 文件完成
# 因为 TypeScript 配置文件的复杂性,使用脚本解析和修改容易出错
echo "提示: 请手动更新 $CONFIG_FILE 中的侧边栏配置"
echo "或者让 AI 使用 Edit 工具直接修改配置文件"
exit 0

View File

@ -0,0 +1,210 @@
# VitePress API 文档生成
为单个 C# 类、接口或枚举生成符合 VitePress 标准的 API 参考文档。
## 用途
此 skill 用于从 C# 源代码文件自动生成结构化的 API 文档,包括:
- 类型概述和命名空间信息
- 构造函数、方法、属性的详细说明
- 基于 XML 文档注释的描述
- 自动生成的使用示例
- 相关类型的交叉引用
## 调用方式
```bash
/vitepress-api-doc <C# 文件路径>
```
**示例**
```bash
/vitepress-api-doc GFramework.Core/architecture/Architecture.cs
```
## 工作流程
1. **读取源代码文件**
- 验证文件存在且为 C# 文件
- 读取完整的源代码内容
2. **解析代码结构**
- 提取命名空间、类名、访问修饰符
- 识别类型class/interface/enum/struct
- 解析继承关系和实现的接口
- 提取所有公共成员(构造函数、方法、属性、事件、字段)
3. **提取 XML 文档注释**
- 解析 `/// <summary>` 标签(类型和成员描述)
- 解析 `/// <param>` 标签(参数说明)
- 解析 `/// <returns>` 标签(返回值说明)
- 解析 `/// <exception>` 标签(异常说明)
- 解析 `/// <example>` 标签(示例代码)
- 解析 `/// <see cref=""/>` 标签(交叉引用)
4. **生成 Markdown 文档**
- 根据 `template.md` 填充内容
- 转义泛型符号(`<T>``&lt;T&gt;`
- 生成使用示例(基于 API 签名)
- 添加相关文档链接
5. **确定输出路径**
- 根据命名空间确定模块Core/Game/Godot/SourceGenerators
- 输出到 `docs/zh-CN/api-reference/<模块>/<类名>.md`
6. **更新 VitePress 配置**
- 调用共享脚本 `update-vitepress-nav.sh`
- 在侧边栏配置中添加新文档条目
7. **验证文档质量**
- 检查 Frontmatter 格式
- 验证内部链接
- 确保代码块语法正确
## 输出规范
### Frontmatter 格式
```yaml
---
title: 类名
description: 从 XML <summary> 提取的简短描述
outline: deep
---
```
### 文档结构
1. **标题**:使用类名作为一级标题
2. **概述**XML summary 内容
3. **命名空间和程序集信息**
4. **继承链**(如果适用)
5. **构造函数**(如果有)
6. **公共方法**(按字母顺序)
7. **公共属性**(按字母顺序)
8. **公共事件**(如果有)
9. **使用示例**(自动生成)
10. **另请参阅**(相关类型链接)
### 代码块格式
所有 C# 代码块必须使用:
```markdown
\`\`\`csharp
// 代码内容
\`\`\`
```
### 泛型符号转义
- `List<T>``List&lt;T&gt;`
- `Dictionary<K, V>``Dictionary&lt;K, V&gt;`
- `IEnumerable<T>``IEnumerable&lt;T&gt;`
### 内部链接格式
- 相对路径:`[Architecture](./architecture.md)`
- 绝对路径:`[Core 架构](/zh-CN/core/architecture)`
- 锚点链接:`[构造函数](#构造函数)`
## 前置条件
1. 项目必须有 VitePress 配置文件(`docs/.vitepress/config.mts`
2. 目标 C# 文件必须存在且可读
3. C# 文件必须包含 XML 文档注释(`///`
4. 文件必须包含至少一个公共类型
## 配置选项
### 自动检测模块
根据命名空间自动确定模块:
- `GFramework.Core.*``core`
- `GFramework.Game.*``game`
- `GFramework.Godot.*``godot`
- `GFramework.SourceGenerators.*``source-generators`
### 示例生成策略
- **基本用法**:最简单的 API 调用
- **常见场景**:实际应用案例
- **高级用法**:复杂配置(如果适用)
## 示例输出
参考 `examples/` 目录中的示例文档:
- `class-example.md` - 类文档示例
- `interface-example.md` - 接口文档示例
- `enum-example.md` - 枚举文档示例
## 注意事项
1. **仅使用 XML 注释**:不对缺失的注释进行 AI 补充
2. **仅提取公共成员**:忽略 `internal``private``protected` 成员
3. **保持文档同步**:文档内容直接来源于代码,确保准确性
4. **遵循项目风格**:参考现有文档的格式和术语
## 相关 Skills
- `/vitepress-validate` - 验证生成的文档质量
- `/vitepress-batch-api` - 批量生成整个模块的 API 文档
## 技术细节
### XML 注释标签映射
| XML 标签 | Markdown 输出 |
|---------|--------------|
| `<summary>` | 概述章节 |
| `<param name="x">` | 参数列表 |
| `<returns>` | 返回值说明 |
| `<exception cref="T">` | 异常列表 |
| `<example>` | 示例代码块 |
| `<see cref="T"/>` | 内部链接 |
| `<remarks>` | 备注章节 |
### 成员签名格式
**方法**
```markdown
### MethodName
描述内容
**签名**
\`\`\`csharp
public ReturnType MethodName(ParamType param)
\`\`\`
**参数**
- `param` (ParamType): 参数说明
**返回值**
- (ReturnType): 返回值说明
```
**属性**
```markdown
### PropertyName
描述内容
**类型**`PropertyType`
**访问**get / set
```
## 故障排除
### 问题:找不到 XML 注释
**解决方案**:确保 C# 文件包含 `///` 注释,而不是 `//``/* */`
### 问题:泛型符号显示错误
**解决方案**VitePress 配置中已包含 `safeGenericEscapePlugin`,确保正确转义
### 问题:侧边栏未更新
**解决方案**:检查 `update-vitepress-nav.sh` 脚本是否正确执行
## 版本历史
- v1.0.0 - 初始版本,支持类、接口、枚举的文档生成

View File

@ -0,0 +1,252 @@
---
title: Architecture
description: 架构基类,提供系统、模型、工具等组件的注册与管理功能。专注于生命周期管理、初始化流程控制和架构阶段转换。
outline: deep
---
# Architecture
## 概述
架构基类,提供系统、模型、工具等组件的注册与管理功能。专注于生命周期管理、初始化流程控制和架构阶段转换。
**命名空间**`GFramework.Core.architecture`
**程序集**`GFramework.Core`
**继承**`Object``Architecture`
**实现**`IArchitecture`
## 构造函数
### Architecture
创建架构实例。
**签名**
```csharp
public Architecture(
IArchitectureConfiguration? configuration = null,
IEnvironment? environment = null,
IArchitectureServices? services = null,
IArchitectureContext? context = null
)
```
**参数**
- `configuration` (IArchitectureConfiguration?): 架构配置对象,为 null 时使用默认配置
- `environment` (IEnvironment?): 环境配置对象,为 null 时使用默认环境
- `services` (IArchitectureServices?): 架构服务对象,为 null 时创建新实例
- `context` (IArchitectureContext?): 架构上下文对象,为 null 时创建新实例
## 公共方法
### Initialize
同步初始化架构,阻塞当前线程直到初始化完成。
**签名**
```csharp
public void Initialize()
```
**特点**
- 阻塞式初始化
- 适用于简单场景或控制台应用
- 初始化失败时抛出异常并进入 `FailedInitialization` 阶段
### InitializeAsync
异步初始化架构,返回 Task 以便调用者可以等待初始化完成。
**签名**
```csharp
public async Task InitializeAsync()
```
**返回值**
- (Task): 表示异步初始化操作的任务
**特点**
- 非阻塞式初始化
- 支持异步组件初始化
- 适用于需要异步加载资源的场景
### InstallModule
安装架构模块,用于扩展架构功能。
**签名**
```csharp
public IArchitectureModule InstallModule(IArchitectureModule module)
```
**参数**
- `module` (IArchitectureModule): 要安装的模块实例
**返回值**
- (IArchitectureModule): 返回安装的模块实例
### RegisterSystem
注册系统组件到架构中。
**签名**
```csharp
public void RegisterSystem<TSystem>(TSystem system) where TSystem : ISystem
```
**类型参数**
- `TSystem`: 系统类型,必须实现 ISystem 接口
**参数**
- `system` (TSystem): 要注册的系统实例
### RegisterModel
注册模型组件到架构中。
**签名**
```csharp
public void RegisterModel<TModel>(TModel model) where TModel : IModel
```
**类型参数**
- `TModel`: 模型类型,必须实现 IModel 接口
**参数**
- `model` (TModel): 要注册的模型实例
### RegisterUtility
注册工具组件到架构中。
**签名**
```csharp
public void RegisterUtility<TUtility>(TUtility utility) where TUtility : IUtility
```
**类型参数**
- `TUtility`: 工具类型,必须实现 IUtility 接口
**参数**
- `utility` (TUtility): 要注册的工具实例
### SendCommand
发送并执行命令。
**签名**
```csharp
public void SendCommand(ICommand command)
```
**参数**
- `command` (ICommand): 要执行的命令实例
### SendCommand&lt;TResult&gt;
发送并执行带返回值的命令。
**签名**
```csharp
public TResult SendCommand<TResult>(ICommand<TResult> command)
```
**类型参数**
- `TResult`: 命令返回值类型
**参数**
- `command` (ICommand&lt;TResult&gt;): 要执行的命令实例
**返回值**
- (TResult): 命令执行结果
## 公共属性
### CurrentPhase
获取当前架构的阶段。
**类型**`ArchitecturePhase`
**访问**get
### Context
获取架构上下文,提供对架构服务的访问。
**类型**`IArchitectureContext`
**访问**get
### IsReady
获取一个布尔值,指示当前架构是否处于就绪状态。
**类型**`bool`
**访问**get
## 使用示例
### 基本用法
```csharp
// 1. 定义你的架构(继承 Architecture 基类)
public class GameArchitecture : Architecture
{
protected override void Init()
{
// 注册 Model
RegisterModel(new PlayerModel());
RegisterModel(new InventoryModel());
// 注册 System
RegisterSystem(new GameplaySystem());
RegisterSystem(new SaveSystem());
// 注册 Utility
RegisterUtility(new StorageUtility());
RegisterUtility(new TimeUtility());
}
}
// 2. 创建并初始化架构
var architecture = new GameArchitecture();
architecture.Initialize();
// 3. 等待架构就绪
await architecture.WaitUntilReadyAsync();
```
### 异步初始化
```csharp
var architecture = new GameArchitecture();
await architecture.InitializeAsync(); // 异步等待初始化完成
// 检查架构是否已就绪
if (architecture.IsReady)
{
Console.WriteLine("架构已就绪,可以开始游戏");
}
```
### 使用自定义配置
```csharp
var config = new ArchitectureConfiguration
{
ArchitectureProperties = new ArchitectureProperties
{
StrictPhaseValidation = true, // 启用严格阶段验证
AllowLateRegistration = false // 禁止就绪后注册组件
}
};
var architecture = new GameArchitecture(configuration: config);
architecture.Initialize();
```
## 另请参阅
- [IArchitecture](./iarchitecture.md) - 架构接口
- [ArchitecturePhase](./architecture-phase.md) - 架构阶段枚举
- [IArchitectureModule](./iarchitecture-module.md) - 架构模块接口
- [架构组件](/zh-CN/core/architecture) - 架构使用指南

View File

@ -0,0 +1,193 @@
---
title: ArchitecturePhase
description: 架构阶段枚举,定义了架构生命周期的各个阶段。
outline: deep
---
# ArchitecturePhase
## 概述
架构阶段枚举,定义了架构生命周期的各个阶段。
**命名空间**`GFramework.Core.Abstractions.enums`
**程序集**`GFramework.Core.Abstractions`
**基础类型**`Enum`
## 枚举值
### None
初始阶段,架构尚未开始初始化。
**值**`0`
### BeforeUtilityInit
工具初始化前阶段。
**值**`1`
### AfterUtilityInit
工具初始化后阶段。
**值**`2`
### BeforeModelInit
模型初始化前阶段。
**值**`3`
### AfterModelInit
模型初始化后阶段。
**值**`4`
### BeforeSystemInit
系统初始化前阶段。
**值**`5`
### AfterSystemInit
系统初始化后阶段。
**值**`6`
### Ready
就绪状态,架构已完全初始化并可以使用。
**值**`7`
### FailedInitialization
初始化失败状态。
**值**`8`
### Destroying
正在销毁阶段。
**值**`9`
### Destroyed
已销毁阶段。
**值**`10`
## 使用示例
### 检查架构阶段
```csharp
var architecture = new GameArchitecture();
architecture.Initialize();
// 检查架构是否已就绪
if (architecture.CurrentPhase == ArchitecturePhase.Ready)
{
Console.WriteLine("架构已就绪,可以开始游戏");
}
```
### 监听阶段变化
```csharp
public class PhaseMonitor : IArchitectureLifecycle
{
public void OnPhase(ArchitecturePhase phase, IArchitecture architecture)
{
switch (phase)
{
case ArchitecturePhase.BeforeUtilityInit:
Console.WriteLine("开始初始化工具");
break;
case ArchitecturePhase.AfterUtilityInit:
Console.WriteLine("工具初始化完成");
break;
case ArchitecturePhase.BeforeModelInit:
Console.WriteLine("开始初始化模型");
break;
case ArchitecturePhase.AfterModelInit:
Console.WriteLine("模型初始化完成");
break;
case ArchitecturePhase.BeforeSystemInit:
Console.WriteLine("开始初始化系统");
break;
case ArchitecturePhase.AfterSystemInit:
Console.WriteLine("系统初始化完成");
break;
case ArchitecturePhase.Ready:
Console.WriteLine("架构就绪");
break;
case ArchitecturePhase.FailedInitialization:
Console.WriteLine("架构初始化失败");
break;
case ArchitecturePhase.Destroying:
Console.WriteLine("架构正在销毁");
break;
case ArchitecturePhase.Destroyed:
Console.WriteLine("架构已销毁");
break;
}
}
}
// 注册监听器
var architecture = new GameArchitecture();
architecture.RegisterLifecycleHook(new PhaseMonitor());
architecture.Initialize();
```
### 等待特定阶段
```csharp
public async Task WaitForReady(IArchitecture architecture)
{
while (architecture.CurrentPhase != ArchitecturePhase.Ready)
{
if (architecture.CurrentPhase == ArchitecturePhase.FailedInitialization)
{
throw new Exception("架构初始化失败");
}
await Task.Delay(100);
}
Console.WriteLine("架构已就绪");
}
```
## 阶段转换顺序
正常初始化流程的阶段转换顺序:
1. `None``BeforeUtilityInit`
2. `BeforeUtilityInit``AfterUtilityInit`
3. `AfterUtilityInit``BeforeModelInit`
4. `BeforeModelInit``AfterModelInit`
5. `AfterModelInit``BeforeSystemInit`
6. `BeforeSystemInit``AfterSystemInit`
7. `AfterSystemInit``Ready`
销毁流程的阶段转换顺序:
1. `Ready``Destroying`
2. `Destroying``Destroyed`
异常流程:
- 任何阶段 → `FailedInitialization`(初始化过程中发生异常)
## 另请参阅
- [Architecture](./architecture.md) - 架构基类
- [IArchitectureLifecycle](./iarchitecture-lifecycle.md) - 生命周期钩子接口
- [架构组件](/zh-CN/core/architecture) - 架构使用指南

View File

@ -0,0 +1,290 @@
---
title: IArchitecture
description: 架构接口,定义了框架的核心功能契约。
outline: deep
---
# IArchitecture
## 概述
架构接口,定义了框架的核心功能契约。
**命名空间**`GFramework.Core.Abstractions.architecture`
**程序集**`GFramework.Core.Abstractions`
**实现类**[Architecture](./architecture.md)
## 公共方法
### RegisterSystem&lt;TSystem&gt;
注册系统组件到架构中。
**签名**
```csharp
void RegisterSystem<TSystem>(TSystem system) where TSystem : ISystem
```
**类型参数**
- `TSystem`: 系统类型,必须实现 ISystem 接口
**参数**
- `system` (TSystem): 要注册的系统实例
### RegisterModel&lt;TModel&gt;
注册模型组件到架构中。
**签名**
```csharp
void RegisterModel<TModel>(TModel model) where TModel : IModel
```
**类型参数**
- `TModel`: 模型类型,必须实现 IModel 接口
**参数**
- `model` (TModel): 要注册的模型实例
### RegisterUtility&lt;TUtility&gt;
注册工具组件到架构中。
**签名**
```csharp
void RegisterUtility<TUtility>(TUtility utility) where TUtility : IUtility
```
**类型参数**
- `TUtility`: 工具类型,必须实现 IUtility 接口
**参数**
- `utility` (TUtility): 要注册的工具实例
### GetModel&lt;T&gt;
从容器中获取已注册的模型。
**签名**
```csharp
T GetModel<T>() where T : class, IModel
```
**类型参数**
- `T`: 模型类型
**返回值**
- (T): 模型实例
### GetSystem&lt;T&gt;
从容器中获取已注册的系统。
**签名**
```csharp
T GetSystem<T>() where T : class, ISystem
```
**类型参数**
- `T`: 系统类型
**返回值**
- (T): 系统实例
### GetUtility&lt;T&gt;
从容器中获取已注册的工具。
**签名**
```csharp
T GetUtility<T>() where T : class, IUtility
```
**类型参数**
- `T`: 工具类型
**返回值**
- (T): 工具实例
### SendCommand
发送并执行命令。
**签名**
```csharp
void SendCommand(ICommand command)
```
**参数**
- `command` (ICommand): 要执行的命令实例
### SendCommand&lt;TResult&gt;
发送并执行带返回值的命令。
**签名**
```csharp
TResult SendCommand<TResult>(ICommand<TResult> command)
```
**类型参数**
- `TResult`: 命令返回值类型
**参数**
- `command` (ICommand&lt;TResult&gt;): 要执行的命令实例
**返回值**
- (TResult): 命令执行结果
### SendQuery&lt;TResult&gt;
发送并执行查询。
**签名**
```csharp
TResult SendQuery<TResult>(IQuery<TResult> query)
```
**类型参数**
- `TResult`: 查询返回值类型
**参数**
- `query` (IQuery&lt;TResult&gt;): 要执行的查询实例
**返回值**
- (TResult): 查询结果
### SendEvent&lt;T&gt;
发送事件(无参数)。
**签名**
```csharp
void SendEvent<T>() where T : new()
```
**类型参数**
- `T`: 事件类型,必须有无参构造函数
### SendEvent&lt;T&gt;
发送事件(带参数)。
**签名**
```csharp
void SendEvent<T>(T e)
```
**类型参数**
- `T`: 事件类型
**参数**
- `e` (T): 事件实例
### RegisterEvent&lt;T&gt;
注册事件监听器。
**签名**
```csharp
IUnRegister RegisterEvent<T>(Action<T> onEvent)
```
**类型参数**
- `T`: 事件类型
**参数**
- `onEvent` (Action&lt;T&gt;): 事件处理回调
**返回值**
- (IUnRegister): 用于注销事件的对象
### UnRegisterEvent&lt;T&gt;
注销事件监听器。
**签名**
```csharp
void UnRegisterEvent<T>(Action<T> onEvent)
```
**类型参数**
- `T`: 事件类型
**参数**
- `onEvent` (Action&lt;T&gt;): 要注销的事件处理回调
## 公共属性
### CurrentPhase
获取当前架构的阶段。
**类型**`ArchitecturePhase`
**访问**get
### Context
获取架构上下文。
**类型**`IArchitectureContext`
**访问**get
## 使用示例
### 在 Controller 中使用
```csharp
public class GameController : IController
{
public IArchitecture GetArchitecture() => GameArchitecture.Interface;
public void Start()
{
// 获取 Model
var playerModel = this.GetModel<PlayerModel>();
// 发送命令
this.SendCommand(new StartGameCommand());
// 发送查询
var score = this.SendQuery(new GetScoreQuery());
// 注册事件
this.RegisterEvent<PlayerDiedEvent>(OnPlayerDied);
}
private void OnPlayerDied(PlayerDiedEvent e)
{
// 处理玩家死亡事件
}
}
```
### 实现自定义架构
```csharp
public class GameArchitecture : Architecture
{
// 单例访问
public static IArchitecture Interface { get; private set; }
protected override void Init()
{
Interface = this;
// 注册组件
RegisterModel(new PlayerModel());
RegisterSystem(new GameplaySystem());
RegisterUtility(new StorageUtility());
}
}
```
## 另请参阅
- [Architecture](./architecture.md) - 架构基类实现
- [IModel](./imodel.md) - 模型接口
- [ISystem](./isystem.md) - 系统接口
- [IUtility](./iutility.md) - 工具接口
- [架构组件](/zh-CN/core/architecture) - 架构使用指南

View File

@ -0,0 +1,37 @@
---
title: {{CLASS_NAME}}
description: {{XML_SUMMARY}}
outline: deep
---
# {{CLASS_NAME}}
## 概述
{{XML_SUMMARY}}
**命名空间**`{{NAMESPACE}}`
**程序集**`{{ASSEMBLY}}`
{{INHERITANCE_CHAIN}}
## 构造函数
{{CONSTRUCTORS}}
## 公共方法
{{PUBLIC_METHODS}}
## 公共属性
{{PUBLIC_PROPERTIES}}
{{PUBLIC_EVENTS}}
## 使用示例
{{AUTO_GENERATED_EXAMPLES}}
## 另请参阅
{{RELATED_TYPES}}

View File

@ -0,0 +1,364 @@
# VitePress 批量 API 文档生成
为整个模块批量生成 API 参考文档,提高文档生成效率。
## 用途
此 skill 用于批量生成模块的 API 文档,适用于:
- 初始化模块文档
- 更新整个模块的文档
- 为新模块快速生成文档
- 重新生成所有 API 文档
## 调用方式
```bash
/vitepress-batch-api <模块名>
```
**示例**
```bash
/vitepress-batch-api Core
/vitepress-batch-api Game
/vitepress-batch-api Godot
/vitepress-batch-api SourceGenerators
```
## 工作流程
1. **扫描模块目录**
- 根据模块名确定源代码目录
- 递归扫描所有 C# 文件
2. **过滤目标文件**
- 仅包含公共类型public class/interface/enum/struct
- 排除内部类型internal
- 排除生成的代码(*.g.cs、*.Designer.cs
- 排除测试文件(*.Tests.cs
3. **批量生成文档**
- 为每个类型调用 `/vitepress-api-doc`
- 显示进度信息
- 收集生成结果
4. **生成模块索引页**
- 创建 `index.md` 列出所有 API
- 按类别分组(类、接口、枚举)
- 添加简短描述
5. **批量更新导航**
- 在 VitePress 配置中添加所有新文档
- 保持字母顺序
- 更新模块索引
6. **生成摘要报告**
- 统计生成的文档数量
- 列出成功和失败的文件
- 提供验证建议
## 输出规范
### 模块索引页格式
```markdown
---
title: Core API 参考
description: GFramework.Core 模块的 API 参考文档
---
# Core API 参考
## 概述
GFramework.Core 是框架的核心模块,提供架构基础、依赖注入、事件系统等核心功能。
## 类
- [Architecture](./architecture.md) - 架构基类
- [ArchitectureConfiguration](./architecture-configuration.md) - 架构配置
- [IocContainer](./ioc-container.md) - IoC 容器
## 接口
- [IArchitecture](./iarchitecture.md) - 架构接口
- [IModel](./imodel.md) - 模型接口
- [ISystem](./isystem.md) - 系统接口
## 枚举
- [ArchitecturePhase](./architecture-phase.md) - 架构阶段
```
### 目录结构
```
docs/zh-CN/api-reference/
├── core/
│ ├── index.md # 模块索引
│ ├── architecture.md
│ ├── iarchitecture.md
│ └── ...
├── game/
│ ├── index.md
│ └── ...
└── godot/
├── index.md
└── ...
```
## 模块映射
### 源代码目录映射
| 模块名 | 源代码目录 | 输出目录 |
|--------|-----------|---------|
| Core | `GFramework.Core/` | `docs/zh-CN/api-reference/core/` |
| Game | `GFramework.Game/` | `docs/zh-CN/api-reference/game/` |
| Godot | `GFramework.Godot/` | `docs/zh-CN/api-reference/godot/` |
| SourceGenerators | `GFramework.SourceGenerators/` | `docs/zh-CN/api-reference/source-generators/` |
### 命名空间映射
- `GFramework.Core.*` → Core 模块
- `GFramework.Game.*` → Game 模块
- `GFramework.Godot.*` → Godot 模块
- `GFramework.SourceGenerators.*` → SourceGenerators 模块
## 过滤规则
### 包含的文件
- 公共类public class
- 公共接口public interface
- 公共枚举public enum
- 公共结构体public struct
### 排除的文件
- 内部类型internal
- 生成的代码(`*.g.cs``*.Designer.cs`
- 测试文件(`*.Tests.cs``*Test.cs`
- 临时文件(`*.tmp.cs`
- 编译器生成的文件(`AssemblyInfo.cs`
### 排除的类型
- 编译器生成的类型(`<>c__DisplayClass`
- 匿名类型
- 嵌套的私有类型
## 批量处理脚本
### batch-generate.sh
```bash
#!/bin/bash
# 批量生成 API 文档
# 用法: batch-generate.sh <模块名>
set -e
MODULE="$1"
if [ -z "$MODULE" ]; then
echo "用法: $0 <模块名>"
echo "可用模块: Core, Game, Godot, SourceGenerators"
exit 1
fi
# 确定源代码目录
case "$MODULE" in
Core)
SOURCE_DIR="GFramework.Core"
;;
Game)
SOURCE_DIR="GFramework.Game"
;;
Godot)
SOURCE_DIR="GFramework.Godot"
;;
SourceGenerators)
SOURCE_DIR="GFramework.SourceGenerators"
;;
*)
echo "错误: 未知的模块: $MODULE"
exit 1
;;
esac
if [ ! -d "$SOURCE_DIR" ]; then
echo "错误: 源代码目录不存在: $SOURCE_DIR"
exit 1
fi
echo "=========================================="
echo "批量生成 $MODULE 模块的 API 文档"
echo "=========================================="
echo ""
# 查找所有 C# 文件
FILES=$(find "$SOURCE_DIR" -name "*.cs" -type f \
! -name "*.g.cs" \
! -name "*.Designer.cs" \
! -name "*Test.cs" \
! -name "*.Tests.cs" \
! -name "AssemblyInfo.cs")
FILE_COUNT=$(echo "$FILES" | wc -l)
echo "找到 $FILE_COUNT 个文件"
echo ""
GENERATED=0
SKIPPED=0
FAILED=0
for FILE in $FILES; do
echo "处理: $FILE"
# 检查是否包含公共类型
if ! grep -q "public \(class\|interface\|enum\|struct\)" "$FILE"; then
echo " ⊘ 跳过(无公共类型)"
SKIPPED=$((SKIPPED + 1))
continue
fi
# 调用 vitepress-api-doc由 AI 执行)
# /vitepress-api-doc "$FILE"
if [ $? -eq 0 ]; then
echo " ✓ 生成成功"
GENERATED=$((GENERATED + 1))
else
echo " ✗ 生成失败"
FAILED=$((FAILED + 1))
fi
echo ""
done
echo "=========================================="
echo "批量生成完成"
echo "=========================================="
echo "总文件数: $FILE_COUNT"
echo "生成成功: $GENERATED"
echo "跳过: $SKIPPED"
echo "失败: $FAILED"
echo ""
if [ $FAILED -eq 0 ]; then
echo "✓ 所有文档生成成功"
exit 0
else
echo "✗ 部分文档生成失败"
exit 1
fi
```
## 配置选项
### 过滤选项
```bash
# 包含内部类型
/vitepress-batch-api Core --include-internal
# 包含生成的代码
/vitepress-batch-api Core --include-generated
# 自定义过滤规则
/vitepress-batch-api Core --exclude "*.Tests.cs" --exclude "*.g.cs"
```
### 输出选项
```bash
# 指定输出目录
/vitepress-batch-api Core --output docs/zh-CN/api-reference/core/
# 覆盖现有文档
/vitepress-batch-api Core --force
# 仅生成索引页
/vitepress-batch-api Core --index-only
```
### 并行处理
```bash
# 并行生成(加快速度)
/vitepress-batch-api Core --parallel 4
```
## 进度显示
### 实时进度
```
========================================
批量生成 Core 模块的 API 文档
========================================
找到 45 个文件
[1/45] 处理: GFramework.Core/architecture/Architecture.cs
✓ 生成成功
[2/45] 处理: GFramework.Core/architecture/IArchitecture.cs
✓ 生成成功
[3/45] 处理: GFramework.Core/command/Command.cs
⊘ 跳过(无公共类型)
...
[45/45] 处理: GFramework.Core/utility/Utility.cs
✓ 生成成功
========================================
批量生成完成
========================================
总文件数: 45
生成成功: 38
跳过: 5
失败: 2
✗ 部分文档生成失败
失败的文件:
- GFramework.Core/internal/InternalClass.cs (缺少 XML 注释)
- GFramework.Core/legacy/LegacyClass.cs (解析错误)
```
## 前置条件
1. 模块源代码目录存在
2. 源代码文件包含 XML 文档注释
3. 有足够的磁盘空间存储生成的文档
## 相关 Skills
- `/vitepress-api-doc` - 单文件 API 文档生成
- `/vitepress-validate` - 验证生成的文档
- `/vitepress-guide` - 生成功能指南
## 最佳实践
1. **首次生成**:使用批量生成快速创建所有文档
2. **增量更新**:修改代码后使用单文件生成更新对应文档
3. **定期验证**:批量生成后运行验证确保质量
4. **版本控制**:将生成的文档提交到版本控制系统
## 故障排除
### 问题:部分文件生成失败
**解决方案**:检查失败文件的 XML 注释是否完整,手动修复后重新生成
### 问题:生成速度慢
**解决方案**:使用 `--parallel` 选项启用并行处理
### 问题:生成的文档过多
**解决方案**:使用过滤选项排除不需要的文件
## 版本历史
- v1.0.0 - 初始版本,支持批量 API 文档生成

View File

@ -0,0 +1,87 @@
#!/bin/bash
# 批量生成 API 文档
# 用法: batch-generate.sh <模块名>
set -e
MODULE="$1"
if [ -z "$MODULE" ]; then
echo "用法: $0 <模块名>"
echo "可用模块: Core, Game, Godot, SourceGenerators"
exit 1
fi
# 确定源代码目录
case "$MODULE" in
Core)
SOURCE_DIR="GFramework.Core"
;;
Game)
SOURCE_DIR="GFramework.Game"
;;
Godot)
SOURCE_DIR="GFramework.Godot"
;;
SourceGenerators)
SOURCE_DIR="GFramework.SourceGenerators"
;;
*)
echo "错误: 未知的模块: $MODULE"
exit 1
;;
esac
if [ ! -d "$SOURCE_DIR" ]; then
echo "错误: 源代码目录不存在: $SOURCE_DIR"
exit 1
fi
echo "=========================================="
echo "批量生成 $MODULE 模块的 API 文档"
echo "=========================================="
echo ""
# 查找所有 C# 文件
FILES=$(find "$SOURCE_DIR" -name "*.cs" -type f \
! -name "*.g.cs" \
! -name "*.Designer.cs" \
! -name "*Test.cs" \
! -name "*.Tests.cs" \
! -name "AssemblyInfo.cs")
FILE_COUNT=$(echo "$FILES" | wc -l)
echo "找到 $FILE_COUNT 个文件"
echo ""
GENERATED=0
SKIPPED=0
FAILED=0
for FILE in $FILES; do
echo "处理: $FILE"
# 检查是否包含公共类型
if ! grep -q "public \(class\|interface\|enum\|struct\)" "$FILE"; then
echo " ⊘ 跳过(无公共类型)"
SKIPPED=$((SKIPPED + 1))
continue
fi
# 注意: 实际的文档生成由 AI 调用 /vitepress-api-doc 完成
# 此脚本仅用于扫描和过滤文件
echo " → 待生成"
GENERATED=$((GENERATED + 1))
echo ""
done
echo "=========================================="
echo "扫描完成"
echo "=========================================="
echo "总文件数: $FILE_COUNT"
echo "待生成: $GENERATED"
echo "跳过: $SKIPPED"
echo ""
exit 0

View File

@ -0,0 +1,52 @@
---
name: vitepress-doc-generator
description: Generate standardized VitePress documentation from source code.
disable-model-invocation: true
---
# Role
You are a technical documentation generator specialized in VitePress.
# Objective
Analyze the provided code context and generate a structured VitePress-compatible Markdown document.
# Output Requirements
1. Output MUST be valid Markdown only.
2. Include frontmatter:
---
title: <Module Name>
outline: deep
---
3. No explanations.
4. No conversational text.
5. No emoji.
6. Use Chinese.
7. Use structured headings.
# Required Structure
# 模块概述
- 模块职责
- 设计目标
# 核心类说明
## 类名
### 职责
### 主要方法
### 依赖关系
# 设计模式分析
# 可扩展性说明
# 使用示例(如适用)
# Self-Validation
Before returning output, verify:
- Frontmatter exists
- All required sections exist
- No extra commentary text

View File

@ -0,0 +1,256 @@
# VitePress 功能指南生成
生成功能模块的使用指南文档,包括概念说明、用法示例和最佳实践。
## 用途
此 skill 用于生成结构化的功能指南文档,适用于:
- 核心功能模块的使用说明
- 设计模式和架构概念
- 系统功能的详细介绍
- 最佳实践和常见问题
## 调用方式
```bash
/vitepress-guide <主题> <目标模块>
```
**示例**
```bash
/vitepress-guide "事件系统" Core
/vitepress-guide "IoC 容器" Core
/vitepress-guide "Godot 节点扩展" Godot
```
## 工作流程
1. **收集需求**
- 询问用户指南主题
- 确定目标受众(初学者/进阶/专家)
- 了解重点内容(概念/用法/最佳实践)
2. **搜索相关资源**
- 搜索相关代码文件
- 查找现有文档
- 识别相关类型和接口
3. **生成指南结构**
- 根据 `template.md` 创建文档框架
- 填充概述和核心概念
- 添加基本用法和高级用法
- 补充最佳实践和常见问题
4. **生成代码示例**
- 基本用法示例(最简单的场景)
- 常见场景示例(实际应用)
- 高级用法示例(复杂配置)
5. **确定输出路径**
- 保存到 `docs/zh-CN/<模块>/`
- 文件名使用小写加连字符(如 `event-system.md`
6. **更新导航配置**
- 在 VitePress 侧边栏中添加新指南
## 输出规范
### Frontmatter 格式
```yaml
---
title: 指南标题
description: 简短描述1-2 句话)
---
```
### 文档结构
1. **概述**:功能的简介和用途
2. **核心概念**:关键概念和术语解释
3. **基本用法**:最简单的使用方式
4. **高级用法**:复杂场景和配置
5. **最佳实践**:推荐的使用方式
6. **常见问题**FAQ 和故障排除
### 章节示例
**概述**
```markdown
## 概述
事件系统提供了一种松耦合的组件间通信机制。通过事件,不同的组件可以在不直接引用彼此的情况下进行交互。
**主要特性**
- 类型安全的事件
- 自动内存管理
- 支持事件优先级
- 线程安全
```
**核心概念**
```markdown
## 核心概念
### 事件类型
事件是一个普通的 C# 类,用于携带事件数据:
\`\`\`csharp
public class PlayerDiedEvent
{
public int PlayerId { get; set; }
public string Reason { get; set; }
}
\`\`\`
### 事件发送
通过架构发送事件:
\`\`\`csharp
this.SendEvent(new PlayerDiedEvent
{
PlayerId = 1,
Reason = "Fall damage"
});
\`\`\`
### 事件监听
注册事件监听器:
\`\`\`csharp
this.RegisterEvent<PlayerDiedEvent>(OnPlayerDied);
\`\`\`
```
## 模板变量
- `{{GUIDE_TITLE}}` - 指南标题
- `{{GUIDE_DESCRIPTION}}` - 简短描述
- `{{OVERVIEW}}` - 概述内容
- `{{CORE_CONCEPTS}}` - 核心概念
- `{{BASIC_USAGE}}` - 基本用法
- `{{ADVANCED_USAGE}}` - 高级用法
- `{{BEST_PRACTICES}}` - 最佳实践
- `{{FAQ}}` - 常见问题
## 示例输出
参考 `examples/guide-example.md`,该示例基于现有的 IoC 容器文档创建。
## 内容要求
### 概述部分
- 1-2 段简介
- 列出主要特性3-5 个)
- 说明适用场景
### 核心概念部分
- 使用三级标题(###)分隔不同概念
- 每个概念包含简短说明和代码示例
- 解释关键术语
### 基本用法部分
- 提供完整的可运行示例
- 从最简单的场景开始
- 逐步增加复杂度
- 包含必要的 using 语句
### 高级用法部分
- 展示复杂场景
- 说明配置选项
- 提供性能优化建议
### 最佳实践部分
- 使用编号列表
- 每条实践包含简短说明
- 提供正反示例(✓ 推荐 / ✗ 不推荐)
### 常见问题部分
- 使用问答格式
- 提供具体的解决方案
- 包含相关链接
## 写作风格
### 语气
- 友好、专业
- 使用第二人称("你"
- 避免过于技术化的术语
### 代码示例
- 完整且可运行
- 包含注释说明关键步骤
- 使用有意义的变量名
- 遵循项目代码风格
### 格式
- 使用 Markdown 标准格式
- 代码块使用语法高亮
- 重要内容使用粗体或引用块
- 适当使用列表和表格
## 配置选项
### 目标受众
```bash
# 初学者(更多解释,简单示例)
/vitepress-guide "事件系统" Core --audience beginner
# 进阶(平衡解释和示例)
/vitepress-guide "事件系统" Core --audience intermediate
# 专家(简洁说明,复杂示例)
/vitepress-guide "事件系统" Core --audience expert
```
### 重点内容
```bash
# 侧重概念
/vitepress-guide "事件系统" Core --focus concepts
# 侧重用法
/vitepress-guide "事件系统" Core --focus usage
# 侧重最佳实践
/vitepress-guide "事件系统" Core --focus best-practices
```
## 前置条件
1. 了解指南主题的基本概念
2. 能够访问相关代码文件
3. 了解项目的代码风格和术语
## 相关 Skills
- `/vitepress-api-doc` - 生成 API 参考文档
- `/vitepress-tutorial` - 生成分步教程
- `/vitepress-validate` - 验证生成的文档
## 最佳实践
1. **先搜索后编写**:查看现有文档和代码,保持一致性
2. **使用真实示例**:基于项目实际代码创建示例
3. **保持简洁**:每个章节聚焦一个主题
4. **提供完整代码**:确保示例可以直接运行
5. **添加交叉引用**:链接到相关的 API 文档和其他指南
## 故障排除
### 问题:不确定指南应该包含哪些内容
**解决方案**:参考 `examples/guide-example.md` 和现有的指南文档
### 问题:代码示例过于复杂
**解决方案**:将复杂示例拆分为多个简单示例,逐步增加复杂度
### 问题:概念解释不清晰
**解决方案**:使用类比、图表或分步说明来辅助解释
## 版本历史
- v1.0.0 - 初始版本,支持功能指南生成

View File

@ -0,0 +1,283 @@
---
title: IoC 容器使用指南
description: IoC控制反转容器提供了轻量级的依赖注入功能用于管理框架中各种组件的注册和获取。
---
# IoC 容器使用指南
## 概述
IoCInversion of Control控制反转包提供了一个轻量级的依赖注入容器用于管理框架中各种组件的注册和获取。通过 IoC 容器,可以实现组件间的解耦,便于测试和维护。
IoC 容器是 GFramework 架构的核心组件之一,为整个框架提供依赖管理和组件解析服务。
**主要特性**
- 类型安全的依赖管理
- 支持单例和多实例注册
- 线程安全操作
- 容器冻结保护
- 自动接口注册
## 核心概念
### 依赖注入
依赖注入是一种设计模式,通过容器管理对象的创建和依赖关系,而不是在代码中直接创建对象。
```csharp
// 不使用依赖注入
public class GameController
{
private PlayerModel model = new PlayerModel(); // 硬编码依赖
}
// 使用依赖注入
public class GameController : IController
{
public IArchitecture GetArchitecture() => GameArchitecture.Interface;
public void Start()
{
var model = this.GetModel<PlayerModel>(); // 从容器获取
}
}
```
### 容器注册
在架构初始化时,将组件注册到容器中:
```csharp
public class GameArchitecture : Architecture
{
protected override void Init()
{
// 注册 Model
RegisterModel(new PlayerModel());
// 注册 System
RegisterSystem(new GameplaySystem());
// 注册 Utility
RegisterUtility(new StorageUtility());
}
}
```
### 容器解析
通过扩展方法从容器中获取已注册的组件:
```csharp
// 在 Controller 中
var playerModel = this.GetModel<PlayerModel>();
var gameplaySystem = this.GetSystem<GameplaySystem>();
var storageUtility = this.GetUtility<StorageUtility>();
```
## 基本用法
### 注册组件
```csharp
var container = new IocContainer();
// 注册单例(一个类型只能有一个实例)
container.RegisterSingleton<IPlayerModel>(new PlayerModel());
// 注册多实例(一个类型可以有多个实例)
container.RegisterPlurality<IEnemy>(new Goblin());
container.RegisterPlurality<IEnemy>(new Orc());
container.RegisterPlurality<IEnemy>(new Dragon());
```
### 获取组件
```csharp
// 获取单例
var playerModel = container.Get<IPlayerModel>();
// 获取多实例集合
var enemies = container.GetAll<IEnemy>(); // 返回 List<IEnemy>
```
### 在架构中使用
```csharp
public class GameArchitecture : Architecture
{
protected override void Init()
{
// 注册组件
RegisterModel(new PlayerModel());
RegisterModel(new InventoryModel());
RegisterSystem(new GameplaySystem());
}
}
// 在 Controller 中使用
public class GameController : IController
{
public IArchitecture GetArchitecture() => GameArchitecture.Interface;
public void Start()
{
// 通过扩展方法获取组件
var playerModel = this.GetModel<PlayerModel>();
var inventoryModel = this.GetModel<InventoryModel>();
var gameplaySystem = this.GetSystem<GameplaySystem>();
}
}
```
## 高级用法
### 容器冻结
容器在架构初始化完成后会被冻结,防止运行时修改:
```csharp
var container = new IocContainer();
container.Register<IPlayerModel>(new PlayerModel());
// 冻结容器
container.Freeze();
// 以下操作会抛出 InvalidOperationException
// container.Register<IGameSystem>(new GameSystem());
```
### 多实例管理
```csharp
// 注册多个同类型实例
container.RegisterPlurality<IWeapon>(new Sword());
container.RegisterPlurality<IWeapon>(new Bow());
container.RegisterPlurality<IWeapon>(new Staff());
// 获取所有实例
var allWeapons = container.GetAll<IWeapon>();
foreach (var weapon in allWeapons)
{
weapon.Attack();
}
```
### 接口自动注册
注册实例时,容器会自动将其注册到所有实现的接口:
```csharp
public class PlayerModel : IModel, IPlayerModel, IDisposable
{
// ...
}
// 注册实例
container.Register<PlayerModel>(new PlayerModel());
// 可以通过任何接口获取
var model1 = container.Get<IModel>();
var model2 = container.Get<IPlayerModel>();
var model3 = container.Get<IDisposable>();
// 以上三个变量指向同一个实例
```
### 线程安全操作
容器的所有操作都是线程安全的:
```csharp
// 多线程环境下安全使用
Parallel.For(0, 100, i =>
{
var model = container.Get<IPlayerModel>();
model.DoSomething();
});
```
## 最佳实践
1. **使用接口注册**:优先使用接口类型注册,而不是具体类型
```csharp
✓ container.Register<IPlayerModel>(new PlayerModel());
✗ container.Register<PlayerModel>(new PlayerModel());
```
2. **单例 vs 多实例**:根据需求选择合适的注册方式
- 单例:全局唯一的服务(如配置、管理器)
- 多实例:可以有多个实例的对象(如敌人、道具)
3. **避免循环依赖**:组件之间不应该相互依赖
```csharp
✗ System A 依赖 System BSystem B 又依赖 System A
✓ 使用事件系统进行通信,避免直接依赖
```
4. **在 Init 中注册**:所有组件应该在架构的 `Init()` 方法中注册
```csharp
protected override void Init()
{
// 在这里注册所有组件
RegisterModel(new PlayerModel());
RegisterSystem(new GameplaySystem());
}
```
5. **使用扩展方法**:通过扩展方法获取组件,代码更简洁
```csharp
✓ var model = this.GetModel<PlayerModel>();
✗ var model = this.GetArchitecture().GetModel<PlayerModel>();
```
6. **不要在运行时注册**:容器冻结后不应该再注册新组件
```csharp
✗ 在游戏运行时动态注册组件
✓ 在架构初始化时注册所有需要的组件
```
## 常见问题
### 问题:如何判断使用单例还是多实例?
**解答**
- 使用单例(`RegisterSingleton`):全局唯一的服务,如 PlayerModel、GameConfiguration
- 使用多实例(`RegisterPlurality`):可以有多个实例的对象,如 Enemy、Weapon
### 问题:容器冻结后如何添加新组件?
**解答**
容器冻结是为了保护架构稳定性。如果需要动态添加组件,应该:
1. 在架构初始化时预先注册所有可能需要的组件
2. 使用对象池模式管理动态对象
3. 考虑使用工厂模式创建临时对象
### 问题:如何处理组件的生命周期?
**解答**
- 实现 `IDisposable` 接口的组件会在架构销毁时自动释放
- 架构会按注册的逆序销毁组件
- 不需要手动管理组件的生命周期
### 问题:可以在容器中注册值类型吗?
**解答**
可以,但会发生装箱。建议将值类型包装在类中:
```csharp
// 不推荐
container.Register<int>(42);
// 推荐
public class GameConfig
{
public int MaxPlayers { get; set; } = 42;
}
container.Register<GameConfig>(new GameConfig());
```
## 相关文档
- [架构组件](/zh-CN/core/architecture) - 架构基础
- [Model 层](/zh-CN/core/model) - 数据模型
- [System 层](/zh-CN/core/system) - 业务系统
- [Utility 工具类](/zh-CN/core/utility) - 工具类

View File

@ -0,0 +1,34 @@
---
title: {{GUIDE_TITLE}}
description: {{GUIDE_DESCRIPTION}}
---
# {{GUIDE_TITLE}}
## 概述
{{OVERVIEW}}
## 核心概念
{{CORE_CONCEPTS}}
## 基本用法
{{BASIC_USAGE}}
## 高级用法
{{ADVANCED_USAGE}}
## 最佳实践
{{BEST_PRACTICES}}
## 常见问题
{{FAQ}}
## 相关文档
{{RELATED_DOCS}}

View File

@ -0,0 +1,253 @@
# VitePress 教程生成
生成分步教程文档,适合初学者学习框架功能。
## 用途
此 skill 用于生成结构化的分步教程,适用于:
- 框架入门教程
- 功能实现教程
- 最佳实践演示
- 问题解决方案
## 调用方式
```bash
/vitepress-tutorial <教程主题>
```
**示例**
```bash
/vitepress-tutorial "创建第一个 System"
/vitepress-tutorial "实现自定义命令"
/vitepress-tutorial "使用事件系统"
```
## 工作流程
1. **收集需求**
- 询问用户教程主题
- 确定学习目标
- 了解前置知识要求
2. **设计教程步骤**
- 将任务分解为 3-7 个步骤
- 每步聚焦一个具体任务
- 确保步骤之间逻辑连贯
3. **生成教程内容**
- 根据 `template.md` 创建文档框架
- 为每步编写详细说明和代码
- 添加完整的可运行代码
- 说明预期结果
4. **确定输出路径**
- 保存到 `docs/zh-CN/tutorials/`
- 文件名使用小写加连字符
5. **更新导航配置**
- 在 VitePress 侧边栏中添加新教程
## 输出规范
### Frontmatter 格式
```yaml
---
title: 教程标题
description: 简短描述1 句话说明学习内容)
---
```
### 文档结构
1. **学习目标**:完成教程后能够掌握的技能
2. **前置条件**:需要的前置知识和环境
3. **步骤 1-N**分步说明3-7 步)
4. **完整代码**:汇总所有代码
5. **运行结果**:预期输出和效果
6. **下一步**:后续学习建议
### 步骤格式
每个步骤应包含:
- 步骤标题(简短、动词开头)
- 步骤说明(为什么要这样做)
- 代码示例(完整且可运行)
- 代码解释(关键部分的说明)
**示例**
```markdown
## 步骤 1创建 Model 类
首先,我们需要创建一个 Model 来存储玩家数据。Model 负责管理应用的数据和状态。
\`\`\`csharp
using GFramework.Core.Abstractions.model;
using GFramework.Core.Abstractions.property;
public class PlayerModel : IModel
{
// 玩家名称(可绑定属性)
public BindableProperty<string> Name { get; } = new("Player");
// 玩家生命值
public BindableProperty<int> Health { get; } = new(100);
// 玩家金币
public BindableProperty<int> Gold { get; } = new(0);
public void Init() { }
}
\`\`\`
**代码说明**
- `BindableProperty<T>` 是可绑定属性,值变化时会自动通知监听者
- `Init()` 方法在 Model 注册到架构时被调用
- 使用属性初始化器设置默认值
```
## 模板变量
- `{{TUTORIAL_TITLE}}` - 教程标题
- `{{TUTORIAL_DESCRIPTION}}` - 简短描述
- `{{LEARNING_OBJECTIVES}}` - 学习目标
- `{{PREREQUISITES}}` - 前置条件
- `{{STEP_N_TITLE}}` - 步骤标题
- `{{STEP_N_CONTENT}}` - 步骤内容
- `{{FULL_CODE}}` - 完整代码
- `{{EXPECTED_OUTPUT}}` - 预期输出
- `{{NEXT_STEPS}}` - 下一步建议
## 示例输出
参考 `examples/tutorial-example.md`,该示例基于现有的教程文档创建。
## 内容要求
### 学习目标
- 使用列表格式
- 3-5 个具体的学习目标
- 使用"能够..."句式
**示例**
```markdown
## 学习目标
完成本教程后,你将能够:
- 创建自定义的 Model 类
- 在架构中注册 Model
- 从 Controller 中访问 Model
- 使用可绑定属性管理数据
```
### 前置条件
- 列出必需的知识
- 说明环境要求
- 提供相关文档链接
**示例**
```markdown
## 前置条件
- 已安装 GFramework.Core NuGet 包
- 了解 C# 基础语法
- 阅读过[架构概览](/zh-CN/getting-started)
```
### 步骤内容
- 每步 100-300 字说明
- 包含完整的代码示例
- 解释关键代码的作用
- 使用注释标注重要部分
### 完整代码
- 汇总所有步骤的代码
- 确保可以直接复制运行
- 包含必要的 using 语句
- 添加文件结构说明
### 运行结果
- 描述预期的输出
- 如果有界面,提供截图或描述
- 说明如何验证结果正确
### 下一步
- 推荐 2-3 个后续教程
- 提供相关文档链接
- 建议进阶学习方向
## 写作风格
### 语气
- 友好、鼓励性
- 使用第二人称("你"
- 避免假设读者已有高级知识
### 步骤说明
- 使用主动语态
- 步骤标题使用动词开头
- 说明"为什么"而不仅是"怎么做"
### 代码示例
- 完整且可运行
- 包含详细注释
- 使用有意义的变量名
- 遵循项目代码风格
## 配置选项
### 教程难度
```bash
# 初学者(更多解释,简单示例)
/vitepress-tutorial "创建第一个 System" --level beginner
# 中级(平衡解释和复杂度)
/vitepress-tutorial "实现自定义命令" --level intermediate
# 高级(简洁说明,复杂示例)
/vitepress-tutorial "架构模块开发" --level advanced
```
### 步骤数量
```bash
# 指定步骤数量3-7 步)
/vitepress-tutorial "使用事件系统" --steps 5
```
## 前置条件
1. 了解教程主题的基本概念
2. 能够访问相关代码文件
3. 了解目标受众的知识水平
## 相关 Skills
- `/vitepress-api-doc` - 生成 API 参考文档
- `/vitepress-guide` - 生成功能指南
- `/vitepress-validate` - 验证生成的文档
## 最佳实践
1. **从简单开始**:第一步应该是最简单的操作
2. **逐步增加复杂度**:每步在前一步基础上增加新内容
3. **提供完整代码**:确保每步的代码都可以运行
4. **解释关键概念**:不要假设读者已经了解所有术语
5. **测试教程**:确保按照步骤操作能够得到预期结果
## 故障排除
### 问题:步骤过多,教程太长
**解决方案**:将教程拆分为多个小教程,或合并相似的步骤
### 问题:代码示例不完整
**解决方案**:在"完整代码"章节提供所有文件的完整代码
### 问题:读者反馈步骤不清晰
**解决方案**:增加更多说明,使用截图或图表辅助
## 版本历史
- v1.0.0 - 初始版本,支持分步教程生成

View File

@ -0,0 +1,347 @@
---
title: 创建第一个 Model
description: 学习如何创建和使用 Model 来管理应用数据
---
# 创建第一个 Model
## 学习目标
完成本教程后,你将能够:
- 理解 Model 在架构中的作用
- 创建自定义的 Model 类
- 在架构中注册 Model
- 从 Controller 中访问 Model
- 使用可绑定属性管理数据
## 前置条件
- 已安装 GFramework.Core NuGet 包
- 了解 C# 基础语法
- 阅读过[架构概览](/zh-CN/getting-started)
## 步骤 1创建 Model 类
首先,我们需要创建一个 Model 来存储玩家数据。Model 负责管理应用的数据和状态。
```csharp
using GFramework.Core.Abstractions.model;
using GFramework.Core.Abstractions.property;
namespace MyGame.Models
{
/// <summary>
/// 玩家数据模型
/// </summary>
public class PlayerModel : IModel
{
// 玩家名称(可绑定属性)
public BindableProperty<string> Name { get; } = new("Player");
// 玩家生命值
public BindableProperty<int> Health { get; } = new(100);
// 玩家金币
public BindableProperty<int> Gold { get; } = new(0);
// 玩家等级
public BindableProperty<int> Level { get; } = new(1);
/// <summary>
/// Model 初始化方法
/// </summary>
public void Init()
{
// 在这里可以进行初始化操作
// 例如:从配置文件加载默认值
}
}
}
```
**代码说明**
- `IModel` 接口标识这是一个数据模型
- `BindableProperty<T>` 是可绑定属性,值变化时会自动通知监听者
- `Init()` 方法在 Model 注册到架构时被调用
- 使用属性初始化器设置默认值
## 步骤 2在架构中注册 Model
创建架构类并注册 Model
```csharp
using GFramework.Core.architecture;
using MyGame.Models;
namespace MyGame
{
/// <summary>
/// 游戏架构
/// </summary>
public class GameArchitecture : Architecture
{
// 单例访问点
public static IArchitecture Interface { get; private set; }
/// <summary>
/// 初始化架构
/// </summary>
protected override void Init()
{
Interface = this;
// 注册 Model
RegisterModel(new PlayerModel());
}
}
}
```
**代码说明**
- 继承 `Architecture` 基类
- 在 `Init()` 方法中注册 Model
- 提供静态属性 `Interface` 用于全局访问架构
## 步骤 3创建 Controller 访问 Model
创建 Controller 来使用 Model
```csharp
using GFramework.Core.Abstractions.architecture;
using GFramework.Core.Abstractions.controller;
using GFramework.Core.extensions;
using MyGame.Models;
namespace MyGame.Controllers
{
/// <summary>
/// 游戏控制器
/// </summary>
public class GameController : IController
{
/// <summary>
/// 获取架构实例
/// </summary>
public IArchitecture GetArchitecture() => GameArchitecture.Interface;
/// <summary>
/// 初始化玩家数据
/// </summary>
public void InitializePlayer()
{
// 获取 PlayerModel
var playerModel = this.GetModel<PlayerModel>();
// 设置玩家数据
playerModel.Name.Value = "勇者";
playerModel.Health.Value = 100;
playerModel.Gold.Value = 50;
playerModel.Level.Value = 1;
// 监听属性变化
playerModel.Health.RegisterOnValueChanged(health =>
{
Console.WriteLine($"玩家生命值变化: {health}");
if (health <= 0)
{
Console.WriteLine("玩家死亡!");
}
});
}
/// <summary>
/// 玩家受到伤害
/// </summary>
public void TakeDamage(int damage)
{
var playerModel = this.GetModel<PlayerModel>();
playerModel.Health.Value -= damage;
}
/// <summary>
/// 玩家获得金币
/// </summary>
public void AddGold(int amount)
{
var playerModel = this.GetModel<PlayerModel>();
playerModel.Gold.Value += amount;
}
}
}
```
**代码说明**
- 实现 `IController` 接口
- 通过 `this.GetModel<T>()` 扩展方法获取 Model
- 使用 `.Value` 访问和修改属性值
- 使用 `RegisterOnValueChanged` 监听属性变化
## 步骤 4初始化并使用架构
在程序入口点初始化架构:
```csharp
using MyGame;
using MyGame.Controllers;
// 1. 创建并初始化架构
var architecture = new GameArchitecture();
architecture.Initialize();
// 2. 等待架构就绪
await architecture.WaitUntilReadyAsync();
// 3. 创建 Controller 并使用
var gameController = new GameController();
// 初始化玩家
gameController.InitializePlayer();
// 玩家受到伤害
gameController.TakeDamage(20);
// 输出: 玩家生命值变化: 80
// 玩家获得金币
gameController.AddGold(100);
```
**代码说明**
- 创建架构实例并调用 `Initialize()`
- 使用 `WaitUntilReadyAsync()` 等待架构就绪
- 创建 Controller 实例并调用方法
## 完整代码
### PlayerModel.cs
```csharp
using GFramework.Core.Abstractions.model;
using GFramework.Core.Abstractions.property;
namespace MyGame.Models
{
public class PlayerModel : IModel
{
public BindableProperty<string> Name { get; } = new("Player");
public BindableProperty<int> Health { get; } = new(100);
public BindableProperty<int> Gold { get; } = new(0);
public BindableProperty<int> Level { get; } = new(1);
public void Init() { }
}
}
```
### GameArchitecture.cs
```csharp
using GFramework.Core.architecture;
using MyGame.Models;
namespace MyGame
{
public class GameArchitecture : Architecture
{
public static IArchitecture Interface { get; private set; }
protected override void Init()
{
Interface = this;
RegisterModel(new PlayerModel());
}
}
}
```
### GameController.cs
```csharp
using GFramework.Core.Abstractions.architecture;
using GFramework.Core.Abstractions.controller;
using GFramework.Core.extensions;
using MyGame.Models;
namespace MyGame.Controllers
{
public class GameController : IController
{
public IArchitecture GetArchitecture() => GameArchitecture.Interface;
public void InitializePlayer()
{
var playerModel = this.GetModel<PlayerModel>();
playerModel.Name.Value = "勇者";
playerModel.Health.Value = 100;
playerModel.Gold.Value = 50;
playerModel.Level.Value = 1;
playerModel.Health.RegisterOnValueChanged(health =>
{
Console.WriteLine($"玩家生命值变化: {health}");
if (health <= 0)
{
Console.WriteLine("玩家死亡!");
}
});
}
public void TakeDamage(int damage)
{
var playerModel = this.GetModel<PlayerModel>();
playerModel.Health.Value -= damage;
}
public void AddGold(int amount)
{
var playerModel = this.GetModel<PlayerModel>();
playerModel.Gold.Value += amount;
}
}
}
```
### Program.cs
```csharp
using MyGame;
using MyGame.Controllers;
var architecture = new GameArchitecture();
architecture.Initialize();
await architecture.WaitUntilReadyAsync();
var gameController = new GameController();
gameController.InitializePlayer();
gameController.TakeDamage(20);
gameController.AddGold(100);
```
## 运行结果
运行程序后,你将看到以下输出:
```
玩家生命值变化: 100
玩家生命值变化: 80
```
**验证步骤**
1. 程序成功启动,没有异常
2. 控制台输出生命值变化信息
3. 玩家数据正确更新
## 下一步
恭喜!你已经学会了如何创建和使用 Model。接下来可以学习
- [创建第一个 System](/zh-CN/tutorials/create-first-system) - 学习如何创建业务逻辑层
- [使用命令系统](/zh-CN/tutorials/use-command-system) - 学习如何封装操作
- [使用事件系统](/zh-CN/tutorials/use-event-system) - 学习组件间通信
## 相关文档
- [Model 层](/zh-CN/core/model) - Model 详细说明
- [属性系统](/zh-CN/core/property) - 可绑定属性详解
- [架构组件](/zh-CN/core/architecture) - 架构基础
- [Controller 层](/zh-CN/core/controller) - Controller 详细说明

View File

@ -0,0 +1,42 @@
---
title: {{TUTORIAL_TITLE}}
description: {{TUTORIAL_DESCRIPTION}}
---
# {{TUTORIAL_TITLE}}
## 学习目标
{{LEARNING_OBJECTIVES}}
## 前置条件
{{PREREQUISITES}}
## 步骤 1{{STEP_1_TITLE}}
{{STEP_1_CONTENT}}
## 步骤 2{{STEP_2_TITLE}}
{{STEP_2_CONTENT}}
## 步骤 3{{STEP_3_TITLE}}
{{STEP_3_CONTENT}}
## 完整代码
{{FULL_CODE}}
## 运行结果
{{EXPECTED_OUTPUT}}
## 下一步
{{NEXT_STEPS}}
## 相关文档
{{RELATED_DOCS}}

View File

@ -0,0 +1,297 @@
# VitePress 文档验证
验证 VitePress 文档的质量和规范性,确保文档符合项目标准。
## 用途
此 skill 用于验证 Markdown 文档的格式和内容,包括:
- Frontmatter 格式正确性
- 内部链接有效性
- 代码块语法标记
- 标题层级结构
- 中文标点符号规范
- 泛型符号转义
## 调用方式
```bash
# 验证单个文件
/vitepress-validate <文件路径>
# 验证整个目录
/vitepress-validate <目录路径>
# 验证所有文档
/vitepress-validate docs/zh-CN/
```
**示例**
```bash
/vitepress-validate docs/zh-CN/api-reference/core/architecture.md
/vitepress-validate docs/zh-CN/core/
```
## 验证项
### 1. Frontmatter 验证
**检查项**
- YAML 语法正确性
- 必需字段存在(`title``description`
- 字段值类型正确
- `outline` 字段值有效(`deep``[2,3]` 等)
**示例**
```yaml
---
title: Architecture # 必需
description: 架构基类说明 # 必需
outline: deep # 可选,但值必须有效
---
```
### 2. 内部链接验证
**检查项**
- 相对路径链接指向的文件存在
- 绝对路径链接格式正确
- 锚点链接对应的标题存在
- 没有损坏的链接
**有效链接格式**
- `[文本](./file.md)` - 相对路径
- `[文本](/zh-CN/core/architecture)` - 绝对路径
- `[文本](#标题)` - 锚点链接
- `[文本](./file.md#标题)` - 组合链接
### 3. 代码块验证
**检查项**
- 代码块有语法标记(```csharp、```bash 等)
- C# 代码块使用 `csharp` 标记(不是 `cs``c#`
- 代码块正确闭合
- 没有未闭合的反引号
**正确格式**
```markdown
\`\`\`csharp
public class Example { }
\`\`\`
```
**错误格式**
```markdown
\`\`\`cs // 应该使用 csharp
public class Example { }
\`\`\`
```
### 4. 标题层级验证
**检查项**
- 标题层级不跳级(不能从 `#` 直接跳到 `###`
- 每个文档只有一个一级标题(`#`
- 标题层级递增合理
**正确示例**
```markdown
# 一级标题
## 二级标题
### 三级标题
## 另一个二级标题
```
**错误示例**
```markdown
# 一级标题
### 三级标题 ❌ 跳过了二级标题
```
### 5. 中文标点符号验证
**检查项**
- 中文句子使用全角标点(,。!?)
- 英文句子使用半角标点(,.!?
- 代码和技术术语周围使用半角符号
- 括号使用规范
**规范示例**
- "这是一个示例。" ✓(中文全角句号)
- "This is an example." ✓(英文半角句号)
- "`Architecture` 类提供了..." ✓(代码周围半角)
### 6. 泛型符号验证
**检查项**
- 泛型符号正确转义(`<T>``&lt;T&gt;`
- 仅在代码块外转义
- 代码块内保持原样
**正确示例**
```markdown
`List&lt;T&gt;` 是一个泛型类。
\`\`\`csharp
List<T> items = new List<T>(); // 代码块内不转义
\`\`\`
```
## 验证脚本
### validate-frontmatter.sh
验证 Frontmatter 格式。
**用法**
```bash
.claude/skills/vitepress-validate/scripts/validate-frontmatter.sh <文件路径>
```
### validate-links.sh
验证内部链接有效性。
**用法**
```bash
.claude/skills/vitepress-validate/scripts/validate-links.sh <文件路径>
```
### validate-code-blocks.sh
验证代码块语法。
**用法**
```bash
.claude/skills/vitepress-validate/scripts/validate-code-blocks.sh <文件路径>
```
### validate-all.sh
执行所有验证。
**用法**
```bash
.claude/skills/vitepress-validate/scripts/validate-all.sh <文件或目录路径>
```
## 输出格式
### 验证通过
```
✓ docs/zh-CN/core/architecture.md
- Frontmatter: 通过
- 内部链接: 通过
- 代码块: 通过
- 标题层级: 通过
- 标点符号: 通过
- 泛型符号: 通过
```
### 验证失败
```
✗ docs/zh-CN/core/architecture.md
- Frontmatter: 失败
× 缺少必需字段: description
- 内部链接: 失败
× 损坏的链接: ./missing-file.md (第 45 行)
- 代码块: 警告
⚠ 使用了 'cs' 标记,建议使用 'csharp' (第 78 行)
- 标题层级: 通过
- 标点符号: 警告
⚠ 中文句子使用了半角句号 (第 102 行)
- 泛型符号: 失败
× 未转义的泛型符号: List<T> (第 120 行)
```
## 修复建议
验证失败时skill 会提供具体的修复建议:
**示例**
```
修复建议:
1. 在 Frontmatter 中添加 description 字段
2. 修复或删除损坏的链接: ./missing-file.md
3. 将代码块标记从 'cs' 改为 'csharp'
4. 将第 102 行的半角句号改为全角句号
5. 将第 120 行的 List<T> 改为 List&lt;T&gt;
```
## 配置选项
### 严格模式
启用严格模式时,警告也会导致验证失败。
```bash
/vitepress-validate --strict docs/zh-CN/
```
### 忽略特定检查
```bash
# 忽略标点符号检查
/vitepress-validate --ignore-punctuation docs/zh-CN/
# 忽略多个检查
/vitepress-validate --ignore-punctuation --ignore-generics docs/zh-CN/
```
## 集成到工作流
### 生成后自动验证
```bash
# 1. 生成 API 文档
/vitepress-api-doc GFramework.Core/architecture/Architecture.cs
# 2. 自动验证生成的文档
/vitepress-validate docs/zh-CN/api-reference/core/architecture.md
```
### 批量验证
```bash
# 验证所有 API 文档
/vitepress-validate docs/zh-CN/api-reference/
# 验证所有文档
/vitepress-validate docs/zh-CN/
```
## 退出代码
- `0` - 所有验证通过
- `1` - 存在错误
- `2` - 仅存在警告(非严格模式下仍返回 0
## 相关 Skills
- `/vitepress-api-doc` - 生成 API 文档后自动验证
- `/vitepress-guide` - 生成指南文档后自动验证
- `/vitepress-tutorial` - 生成教程文档后自动验证
## 最佳实践
1. **生成后立即验证**:每次生成文档后立即运行验证
2. **定期批量验证**:定期验证所有文档,确保一致性
3. **修复所有错误**:不要忽略验证错误,及时修复
4. **关注警告**:警告虽不致命,但应该重视并修复
5. **使用严格模式**:在 CI/CD 中使用严格模式确保质量
## 故障排除
### 问题:误报泛型符号错误
**解决方案**:确保泛型符号在代码块外正确转义,代码块内保持原样
### 问题:中文标点符号检查过于严格
**解决方案**:使用 `--ignore-punctuation` 选项,或手动调整规则
### 问题:链接验证失败但文件确实存在
**解决方案**:检查文件路径大小写,确保路径完全匹配
## 版本历史
- v1.0.0 - 初始版本,支持 6 项基本验证

View File

@ -0,0 +1,109 @@
#!/bin/bash
# 执行所有验证
# 用法: validate-all.sh <文件或目录路径>
set -e
TARGET="$1"
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
if [ -z "$TARGET" ]; then
echo "用法: $0 <文件或目录路径>"
exit 1
fi
if [ ! -e "$TARGET" ]; then
echo "错误: 路径不存在: $TARGET"
exit 1
fi
echo "=========================================="
echo "VitePress 文档验证"
echo "=========================================="
echo ""
# 收集所有 Markdown 文件
if [ -f "$TARGET" ]; then
FILES=("$TARGET")
elif [ -d "$TARGET" ]; then
mapfile -t FILES < <(find "$TARGET" -name "*.md" -type f)
else
echo "错误: 无效的路径: $TARGET"
exit 1
fi
if [ ${#FILES[@]} -eq 0 ]; then
echo "未找到 Markdown 文件"
exit 0
fi
echo "找到 ${#FILES[@]} 个文件"
echo ""
TOTAL_ERRORS=0
TOTAL_WARNINGS=0
PASSED_FILES=0
FAILED_FILES=0
for FILE in "${FILES[@]}"; do
echo "验证: $FILE"
echo "----------------------------------------"
FILE_ERRORS=0
FILE_WARNINGS=0
# 1. Frontmatter 验证
if bash "$SCRIPT_DIR/validate-frontmatter.sh" "$FILE" 2>&1 | grep -q "✗"; then
FILE_ERRORS=$((FILE_ERRORS + 1))
fi
# 2. 链接验证
if bash "$SCRIPT_DIR/validate-links.sh" "$FILE" 2>&1 | grep -q "✗"; then
FILE_ERRORS=$((FILE_ERRORS + 1))
fi
# 3. 代码块验证
OUTPUT=$(bash "$SCRIPT_DIR/validate-code-blocks.sh" "$FILE" 2>&1)
if echo "$OUTPUT" | grep -q "✗"; then
FILE_ERRORS=$((FILE_ERRORS + 1))
fi
if echo "$OUTPUT" | grep -q "⚠"; then
FILE_WARNINGS=$((FILE_WARNINGS + 1))
fi
# 统计结果
if [ $FILE_ERRORS -eq 0 ]; then
echo "✓ 验证通过"
PASSED_FILES=$((PASSED_FILES + 1))
else
echo "✗ 验证失败($FILE_ERRORS 个错误)"
FAILED_FILES=$((FAILED_FILES + 1))
fi
if [ $FILE_WARNINGS -gt 0 ]; then
echo "$FILE_WARNINGS 个警告"
fi
TOTAL_ERRORS=$((TOTAL_ERRORS + FILE_ERRORS))
TOTAL_WARNINGS=$((TOTAL_WARNINGS + FILE_WARNINGS))
echo ""
done
echo "=========================================="
echo "验证摘要"
echo "=========================================="
echo "总文件数: ${#FILES[@]}"
echo "通过: $PASSED_FILES"
echo "失败: $FAILED_FILES"
echo "总错误数: $TOTAL_ERRORS"
echo "总警告数: $TOTAL_WARNINGS"
echo ""
if [ $TOTAL_ERRORS -eq 0 ]; then
echo "✓ 所有验证通过"
exit 0
else
echo "✗ 验证失败"
exit 1
fi

View File

@ -0,0 +1,64 @@
#!/bin/bash
# 验证代码块语法
# 用法: validate-code-blocks.sh <文件路径>
set -e
FILE="$1"
if [ -z "$FILE" ]; then
echo "用法: $0 <文件路径>"
exit 1
fi
if [ ! -f "$FILE" ]; then
echo "错误: 文件不存在: $FILE"
exit 1
fi
echo "验证代码块语法: $FILE"
ERROR_COUNT=0
WARNING_COUNT=0
# 检查未闭合的代码块
OPEN_COUNT=$(grep -c '^```' "$FILE" || true)
if [ $((OPEN_COUNT % 2)) -ne 0 ]; then
echo "✗ 错误: 存在未闭合的代码块"
ERROR_COUNT=$((ERROR_COUNT + 1))
fi
# 检查 C# 代码块标记
LINE_NUM=0
while IFS= read -r LINE; do
LINE_NUM=$((LINE_NUM + 1))
# 检查是否使用了错误的 C# 标记
if echo "$LINE" | grep -qE '^```(cs|c#|C#)$'; then
echo "⚠ 警告: 第 $LINE_NUM 行使用了非标准标记,建议使用 'csharp'"
echo " 当前: $LINE"
WARNING_COUNT=$((WARNING_COUNT + 1))
fi
# 检查代码块是否有语言标记
if echo "$LINE" | grep -qE '^```$'; then
# 检查下一行是否是代码(简单启发式:不是空行且不是 ```
NEXT_LINE=$(sed -n "$((LINE_NUM + 1))p" "$FILE")
if [ -n "$NEXT_LINE" ] && ! echo "$NEXT_LINE" | grep -qE '^```'; then
echo "⚠ 警告: 第 $LINE_NUM 行的代码块缺少语言标记"
WARNING_COUNT=$((WARNING_COUNT + 1))
fi
fi
done < "$FILE"
# 输出结果
if [ $ERROR_COUNT -eq 0 ] && [ $WARNING_COUNT -eq 0 ]; then
echo "✓ 代码块验证通过"
exit 0
elif [ $ERROR_COUNT -eq 0 ]; then
echo "⚠ 代码块验证通过(有 $WARNING_COUNT 个警告)"
exit 0
else
echo "✗ 代码块验证失败($ERROR_COUNT 个错误,$WARNING_COUNT 个警告)"
exit 1
fi

View File

@ -0,0 +1,57 @@
#!/bin/bash
# 验证 Frontmatter 格式
# 用法: validate-frontmatter.sh <文件路径>
set -e
FILE="$1"
if [ -z "$FILE" ]; then
echo "用法: $0 <文件路径>"
exit 1
fi
if [ ! -f "$FILE" ]; then
echo "错误: 文件不存在: $FILE"
exit 1
fi
echo "验证 Frontmatter: $FILE"
# 检查是否有 Frontmatter
if ! grep -q "^---$" "$FILE"; then
echo "✗ 错误: 文件缺少 Frontmatter"
exit 1
fi
# 提取 Frontmatter 内容(第一个 --- 到第二个 --- 之间)
FRONTMATTER=$(sed -n '/^---$/,/^---$/p' "$FILE" | sed '1d;$d')
if [ -z "$FRONTMATTER" ]; then
echo "✗ 错误: Frontmatter 为空"
exit 1
fi
# 检查必需字段: title
if ! echo "$FRONTMATTER" | grep -q "^title:"; then
echo "✗ 错误: 缺少必需字段: title"
exit 1
fi
# 检查必需字段: description
if ! echo "$FRONTMATTER" | grep -q "^description:"; then
echo "✗ 错误: 缺少必需字段: description"
exit 1
fi
# 检查 outline 字段值(如果存在)
if echo "$FRONTMATTER" | grep -q "^outline:"; then
OUTLINE_VALUE=$(echo "$FRONTMATTER" | grep "^outline:" | sed 's/outline:\s*//')
if [ "$OUTLINE_VALUE" != "deep" ] && [ "$OUTLINE_VALUE" != "false" ] && ! echo "$OUTLINE_VALUE" | grep -qE '^\[.*\]$'; then
echo "⚠ 警告: outline 字段值可能无效: $OUTLINE_VALUE"
echo " 有效值: deep, false, [2,3]"
fi
fi
echo "✓ Frontmatter 验证通过"
exit 0

View File

@ -0,0 +1,85 @@
#!/bin/bash
# 验证内部链接有效性
# 用法: validate-links.sh <文件路径>
set -e
FILE="$1"
BASE_DIR="docs/zh-CN"
if [ -z "$FILE" ]; then
echo "用法: $0 <文件路径>"
exit 1
fi
if [ ! -f "$FILE" ]; then
echo "错误: 文件不存在: $FILE"
exit 1
fi
echo "验证内部链接: $FILE"
# 获取文件所在目录
FILE_DIR=$(dirname "$FILE")
# 提取所有 Markdown 链接
LINKS=$(grep -oP '\[([^\]]+)\]\(([^)]+)\)' "$FILE" | grep -oP '\(([^)]+)\)' | sed 's/[()]//g' || true)
if [ -z "$LINKS" ]; then
echo "✓ 未找到链接"
exit 0
fi
ERROR_COUNT=0
while IFS= read -r LINK; do
# 跳过外部链接
if [[ "$LINK" =~ ^https?:// ]]; then
continue
fi
# 跳过锚点链接(仅 #开头)
if [[ "$LINK" =~ ^# ]]; then
continue
fi
# 移除锚点部分
LINK_PATH=$(echo "$LINK" | sed 's/#.*//')
# 跳过空路径
if [ -z "$LINK_PATH" ]; then
continue
fi
# 处理相对路径
if [[ "$LINK_PATH" =~ ^\. ]]; then
TARGET="$FILE_DIR/$LINK_PATH"
# 处理绝对路径
elif [[ "$LINK_PATH" =~ ^/ ]]; then
TARGET="docs$LINK_PATH"
# 如果没有扩展名,尝试添加 .md
if [[ ! "$TARGET" =~ \. ]]; then
TARGET="$TARGET.md"
fi
else
TARGET="$FILE_DIR/$LINK_PATH"
fi
# 规范化路径
TARGET=$(realpath -m "$TARGET" 2>/dev/null || echo "$TARGET")
# 检查文件是否存在
if [ ! -f "$TARGET" ] && [ ! -d "$TARGET" ]; then
echo "✗ 损坏的链接: $LINK"
echo " 目标不存在: $TARGET"
ERROR_COUNT=$((ERROR_COUNT + 1))
fi
done <<< "$LINKS"
if [ $ERROR_COUNT -eq 0 ]; then
echo "✓ 内部链接验证通过"
exit 0
else
echo "✗ 发现 $ERROR_COUNT 个损坏的链接"
exit 1
fi

2
.gitignore vendored
View File

@ -6,4 +6,4 @@ riderModule.iml
GFramework.sln.DotSettings.user
.idea/
.opencode.json
.claude/
.claude/settings.local.json