GFramework/docs/core/system.md
GeWuYou 1dc173e4df docs(core): 添加核心模块架构文档
- 添加 Architecture 包使用说明文档,介绍 MVC 架构模式实现
- 添加 Command 包使用说明文档,阐述命令模式设计和实现
- 添加 Controller 包使用说明文档,描述控制器接口规范
- 添加 Environment 包使用说明文档,定义环境配置功能
- 添加 Events 包使用说明文档,提供事件系统完整介绍
2026-02-11 12:52:14 +08:00

544 lines
14 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# System 包使用说明
## 概述
System 包定义了业务逻辑层Business Logic Layer。System 负责处理游戏的核心业务逻辑,协调 Model 之间的交互,响应事件并执行复杂的业务流程。
## 核心接口
### [`ICanGetSystem`](ICanGetSystem.cs)
标记接口,表示该类型可以获取其他 System。
**继承关系:**
```csharp
public interface ICanGetSystem : IBelongToArchitecture
```
### [`ISystem`](ISystem.cs)
System 接口,定义了系统的基本行为。
**核心成员:**
```csharp
void Init(); // 系统初始化方法
void Destroy(); // 系统销毁方法
void OnArchitecturePhase(ArchitecturePhase phase); // 处理架构阶段事件
```
**继承的能力:**
- `ICanSetArchitecture` - 可设置架构
- `ICanGetModel` - 可获取 Model
- `ICanGetUtility` - 可获取 Utility
- `ICanGetSystem` - 可获取其他 System
- `ICanRegisterEvent` - 可注册事件
- `ICanSendEvent` - 可发送事件
## 核心类
### [`AbstractSystem`](AbstractSystem.cs)
抽象 System 基类,提供了 System 的基础实现。继承自 ContextAwareBase具有上下文感知能力。
**使用方式:**
```csharp
public abstract class AbstractSystem : ContextAwareBase, ISystem
{
void ISystem.Init() => OnInit(); // 系统初始化,内部调用抽象方法 OnInit()
void ISystem.Destroy() => OnDestroy(); // 系统销毁,内部调用 OnDestroy()
protected abstract void OnInit(); // 子类实现初始化逻辑
protected virtual void OnDestroy(); // 子类可选择重写销毁逻辑
public virtual void OnArchitecturePhase(ArchitecturePhase phase); // 处理架构阶段事件
}
```
## 基本使用
### 1. 定义 System
```csharp
// 战斗系统
public class CombatSystem : AbstractSystem
{
protected override void OnInit()
{
// 注册事件监听
this.RegisterEvent<EnemyAttackEvent>(OnEnemyAttack);
this.RegisterEvent<PlayerAttackEvent>(OnPlayerAttack);
}
private void OnEnemyAttack(EnemyAttackEvent e)
{
var playerModel = this.GetModel<PlayerModel>();
// 计算伤害
int damage = CalculateDamage(e.AttackPower, playerModel.Defense.Value);
// 应用伤害
playerModel.Health.Value -= damage;
// 发送伤害事件
this.SendEvent(new PlayerTookDamageEvent { Damage = damage });
}
private void OnPlayerAttack(PlayerAttackEvent e)
{
var playerModel = this.GetModel<PlayerModel>();
var enemyModel = this.GetModel<EnemyModel>();
int damage = CalculateDamage(playerModel.AttackPower.Value, e.Enemy.Defense);
e.Enemy.Health -= damage;
this.SendEvent(new EnemyTookDamageEvent
{
EnemyId = e.Enemy.Id,
Damage = damage
});
}
private int CalculateDamage(int attackPower, int defense)
{
return Math.Max(1, attackPower - defense / 2);
}
protected override void OnDestroy()
{
// 清理资源
base.OnDestroy();
}
}
```
### 2. 注册 System
```csharp
public class GameArchitecture : Architecture
{
protected override void Init()
{
// 注册 Model
this.RegisterModel<PlayerModel>(new PlayerModel());
this.RegisterModel<EnemyModel>(new EnemyModel());
// 注册 System系统注册后会自动调用 Init
this.RegisterSystem<CombatSystem>(new CombatSystem());
this.RegisterSystem<InventorySystem>(new InventorySystem());
this.RegisterSystem<QuestSystem>(new QuestSystem());
}
}
```
### 3. 在其他组件中获取 System
```csharp
// 在 Controller 中
public partial class GameController : Node, IController
{
public IArchitecture GetArchitecture() => GameArchitecture.Interface;
public override void _Ready()
{
// 获取 System
var combatSystem = this.GetSystem<CombatSystem>();
var questSystem = this.GetSystem<QuestSystem>();
}
}
// 在 Command 中
public class StartBattleCommand : AbstractCommand
{
protected override void OnExecute()
{
var combatSystem = this.GetSystem<CombatSystem>();
// 使用 System...
}
}
```
## 常见使用模式
### 1. 事件驱动的 System
```csharp
public class InventorySystem : AbstractSystem
{
protected override void OnInit()
{
// 监听物品相关事件
this.RegisterEvent<ItemAddedEvent>(OnItemAdded);
this.RegisterEvent<ItemRemovedEvent>(OnItemRemoved);
this.RegisterEvent<ItemUsedEvent>(OnItemUsed);
}
private void OnItemAdded(ItemAddedEvent e)
{
var inventoryModel = this.GetModel<InventoryModel>();
// 添加物品
inventoryModel.AddItem(e.ItemId, e.Count);
// 检查成就
CheckAchievements(e.ItemId);
// 发送通知
this.SendEvent(new ShowNotificationEvent
{
Message = $"获得物品: {e.ItemId} x{e.Count}"
});
}
private void OnItemUsed(ItemUsedEvent e)
{
var inventoryModel = this.GetModel<InventoryModel>();
var playerModel = this.GetModel<PlayerModel>();
if (inventoryModel.HasItem(e.ItemId))
{
// 应用物品效果
ApplyItemEffect(e.ItemId, playerModel);
// 移除物品
inventoryModel.RemoveItem(e.ItemId, 1);
this.SendEvent(new ItemEffectAppliedEvent { ItemId = e.ItemId });
}
}
private void ApplyItemEffect(string itemId, PlayerModel player)
{
// 物品效果逻辑...
if (itemId == "health_potion")
{
player.Health.Value = Math.Min(
player.Health.Value + 50,
player.MaxHealth.Value
);
}
}
private void CheckAchievements(string itemId)
{
// 成就检查逻辑...
}
}
```
### 2. 定时更新的 System
```csharp
public class BuffSystem : AbstractSystem
{
private List<BuffData> _activeBuffs = new();
protected override void OnInit()
{
this.RegisterEvent<BuffAppliedEvent>(OnBuffApplied);
this.RegisterEvent<GameUpdateEvent>(OnUpdate);
}
private void OnBuffApplied(BuffAppliedEvent e)
{
_activeBuffs.Add(new BuffData
{
BuffId = e.BuffId,
Duration = e.Duration,
RemainingTime = e.Duration
});
ApplyBuffEffect(e.BuffId, true);
}
private void OnUpdate(GameUpdateEvent e)
{
// 更新所有 Buff
for (int i = _activeBuffs.Count - 1; i >= 0; i--)
{
var buff = _activeBuffs[i];
buff.RemainingTime -= e.DeltaTime;
if (buff.RemainingTime <= 0)
{
// Buff 过期
ApplyBuffEffect(buff.BuffId, false);
_activeBuffs.RemoveAt(i);
this.SendEvent(new BuffExpiredEvent { BuffId = buff.BuffId });
}
}
}
private void ApplyBuffEffect(string buffId, bool apply)
{
var playerModel = this.GetModel<PlayerModel>();
// 应用或移除 Buff 效果...
}
}
```
### 3. 跨 System 协作
```csharp
public class QuestSystem : AbstractSystem
{
protected override void OnInit()
{
this.RegisterEvent<EnemyKilledEvent>(OnEnemyKilled);
this.RegisterEvent<ItemCollectedEvent>(OnItemCollected);
}
private void OnEnemyKilled(EnemyKilledEvent e)
{
var questModel = this.GetModel<QuestModel>();
var activeQuests = questModel.GetActiveQuests();
foreach (var quest in activeQuests)
{
if (quest.Type == QuestType.KillEnemy && quest.TargetId == e.EnemyType)
{
quest.Progress++;
if (quest.Progress >= quest.RequiredAmount)
{
// 任务完成
CompleteQuest(quest.Id);
}
}
}
}
private void CompleteQuest(string questId)
{
var questModel = this.GetModel<QuestModel>();
var quest = questModel.GetQuest(questId);
// 标记任务完成
questModel.CompleteQuest(questId);
// 发放奖励(通过其他 System
this.SendEvent(new QuestCompletedEvent
{
QuestId = questId,
Rewards = quest.Rewards
});
}
}
public class RewardSystem : AbstractSystem
{
protected override void OnInit()
{
this.RegisterEvent<QuestCompletedEvent>(OnQuestCompleted);
}
private void OnQuestCompleted(QuestCompletedEvent e)
{
var playerModel = this.GetModel<PlayerModel>();
// 发放奖励
foreach (var reward in e.Rewards)
{
switch (reward.Type)
{
case RewardType.Gold:
playerModel.Gold.Value += reward.Amount;
break;
case RewardType.Experience:
playerModel.Experience.Value += reward.Amount;
break;
case RewardType.Item:
this.SendEvent(new ItemAddedEvent
{
ItemId = reward.ItemId,
Count = reward.Amount
});
break;
}
}
this.SendEvent(new RewardsGrantedEvent { Rewards = e.Rewards });
}
}
```
### 4. 管理复杂状态机
```csharp
public class GameStateSystem : AbstractSystem
{
private GameState _currentState = GameState.MainMenu;
protected override void OnInit()
{
this.RegisterEvent<GameStateChangeRequestEvent>(OnStateChangeRequest);
}
private void OnStateChangeRequest(GameStateChangeRequestEvent e)
{
if (CanTransition(_currentState, e.TargetState))
{
ExitState(_currentState);
_currentState = e.TargetState;
EnterState(_currentState);
this.SendEvent(new GameStateChangedEvent
{
PreviousState = _currentState,
NewState = e.TargetState
});
}
}
private bool CanTransition(GameState from, GameState to)
{
// 状态转换规则
return (from, to) switch
{
(GameState.MainMenu, GameState.Playing) => true,
(GameState.Playing, GameState.Paused) => true,
(GameState.Paused, GameState.Playing) => true,
(GameState.Playing, GameState.GameOver) => true,
_ => false
};
}
private void EnterState(GameState state)
{
switch (state)
{
case GameState.Playing:
// 开始游戏
this.SendCommand(new StartGameCommand());
break;
case GameState.Paused:
// 暂停游戏
this.SendEvent(new GamePausedEvent());
break;
case GameState.GameOver:
// 游戏结束
this.SendCommand(new GameOverCommand());
break;
}
}
private void ExitState(GameState state)
{
// 清理当前状态
}
}
```
## System vs Model
### Model数据层
- **职责**:存储数据和状态
- **特点**:被动,等待修改
- **示例**PlayerModel、InventoryModel
### System逻辑层
- **职责**:处理业务逻辑,协调 Model
- **特点**:主动,响应事件
- **示例**CombatSystem、QuestSystem
```csharp
// ✅ 正确的职责划分
// Model: 存储数据
public class PlayerModel : AbstractModel
{
public BindableProperty<int> Health { get; } = new(100);
public BindableProperty<int> Mana { get; } = new(50);
protected override void OnInit() { }
}
// System: 处理逻辑
public class CombatSystem : AbstractSystem
{
protected override void OnInit()
{
this.RegisterEvent<AttackEvent>(OnAttack);
}
private void OnAttack(AttackEvent e)
{
var playerModel = this.GetModel<PlayerModel>();
// System 负责计算和决策
int damage = CalculateDamage(e);
playerModel.Health.Value -= damage;
if (playerModel.Health.Value <= 0)
{
this.SendEvent(new PlayerDiedEvent());
}
}
}
```
## 最佳实践
1. **单一职责** - 每个 System 专注于一个业务领域
2. **事件驱动** - 通过事件与其他组件通信
3. **无状态或少状态** - 优先将状态存储在 Model 中
4. **可组合** - System 之间通过事件松耦合协作
5. **初始化注册** - 在 `OnInit` 中注册所有事件监听
## 性能优化
### 1. 避免频繁的 GetModel/GetSystem
```csharp
// ❌ 不好:每次都获取
private void OnUpdate(GameUpdateEvent e)
{
var model = this.GetModel<PlayerModel>(); // 频繁调用
// ...
}
// ✅ 好:缓存引用
private PlayerModel _playerModel;
protected override void OnInit()
{
_playerModel = this.GetModel<PlayerModel>(); // 只获取一次
}
private void OnUpdate(GameUpdateEvent e)
{
// 直接使用缓存的引用
_playerModel.Health.Value += 1;
}
```
### 2. 批量处理
```csharp
public class ParticleSystem : AbstractSystem
{
private List<Particle> _particles = new();
private void OnUpdate(GameUpdateEvent e)
{
// 批量更新,而不是每个粒子发一个事件
for (int i = _particles.Count - 1; i >= 0; i--)
{
UpdateParticle(_particles[i], e.DeltaTime);
}
}
}
```
## 相关包
- [`model`](./model.md) - System 操作 Model 的数据
- [`events`](./events.md) - System 通过事件通信
- [`command`](./command.md) - System 中可以发送 Command
- [`query`](./query.md) - System 中可以发送 Query
- [`utility`](./utility.md) - System 可以使用 Utility
- [`architecture`](./architecture.md) - 在架构中注册 System