mirror of
https://github.com/GeWuYou/GFramework.git
synced 2026-03-25 21:34:28 +08:00
Merge pull request #88 from GeWuYou/refactor/controllers-to-context-aware-architecture-access
refactor(docs): 修正文档中关于IController的描述
This commit is contained in:
commit
23f186d395
@ -1,10 +1,38 @@
|
|||||||
namespace GFramework.Core.Abstractions.controller;
|
namespace GFramework.Core.Abstractions.controller;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 控制器接口,定义了控制器的基本契约和行为规范
|
/// 控制器标记接口,用于标识控制器组件
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <remarks>
|
/// <remarks>
|
||||||
/// 该接口为框架中的控制器组件提供统一的抽象定义,
|
/// <para>
|
||||||
/// 用于实现控制器的标准功能和生命周期管理
|
/// IController 是一个标记接口(Marker Interface),不包含任何方法或属性。
|
||||||
|
/// 它的作用是标识一个类是控制器,用于协调 Model、System 和 UI 之间的交互。
|
||||||
|
/// </para>
|
||||||
|
/// <para>
|
||||||
|
/// 架构访问 :控制器通常需要访问架构上下文。使用 [ContextAware] 特性
|
||||||
|
/// 自动生成上下文访问能力:
|
||||||
|
/// </para>
|
||||||
|
/// <code>
|
||||||
|
/// using GFramework.SourceGenerators.Abstractions.rule;
|
||||||
|
///
|
||||||
|
/// [ContextAware]
|
||||||
|
/// public partial class PlayerController : IController
|
||||||
|
/// {
|
||||||
|
/// public void Initialize()
|
||||||
|
/// {
|
||||||
|
/// // [ContextAware] 实现 IContextAware 接口,可使用扩展方法
|
||||||
|
/// var playerModel = this.GetModel<PlayerModel>();
|
||||||
|
/// var gameSystem = this.GetSystem<GameSystem>();
|
||||||
|
/// }
|
||||||
|
/// }
|
||||||
|
/// </code>
|
||||||
|
/// <para>
|
||||||
|
/// 注意:
|
||||||
|
/// </para>
|
||||||
|
/// <list type="bullet">
|
||||||
|
/// <item>必须添加 partial 关键字</item>
|
||||||
|
/// <item>[ContextAware] 特性会自动实现 IContextAware 接口</item>
|
||||||
|
/// <item>可使用 this.GetModel()、this.GetSystem() 等扩展方法访问架构</item>
|
||||||
|
/// </list>
|
||||||
/// </remarks>
|
/// </remarks>
|
||||||
public interface IController;
|
public interface IController;
|
||||||
@ -92,7 +92,7 @@ public partial class PlayerController : Node, IController
|
|||||||
|
|
||||||
public override void _Ready()
|
public override void _Ready()
|
||||||
{
|
{
|
||||||
_playerModel = Context.GetModel<PlayerModel>();
|
_playerModel = this.GetModel<PlayerModel>();
|
||||||
|
|
||||||
// 监听数据变化,更新视图
|
// 监听数据变化,更新视图
|
||||||
_playerModel.Health.Register(UpdateHealthUI);
|
_playerModel.Health.Register(UpdateHealthUI);
|
||||||
@ -107,7 +107,7 @@ public partial class PlayerController : Node, IController
|
|||||||
if (keyEvent.Keycode == Key.Space)
|
if (keyEvent.Keycode == Key.Space)
|
||||||
{
|
{
|
||||||
// 发送命令修改 Model
|
// 发送命令修改 Model
|
||||||
Context.SendCommand(new AttackCommand());
|
this.SendCommand(new AttackCommand());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -238,7 +238,7 @@ public partial class PlayerView : Control, IController
|
|||||||
|
|
||||||
public override void _Ready()
|
public override void _Ready()
|
||||||
{
|
{
|
||||||
_viewModel = Context.GetModel<PlayerViewModel>();
|
_viewModel = this.GetModel<PlayerViewModel>();
|
||||||
|
|
||||||
_healthLabel = GetNode<Label>("HealthLabel");
|
_healthLabel = GetNode<Label>("HealthLabel");
|
||||||
_healthBar = GetNode<ProgressBar>("HealthBar");
|
_healthBar = GetNode<ProgressBar>("HealthBar");
|
||||||
@ -319,10 +319,9 @@ public class BuyItemCommand : AbstractCommand<BuyItemInput>
|
|||||||
}
|
}
|
||||||
|
|
||||||
// 使用命令
|
// 使用命令
|
||||||
public class ShopController : IController
|
[ContextAware]
|
||||||
|
public partial class ShopController : IController
|
||||||
{
|
{
|
||||||
public IArchitecture GetArchitecture() => GameArchitecture.Interface;
|
|
||||||
|
|
||||||
public void OnBuyButtonClicked(string itemId, int quantity)
|
public void OnBuyButtonClicked(string itemId, int quantity)
|
||||||
{
|
{
|
||||||
// 创建并发送命令
|
// 创建并发送命令
|
||||||
@ -456,10 +455,9 @@ public class GetPlayerStatsQuery : AbstractQuery<GetPlayerStatsInput, PlayerS
|
|||||||
}
|
}
|
||||||
|
|
||||||
// 使用查询
|
// 使用查询
|
||||||
public class CharacterPanelController : IController
|
[ContextAware]
|
||||||
|
public partial class CharacterPanelController : IController
|
||||||
{
|
{
|
||||||
public IArchitecture GetArchitecture() => GameArchitecture.Interface;
|
|
||||||
|
|
||||||
public void ShowCharacterStats()
|
public void ShowCharacterStats()
|
||||||
{
|
{
|
||||||
var input = new GetPlayerStatsInput { PlayerId = "player1" };
|
var input = new GetPlayerStatsInput { PlayerId = "player1" };
|
||||||
@ -623,20 +621,19 @@ public class AchievementSystem : AbstractSystem
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Controller 监听事件
|
// Controller 监听事件
|
||||||
public class UIController : IController
|
[ContextAware]
|
||||||
|
public partial class UIController : IController
|
||||||
{
|
{
|
||||||
private IUnRegisterList _unregisterList = new UnRegisterList();
|
private IUnRegisterList _unregisterList = new UnRegisterList();
|
||||||
|
|
||||||
public IArchitecture GetArchitecture() => GameArchitecture.Interface;
|
|
||||||
|
|
||||||
public void Initialize()
|
public void Initialize()
|
||||||
{
|
{
|
||||||
// 监听成就解锁事件
|
// 监听成就解锁事件
|
||||||
this.RegisterEvent<AchievementUnlockedEvent>(OnAchievementUnlocked)
|
this.RegisterEvent<AchievementUnlockedEvent>(OnAchievementUnlocked)
|
||||||
.AddToUnregisterList(_unregisterList);
|
.AddToUnregisterList(_unregisterList);
|
||||||
|
|
||||||
// 监听玩家死亡事件
|
// 监听玩家死亡事件
|
||||||
this.RegisterEvent<PlayerDiedEvent>(OnPlayerDied)
|
this.RegisterEvent<PlayerDiedEvent>(OnPlayerDied)
|
||||||
.AddToUnregisterList(_unregisterList);
|
.AddToUnregisterList(_unregisterList);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -660,8 +657,11 @@ public class UIController : IController
|
|||||||
### 事件组合
|
### 事件组合
|
||||||
|
|
||||||
```csharp
|
```csharp
|
||||||
|
using GFramework.SourceGenerators.Abstractions.rule;
|
||||||
|
|
||||||
// 使用 OrEvent 组合多个事件
|
// 使用 OrEvent 组合多个事件
|
||||||
public class InputController : IController
|
[ContextAware]
|
||||||
|
public partial class InputController : IController
|
||||||
{
|
{
|
||||||
public void Initialize()
|
public void Initialize()
|
||||||
{
|
{
|
||||||
@ -877,14 +877,13 @@ public class GameplaySystem : AbstractSystem
|
|||||||
}
|
}
|
||||||
|
|
||||||
// 在 Controller 中使用
|
// 在 Controller 中使用
|
||||||
public class MenuController : IController
|
[ContextAware]
|
||||||
|
public partial class MenuController : IController
|
||||||
{
|
{
|
||||||
public IArchitecture GetArchitecture() => GameArchitecture.Interface;
|
|
||||||
|
|
||||||
public void OnStartButtonClicked()
|
public void OnStartButtonClicked()
|
||||||
{
|
{
|
||||||
// 通过架构获取服务
|
// 通过架构获取服务
|
||||||
var gameModel = this.GetModel<GameModel>();
|
var gameModel = this.GetModel<GameModel>();
|
||||||
gameModel.GameState.Value = GameState.Playing;
|
gameModel.GameState.Value = GameState.Playing;
|
||||||
|
|
||||||
// 发送命令
|
// 发送命令
|
||||||
@ -1259,26 +1258,25 @@ public class GameArchitecture : Architecture
|
|||||||
}
|
}
|
||||||
|
|
||||||
// 使用状态机
|
// 使用状态机
|
||||||
public class GameController : IController
|
[ContextAware]
|
||||||
|
public partial class GameController : IController
|
||||||
{
|
{
|
||||||
public IArchitecture GetArchitecture() => GameArchitecture.Interface;
|
|
||||||
|
|
||||||
public async Task StartGame()
|
public async Task StartGame()
|
||||||
{
|
{
|
||||||
var stateMachine = this.GetSystem<IStateMachineSystem>();
|
var stateMachine = this.GetSystem<IStateMachineSystem>();
|
||||||
await stateMachine.ChangeToAsync<GameplayState>();
|
await stateMachine.ChangeToAsync<GameplayState>();
|
||||||
}
|
}
|
||||||
|
|
||||||
public async Task PauseGame()
|
public async Task PauseGame()
|
||||||
{
|
{
|
||||||
var stateMachine = this.GetSystem<IStateMachineSystem>();
|
var stateMachine = this.GetSystem<IStateMachineSystem>();
|
||||||
await stateMachine.ChangeToAsync<PauseState>();
|
await stateMachine.ChangeToAsync<PauseState>();
|
||||||
}
|
}
|
||||||
|
|
||||||
public async Task ResumeGame()
|
public async Task ResumeGame()
|
||||||
{
|
{
|
||||||
var stateMachine = this.GetSystem<IStateMachineSystem>();
|
var stateMachine = this.GetSystem<IStateMachineSystem>();
|
||||||
await stateMachine.ChangeToAsync<GameplayState>();
|
await stateMachine.ChangeToAsync<GameplayState>();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
@ -1710,7 +1708,7 @@ namespace Game.Controllers
|
|||||||
|
|
||||||
public override void _Ready()
|
public override void _Ready()
|
||||||
{
|
{
|
||||||
_playerModel = Context.GetModel<PlayerModel>();
|
_playerModel = this.GetModel<PlayerModel>();
|
||||||
|
|
||||||
// 监听用户输入
|
// 监听用户输入
|
||||||
SetProcessInput(true);
|
SetProcessInput(true);
|
||||||
@ -1725,7 +1723,7 @@ namespace Game.Controllers
|
|||||||
if (@event is InputEventKey keyEvent && keyEvent.Pressed)
|
if (@event is InputEventKey keyEvent && keyEvent.Pressed)
|
||||||
{
|
{
|
||||||
var direction = GetInputDirection(keyEvent);
|
var direction = GetInputDirection(keyEvent);
|
||||||
Context.SendEvent(new PlayerInputEvent { Direction = direction });
|
this.SendEvent(new PlayerInputEvent { Direction = direction });
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -32,12 +32,16 @@ public class CombatSystem : AbstractSystem
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public class PlayerController : IController
|
using GFramework.Core.Abstractions.controller;
|
||||||
|
using GFramework.SourceGenerators.Abstractions.rule;
|
||||||
|
|
||||||
|
[ContextAware]
|
||||||
|
public partial class PlayerController : IController
|
||||||
{
|
{
|
||||||
// Controller:连接 UI 和逻辑
|
// Controller:连接 UI 和逻辑
|
||||||
public void Initialize()
|
public void Initialize()
|
||||||
{
|
{
|
||||||
var player = _architecture.GetModel<PlayerModel>();
|
var player = this.GetModel<PlayerModel>();
|
||||||
player.Health.RegisterWithInitValue(OnHealthChanged);
|
player.Health.RegisterWithInitValue(OnHealthChanged);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -177,13 +181,17 @@ public class StorageUtility : IUtility { }
|
|||||||
### 1. 正确的注销管理
|
### 1. 正确的注销管理
|
||||||
|
|
||||||
```csharp
|
```csharp
|
||||||
public class MyController : IController
|
using GFramework.Core.Abstractions.controller;
|
||||||
|
using GFramework.SourceGenerators.Abstractions.rule;
|
||||||
|
|
||||||
|
[ContextAware]
|
||||||
|
public partial class MyController : IController
|
||||||
{
|
{
|
||||||
private IUnRegisterList _unregisterList = new UnRegisterList();
|
private IUnRegisterList _unregisterList = new UnRegisterList();
|
||||||
|
|
||||||
public void Initialize()
|
public void Initialize()
|
||||||
{
|
{
|
||||||
var model = _architecture.GetModel<PlayerModel>();
|
var model = this.GetModel<PlayerModel>();
|
||||||
|
|
||||||
// 注册事件并添加到注销列表
|
// 注册事件并添加到注销列表
|
||||||
this.RegisterEvent<PlayerDiedEvent>(OnPlayerDied)
|
this.RegisterEvent<PlayerDiedEvent>(OnPlayerDied)
|
||||||
@ -235,7 +243,7 @@ public class GameManager
|
|||||||
// ❌ 低效:每次都查询
|
// ❌ 低效:每次都查询
|
||||||
public void Update()
|
public void Update()
|
||||||
{
|
{
|
||||||
var model = _architecture.GetModel<PlayerModel>();
|
var model = this.GetModel<PlayerModel>();
|
||||||
model.Health.Value -= 1;
|
model.Health.Value -= 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -244,7 +252,7 @@ private PlayerModel _playerModel;
|
|||||||
|
|
||||||
public void Initialize()
|
public void Initialize()
|
||||||
{
|
{
|
||||||
_playerModel = _architecture.GetModel<PlayerModel>();
|
_playerModel = this.GetModel<PlayerModel>();
|
||||||
}
|
}
|
||||||
|
|
||||||
public void Update()
|
public void Update()
|
||||||
|
|||||||
@ -277,18 +277,22 @@ public class PoolMonitorSystem : AbstractSystem
|
|||||||
### 1. 避免事件订阅泄漏
|
### 1. 避免事件订阅泄漏
|
||||||
|
|
||||||
```csharp
|
```csharp
|
||||||
|
using GFramework.Core.Abstractions.controller;
|
||||||
|
using GFramework.SourceGenerators.Abstractions.rule;
|
||||||
|
|
||||||
// ✅ 好的做法:正确管理事件订阅
|
// ✅ 好的做法:正确管理事件订阅
|
||||||
public class PlayerController : Node, IController
|
[ContextAware]
|
||||||
|
public partial class PlayerController : Node, IController
|
||||||
{
|
{
|
||||||
private IUnRegisterList _unRegisterList = new UnRegisterList();
|
private IUnRegisterList _unRegisterList = new UnRegisterList();
|
||||||
private PlayerModel _playerModel;
|
private PlayerModel _playerModel;
|
||||||
|
|
||||||
public void Initialize(IArchitectureContext context)
|
public void Initialize()
|
||||||
{
|
{
|
||||||
_playerModel = context.GetModel<PlayerModel>();
|
_playerModel = this.GetModel<PlayerModel>();
|
||||||
|
|
||||||
// 使用 UnRegisterList 管理订阅
|
// 使用 UnRegisterList 管理订阅
|
||||||
context.RegisterEvent<PlayerDamagedEvent>(OnPlayerDamaged)
|
this.RegisterEvent<PlayerDamagedEvent>(OnPlayerDamaged)
|
||||||
.AddTo(_unRegisterList);
|
.AddTo(_unRegisterList);
|
||||||
|
|
||||||
_playerModel.Health.Register(OnHealthChanged)
|
_playerModel.Health.Register(OnHealthChanged)
|
||||||
@ -306,14 +310,15 @@ public class PlayerController : Node, IController
|
|||||||
}
|
}
|
||||||
|
|
||||||
// ❌ 避免:忘记取消订阅
|
// ❌ 避免:忘记取消订阅
|
||||||
public class PlayerController : Node, IController
|
[ContextAware]
|
||||||
|
public partial class PlayerController : Node, IController
|
||||||
{
|
{
|
||||||
public void Initialize(IArchitectureContext context)
|
public void Initialize()
|
||||||
{
|
{
|
||||||
// 订阅事件但从不取消订阅
|
// 订阅事件但从不取消订阅
|
||||||
context.RegisterEvent<PlayerDamagedEvent>(OnPlayerDamaged);
|
this.RegisterEvent<PlayerDamagedEvent>(OnPlayerDamaged);
|
||||||
|
|
||||||
var playerModel = context.GetModel<PlayerModel>();
|
var playerModel = this.GetModel<PlayerModel>();
|
||||||
playerModel.Health.Register(OnHealthChanged);
|
playerModel.Health.Register(OnHealthChanged);
|
||||||
|
|
||||||
// 当对象被销毁时,这些订阅仍然存在,导致内存泄漏
|
// 当对象被销毁时,这些订阅仍然存在,导致内存泄漏
|
||||||
|
|||||||
@ -176,13 +176,15 @@ await architecture.WaitUntilReadyAsync();
|
|||||||
|
|
||||||
// 4. 通过依赖注入使用架构
|
// 4. 通过依赖注入使用架构
|
||||||
// 在 Controller 或其他组件中获取架构实例
|
// 在 Controller 或其他组件中获取架构实例
|
||||||
public class GameController : IController
|
using GFramework.Core.Abstractions.controller;
|
||||||
{
|
using GFramework.SourceGenerators.Abstractions.rule;
|
||||||
public IArchitecture GetArchitecture() => GameArchitecture.Interface;
|
|
||||||
|
|
||||||
|
[ContextAware]
|
||||||
|
public partial class GameController : IController
|
||||||
|
{
|
||||||
public void Start()
|
public void Start()
|
||||||
{
|
{
|
||||||
// 获取 Model
|
// 获取 Model(使用扩展方法访问架构([ContextAware] 实现 IContextAware 接口))
|
||||||
var playerModel = this.GetModel<PlayerModel>();
|
var playerModel = this.GetModel<PlayerModel>();
|
||||||
|
|
||||||
// 发送命令
|
// 发送命令
|
||||||
|
|||||||
@ -56,10 +56,12 @@ public class SimpleCommand : AbstractCommand
|
|||||||
}
|
}
|
||||||
|
|
||||||
// 使用命令
|
// 使用命令
|
||||||
public class GameController : IController
|
using GFramework.Core.Abstractions.controller;
|
||||||
{
|
using GFramework.SourceGenerators.Abstractions.rule;
|
||||||
public IArchitecture GetArchitecture() => GameArchitecture.Interface;
|
|
||||||
|
|
||||||
|
[ContextAware]
|
||||||
|
public partial class GameController : IController
|
||||||
|
{
|
||||||
public void OnRestoreHealthButtonClicked()
|
public void OnRestoreHealthButtonClicked()
|
||||||
{
|
{
|
||||||
this.SendCommand(new SimpleCommand());
|
this.SendCommand(new SimpleCommand());
|
||||||
@ -194,10 +196,12 @@ public class StartGameCommand : AbstractCommand<StartGameInput>
|
|||||||
}
|
}
|
||||||
|
|
||||||
// 使用命令
|
// 使用命令
|
||||||
public class GameController : IController
|
using GFramework.Core.Abstractions.controller;
|
||||||
{
|
using GFramework.SourceGenerators.Abstractions.rule;
|
||||||
public IArchitecture GetArchitecture() => GameArchitecture.Interface;
|
|
||||||
|
|
||||||
|
[ContextAware]
|
||||||
|
public partial class GameController : IController
|
||||||
|
{
|
||||||
public void OnStartButtonClicked()
|
public void OnStartButtonClicked()
|
||||||
{
|
{
|
||||||
var input = new StartGameInput { LevelId = 1, PlayerName = "Player1" };
|
var input = new StartGameInput { LevelId = 1, PlayerName = "Player1" };
|
||||||
|
|||||||
@ -622,10 +622,11 @@ public class SettingsSystem : AbstractSystem
|
|||||||
### 在 Controller 中使用
|
### 在 Controller 中使用
|
||||||
|
|
||||||
```csharp
|
```csharp
|
||||||
public class SettingsController : IController
|
using GFramework.SourceGenerators.Abstractions.rule;
|
||||||
{
|
|
||||||
public IArchitecture GetArchitecture() => GameArchitecture.Interface;
|
|
||||||
|
|
||||||
|
[ContextAware]
|
||||||
|
public partial class SettingsController : IController
|
||||||
|
{
|
||||||
public void ApplyGraphicsSettings(int quality, bool fullscreen)
|
public void ApplyGraphicsSettings(int quality, bool fullscreen)
|
||||||
{
|
{
|
||||||
var config = this.GetUtility<IConfigurationManager>();
|
var config = this.GetUtility<IConfigurationManager>();
|
||||||
|
|||||||
@ -232,13 +232,14 @@ public class GameArchitecture : Architecture
|
|||||||
using Arch.Core;
|
using Arch.Core;
|
||||||
using GFramework.Core.Abstractions.controller;
|
using GFramework.Core.Abstractions.controller;
|
||||||
using MyGame.Components;
|
using MyGame.Components;
|
||||||
|
using GFramework.Core.Abstractions.controller;
|
||||||
|
using GFramework.SourceGenerators.Abstractions.rule;
|
||||||
|
|
||||||
public class GameController : IController
|
[ContextAware]
|
||||||
|
public partial class GameController : IController
|
||||||
{
|
{
|
||||||
private World _world;
|
private World _world;
|
||||||
|
|
||||||
public IArchitecture GetArchitecture() => GameArchitecture.Interface;
|
|
||||||
|
|
||||||
public void Start()
|
public void Start()
|
||||||
{
|
{
|
||||||
// 获取 World
|
// 获取 World
|
||||||
|
|||||||
@ -353,12 +353,14 @@ public class CombatSystem : AbstractSystem
|
|||||||
### Controller 中注册事件
|
### Controller 中注册事件
|
||||||
|
|
||||||
```csharp
|
```csharp
|
||||||
public class GameController : IController
|
using GFramework.Core.Abstractions.controller;
|
||||||
|
using GFramework.SourceGenerators.Abstractions.rule;
|
||||||
|
|
||||||
|
[ContextAware]
|
||||||
|
public partial class GameController : IController
|
||||||
{
|
{
|
||||||
private IUnRegisterList _unregisterList = new UnRegisterList();
|
private IUnRegisterList _unregisterList = new UnRegisterList();
|
||||||
|
|
||||||
public IArchitecture GetArchitecture() => GameArchitecture.Interface;
|
|
||||||
|
|
||||||
public void Initialize()
|
public void Initialize()
|
||||||
{
|
{
|
||||||
// 注册多个事件
|
// 注册多个事件
|
||||||
@ -449,10 +451,12 @@ public class EventBridge : AbstractSystem
|
|||||||
### 4. 临时事件监听
|
### 4. 临时事件监听
|
||||||
|
|
||||||
```csharp
|
```csharp
|
||||||
public class TutorialController : IController
|
using GFramework.Core.Abstractions.controller;
|
||||||
{
|
using GFramework.SourceGenerators.Abstractions.rule;
|
||||||
public IArchitecture GetArchitecture() => GameArchitecture.Interface;
|
|
||||||
|
|
||||||
|
[ContextAware]
|
||||||
|
public partial class TutorialController : IController
|
||||||
|
{
|
||||||
public void Initialize()
|
public void Initialize()
|
||||||
{
|
{
|
||||||
// 只监听一次
|
// 只监听一次
|
||||||
@ -497,7 +501,11 @@ public class AchievementSystem : AbstractSystem
|
|||||||
### 使用 UnRegisterList
|
### 使用 UnRegisterList
|
||||||
|
|
||||||
```csharp
|
```csharp
|
||||||
public class MyController : IController
|
using GFramework.Core.Abstractions.controller;
|
||||||
|
using GFramework.SourceGenerators.Abstractions.rule;
|
||||||
|
|
||||||
|
[ContextAware]
|
||||||
|
public partial class MyController : IController
|
||||||
{
|
{
|
||||||
// 统一管理所有注销对象
|
// 统一管理所有注销对象
|
||||||
private IUnRegisterList _unregisterList = new UnRegisterList();
|
private IUnRegisterList _unregisterList = new UnRegisterList();
|
||||||
|
|||||||
@ -109,12 +109,13 @@ event Action<PauseGroup, bool>? OnPauseStateChanged;
|
|||||||
### 1. 获取暂停管理器
|
### 1. 获取暂停管理器
|
||||||
|
|
||||||
```csharp
|
```csharp
|
||||||
public class GameController : IController
|
using GFramework.SourceGenerators.Abstractions.rule;
|
||||||
|
|
||||||
|
[ContextAware]
|
||||||
|
public partial class GameController : IController
|
||||||
{
|
{
|
||||||
private IPauseStackManager _pauseManager;
|
private IPauseStackManager _pauseManager;
|
||||||
|
|
||||||
public IArchitecture GetArchitecture() => GameArchitecture.Interface;
|
|
||||||
|
|
||||||
public void Initialize()
|
public void Initialize()
|
||||||
{
|
{
|
||||||
// 从架构中获取暂停管理器
|
// 从架构中获取暂停管理器
|
||||||
@ -126,13 +127,14 @@ public class GameController : IController
|
|||||||
### 2. 简单的暂停/恢复
|
### 2. 简单的暂停/恢复
|
||||||
|
|
||||||
```csharp
|
```csharp
|
||||||
public class PauseMenuController : IController
|
using GFramework.SourceGenerators.Abstractions.rule;
|
||||||
|
|
||||||
|
[ContextAware]
|
||||||
|
public partial class PauseMenuController : IController
|
||||||
{
|
{
|
||||||
private IPauseStackManager _pauseManager;
|
private IPauseStackManager _pauseManager;
|
||||||
private PauseToken _pauseToken;
|
private PauseToken _pauseToken;
|
||||||
|
|
||||||
public IArchitecture GetArchitecture() => GameArchitecture.Interface;
|
|
||||||
|
|
||||||
public void Initialize()
|
public void Initialize()
|
||||||
{
|
{
|
||||||
_pauseManager = this.GetUtility<IPauseStackManager>();
|
_pauseManager = this.GetUtility<IPauseStackManager>();
|
||||||
@ -161,12 +163,13 @@ public class PauseMenuController : IController
|
|||||||
### 3. 使用作用域自动管理
|
### 3. 使用作用域自动管理
|
||||||
|
|
||||||
```csharp
|
```csharp
|
||||||
public class DialogController : IController
|
using GFramework.SourceGenerators.Abstractions.rule;
|
||||||
|
|
||||||
|
[ContextAware]
|
||||||
|
public partial class DialogController : IController
|
||||||
{
|
{
|
||||||
private IPauseStackManager _pauseManager;
|
private IPauseStackManager _pauseManager;
|
||||||
|
|
||||||
public IArchitecture GetArchitecture() => GameArchitecture.Interface;
|
|
||||||
|
|
||||||
public void ShowDialog(string message)
|
public void ShowDialog(string message)
|
||||||
{
|
{
|
||||||
// 使用 using 语法,自动管理暂停生命周期
|
// 使用 using 语法,自动管理暂停生命周期
|
||||||
@ -212,12 +215,13 @@ public class GameplaySystem : AbstractSystem
|
|||||||
### 1. 嵌套暂停
|
### 1. 嵌套暂停
|
||||||
|
|
||||||
```csharp
|
```csharp
|
||||||
public class UIManager : IController
|
using GFramework.SourceGenerators.Abstractions.rule;
|
||||||
|
|
||||||
|
[ContextAware]
|
||||||
|
public partial class UIManager : IController
|
||||||
{
|
{
|
||||||
private IPauseStackManager _pauseManager;
|
private IPauseStackManager _pauseManager;
|
||||||
|
|
||||||
public IArchitecture GetArchitecture() => GameArchitecture.Interface;
|
|
||||||
|
|
||||||
public void ShowNestedMenus()
|
public void ShowNestedMenus()
|
||||||
{
|
{
|
||||||
// 第一层:主菜单
|
// 第一层:主菜单
|
||||||
@ -250,12 +254,13 @@ public class UIManager : IController
|
|||||||
### 2. 分组暂停
|
### 2. 分组暂停
|
||||||
|
|
||||||
```csharp
|
```csharp
|
||||||
public class GameManager : IController
|
using GFramework.SourceGenerators.Abstractions.rule;
|
||||||
|
|
||||||
|
[ContextAware]
|
||||||
|
public partial class GameManager : IController
|
||||||
{
|
{
|
||||||
private IPauseStackManager _pauseManager;
|
private IPauseStackManager _pauseManager;
|
||||||
|
|
||||||
public IArchitecture GetArchitecture() => GameArchitecture.Interface;
|
|
||||||
|
|
||||||
public void OpenInventory()
|
public void OpenInventory()
|
||||||
{
|
{
|
||||||
// 只暂停游戏逻辑,UI 和音频继续运行
|
// 只暂停游戏逻辑,UI 和音频继续运行
|
||||||
@ -357,12 +362,13 @@ public class GameInitializer
|
|||||||
### 4. 监听暂停状态变化
|
### 4. 监听暂停状态变化
|
||||||
|
|
||||||
```csharp
|
```csharp
|
||||||
public class PauseIndicator : IController
|
using GFramework.SourceGenerators.Abstractions.rule;
|
||||||
|
|
||||||
|
[ContextAware]
|
||||||
|
public partial class PauseIndicator : IController
|
||||||
{
|
{
|
||||||
private IPauseStackManager _pauseManager;
|
private IPauseStackManager _pauseManager;
|
||||||
|
|
||||||
public IArchitecture GetArchitecture() => GameArchitecture.Interface;
|
|
||||||
|
|
||||||
public void Initialize()
|
public void Initialize()
|
||||||
{
|
{
|
||||||
_pauseManager = this.GetUtility<IPauseStackManager>();
|
_pauseManager = this.GetUtility<IPauseStackManager>();
|
||||||
@ -398,12 +404,13 @@ public class PauseIndicator : IController
|
|||||||
### 5. 调试暂停状态
|
### 5. 调试暂停状态
|
||||||
|
|
||||||
```csharp
|
```csharp
|
||||||
public class PauseDebugger : IController
|
using GFramework.SourceGenerators.Abstractions.rule;
|
||||||
|
|
||||||
|
[ContextAware]
|
||||||
|
public partial class PauseDebugger : IController
|
||||||
{
|
{
|
||||||
private IPauseStackManager _pauseManager;
|
private IPauseStackManager _pauseManager;
|
||||||
|
|
||||||
public IArchitecture GetArchitecture() => GameArchitecture.Interface;
|
|
||||||
|
|
||||||
public void PrintPauseStatus()
|
public void PrintPauseStatus()
|
||||||
{
|
{
|
||||||
Console.WriteLine("=== 暂停状态 ===");
|
Console.WriteLine("=== 暂停状态 ===");
|
||||||
@ -434,12 +441,13 @@ public class PauseDebugger : IController
|
|||||||
### 6. 紧急恢复
|
### 6. 紧急恢复
|
||||||
|
|
||||||
```csharp
|
```csharp
|
||||||
public class EmergencyController : IController
|
using GFramework.SourceGenerators.Abstractions.rule;
|
||||||
|
|
||||||
|
[ContextAware]
|
||||||
|
public partial class EmergencyController : IController
|
||||||
{
|
{
|
||||||
private IPauseStackManager _pauseManager;
|
private IPauseStackManager _pauseManager;
|
||||||
|
|
||||||
public IArchitecture GetArchitecture() => GameArchitecture.Interface;
|
|
||||||
|
|
||||||
public void ForceResumeAll()
|
public void ForceResumeAll()
|
||||||
{
|
{
|
||||||
// 清空所有暂停请求(谨慎使用)
|
// 清空所有暂停请求(谨慎使用)
|
||||||
@ -674,13 +682,14 @@ public class ThreadSafeUsage
|
|||||||
在组件销毁时注销处理器和事件:
|
在组件销毁时注销处理器和事件:
|
||||||
|
|
||||||
```csharp
|
```csharp
|
||||||
public class ProperCleanup : IController
|
using GFramework.SourceGenerators.Abstractions.rule;
|
||||||
|
|
||||||
|
[ContextAware]
|
||||||
|
public partial class ProperCleanup : IController
|
||||||
{
|
{
|
||||||
private IPauseStackManager _pauseManager;
|
private IPauseStackManager _pauseManager;
|
||||||
private IPauseHandler _customHandler;
|
private IPauseHandler _customHandler;
|
||||||
|
|
||||||
public IArchitecture GetArchitecture() => GameArchitecture.Interface;
|
|
||||||
|
|
||||||
public void Initialize()
|
public void Initialize()
|
||||||
{
|
{
|
||||||
_pauseManager = this.GetUtility<IPauseStackManager>();
|
_pauseManager = this.GetUtility<IPauseStackManager>();
|
||||||
@ -775,12 +784,13 @@ public class SelectiveSystem : AbstractSystem
|
|||||||
A: 暂停系统控制是否执行,时间缩放需要使用时间系统:
|
A: 暂停系统控制是否执行,时间缩放需要使用时间系统:
|
||||||
|
|
||||||
```csharp
|
```csharp
|
||||||
public class SlowMotionController : IController
|
using GFramework.SourceGenerators.Abstractions.rule;
|
||||||
|
|
||||||
|
[ContextAware]
|
||||||
|
public partial class SlowMotionController : IController
|
||||||
{
|
{
|
||||||
private ITimeProvider _timeProvider;
|
private ITimeProvider _timeProvider;
|
||||||
|
|
||||||
public IArchitecture GetArchitecture() => GameArchitecture.Interface;
|
|
||||||
|
|
||||||
public void EnableSlowMotion()
|
public void EnableSlowMotion()
|
||||||
{
|
{
|
||||||
// 使用时间缩放而不是暂停
|
// 使用时间缩放而不是暂停
|
||||||
@ -819,12 +829,13 @@ _pauseManager.Push("AI 系统", PauseGroup.Custom3);
|
|||||||
A: 使用 `PauseScope` 配合 `async/await`:
|
A: 使用 `PauseScope` 配合 `async/await`:
|
||||||
|
|
||||||
```csharp
|
```csharp
|
||||||
public class AsyncPauseExample : IController
|
using GFramework.SourceGenerators.Abstractions.rule;
|
||||||
|
|
||||||
|
[ContextAware]
|
||||||
|
public partial class AsyncPauseExample : IController
|
||||||
{
|
{
|
||||||
private IPauseStackManager _pauseManager;
|
private IPauseStackManager _pauseManager;
|
||||||
|
|
||||||
public IArchitecture GetArchitecture() => GameArchitecture.Interface;
|
|
||||||
|
|
||||||
public async Task ShowAsyncDialog()
|
public async Task ShowAsyncDialog()
|
||||||
{
|
{
|
||||||
using (_pauseManager.PauseScope("异步对话框"))
|
using (_pauseManager.PauseScope("异步对话框"))
|
||||||
|
|||||||
@ -198,6 +198,10 @@ public class PlayerModel : AbstractModel
|
|||||||
### UI 数据绑定
|
### UI 数据绑定
|
||||||
|
|
||||||
```csharp
|
```csharp
|
||||||
|
using GFramework.Core.Abstractions.controller;
|
||||||
|
using GFramework.SourceGenerators.Abstractions.rule;
|
||||||
|
|
||||||
|
[ContextAware]
|
||||||
public partial class PlayerUI : Control, IController
|
public partial class PlayerUI : Control, IController
|
||||||
{
|
{
|
||||||
[Export] private Label _healthLabel;
|
[Export] private Label _healthLabel;
|
||||||
@ -206,8 +210,6 @@ public partial class PlayerUI : Control, IController
|
|||||||
|
|
||||||
private IUnRegisterList _unregisterList = new UnRegisterList();
|
private IUnRegisterList _unregisterList = new UnRegisterList();
|
||||||
|
|
||||||
public IArchitecture GetArchitecture() => GameArchitecture.Interface;
|
|
||||||
|
|
||||||
public override void _Ready()
|
public override void _Ready()
|
||||||
{
|
{
|
||||||
var playerModel = this.GetModel<PlayerModel>();
|
var playerModel = this.GetModel<PlayerModel>();
|
||||||
@ -269,6 +271,7 @@ public class SettingsModel : AbstractModel
|
|||||||
}
|
}
|
||||||
|
|
||||||
// UI Controller
|
// UI Controller
|
||||||
|
[ContextAware]
|
||||||
public partial class VolumeSlider : HSlider, IController
|
public partial class VolumeSlider : HSlider, IController
|
||||||
{
|
{
|
||||||
private BindableProperty<float> _volumeProperty;
|
private BindableProperty<float> _volumeProperty;
|
||||||
@ -339,7 +342,11 @@ public class PlayerModel : AbstractModel
|
|||||||
### 4. 条件监听
|
### 4. 条件监听
|
||||||
|
|
||||||
```c#
|
```c#
|
||||||
public class CombatController : Node, IController
|
using GFramework.Core.Abstractions.controller;
|
||||||
|
using GFramework.SourceGenerators.Abstractions.rule;
|
||||||
|
|
||||||
|
[ContextAware]
|
||||||
|
public partial class CombatController : Node, IController
|
||||||
{
|
{
|
||||||
public override void _Ready()
|
public override void _Ready()
|
||||||
{
|
{
|
||||||
|
|||||||
@ -144,13 +144,15 @@ public class LoadPlayerDataQuery : AbstractAsyncQuery<LoadPlayerDataInput, Playe
|
|||||||
### 2. 发送查询
|
### 2. 发送查询
|
||||||
|
|
||||||
```csharp
|
```csharp
|
||||||
public class ShopUI : IController
|
using GFramework.Core.Abstractions.controller;
|
||||||
|
using GFramework.SourceGenerators.Abstractions.rule;
|
||||||
|
|
||||||
|
[ContextAware]
|
||||||
|
public partial class ShopUI : IController
|
||||||
{
|
{
|
||||||
[Export] private Button _buyButton;
|
[Export] private Button _buyButton;
|
||||||
[Export] private int _itemPrice = 100;
|
[Export] private int _itemPrice = 100;
|
||||||
|
|
||||||
public IArchitecture GetArchitecture() => GameArchitecture.Interface;
|
|
||||||
|
|
||||||
public void OnReady()
|
public void OnReady()
|
||||||
{
|
{
|
||||||
_buyButton.Pressed += OnBuyButtonPressed;
|
_buyButton.Pressed += OnBuyButtonPressed;
|
||||||
|
|||||||
@ -128,10 +128,12 @@ public class GameArchitecture : Architecture
|
|||||||
### 切换状态
|
### 切换状态
|
||||||
|
|
||||||
```csharp
|
```csharp
|
||||||
public class GameController : IController
|
using GFramework.Core.Abstractions.controller;
|
||||||
{
|
using GFramework.SourceGenerators.Abstractions.rule;
|
||||||
public IArchitecture GetArchitecture() => GameArchitecture.Interface;
|
|
||||||
|
|
||||||
|
[ContextAware]
|
||||||
|
public partial class GameController : IController
|
||||||
|
{
|
||||||
public async Task StartGame()
|
public async Task StartGame()
|
||||||
{
|
{
|
||||||
var stateMachine = this.GetSystem<IStateMachineSystem>();
|
var stateMachine = this.GetSystem<IStateMachineSystem>();
|
||||||
@ -218,7 +220,11 @@ public class LoadingState : AsyncContextAwareStateBase
|
|||||||
### 状态历史和回退
|
### 状态历史和回退
|
||||||
|
|
||||||
```csharp
|
```csharp
|
||||||
public class GameController : IController
|
using GFramework.Core.Abstractions.controller;
|
||||||
|
using GFramework.SourceGenerators.Abstractions.rule;
|
||||||
|
|
||||||
|
[ContextAware]
|
||||||
|
public partial class GameController : IController
|
||||||
{
|
{
|
||||||
public async Task NavigateBack()
|
public async Task NavigateBack()
|
||||||
{
|
{
|
||||||
|
|||||||
@ -185,10 +185,12 @@ public class GameArchitecture : Architecture
|
|||||||
|
|
||||||
```csharp
|
```csharp
|
||||||
// 在 Controller 中
|
// 在 Controller 中
|
||||||
public class GameController : IController
|
using GFramework.Core.Abstractions.controller;
|
||||||
{
|
using GFramework.SourceGenerators.Abstractions.rule;
|
||||||
public IArchitecture GetArchitecture() => GameArchitecture.Interface;
|
|
||||||
|
|
||||||
|
[ContextAware]
|
||||||
|
public partial class GameController : IController
|
||||||
|
{
|
||||||
public void Start()
|
public void Start()
|
||||||
{
|
{
|
||||||
// 获取 System
|
// 获取 System
|
||||||
|
|||||||
@ -102,10 +102,12 @@ public class SaveData : IVersionedData
|
|||||||
### 使用存档仓库
|
### 使用存档仓库
|
||||||
|
|
||||||
```csharp
|
```csharp
|
||||||
public class SaveController : IController
|
using GFramework.Core.Abstractions.controller;
|
||||||
{
|
using GFramework.SourceGenerators.Abstractions.rule;
|
||||||
public IArchitecture GetArchitecture() => GameArchitecture.Interface;
|
|
||||||
|
|
||||||
|
[ContextAware]
|
||||||
|
public partial class SaveController : IController
|
||||||
|
{
|
||||||
public async Task SaveGame(int slot)
|
public async Task SaveGame(int slot)
|
||||||
{
|
{
|
||||||
var saveRepo = this.GetUtility<ISaveRepository<SaveData>>();
|
var saveRepo = this.GetUtility<ISaveRepository<SaveData>>();
|
||||||
@ -207,7 +209,11 @@ public async Task ShowSaveList()
|
|||||||
### 自动保存
|
### 自动保存
|
||||||
|
|
||||||
```csharp
|
```csharp
|
||||||
public class AutoSaveController : IController
|
using GFramework.Core.Abstractions.controller;
|
||||||
|
using GFramework.SourceGenerators.Abstractions.rule;
|
||||||
|
|
||||||
|
[ContextAware]
|
||||||
|
public partial class AutoSaveController : IController
|
||||||
{
|
{
|
||||||
private CancellationTokenSource? _autoSaveCts;
|
private CancellationTokenSource? _autoSaveCts;
|
||||||
|
|
||||||
@ -318,7 +324,11 @@ public async Task<SaveDataV2> LoadWithMigration(int slot)
|
|||||||
### 使用数据仓库
|
### 使用数据仓库
|
||||||
|
|
||||||
```csharp
|
```csharp
|
||||||
public class SettingsController : IController
|
using GFramework.Core.Abstractions.controller;
|
||||||
|
using GFramework.SourceGenerators.Abstractions.rule;
|
||||||
|
|
||||||
|
[ContextAware]
|
||||||
|
public partial class SettingsController : IController
|
||||||
{
|
{
|
||||||
public async Task SaveSettings()
|
public async Task SaveSettings()
|
||||||
{
|
{
|
||||||
|
|||||||
@ -937,7 +937,7 @@ public partial class GameManager : Node, IController
|
|||||||
// 加载初始场景
|
// 加载初始场景
|
||||||
LoadInitialScene();
|
LoadInitialScene();
|
||||||
|
|
||||||
Context.SendEvent(new NewGameStartedEvent { PlayerName = playerName });
|
this.SendEvent(new NewGameStartedEvent { PlayerName = playerName });
|
||||||
}
|
}
|
||||||
|
|
||||||
public void LoadGame(int slotId)
|
public void LoadGame(int slotId)
|
||||||
@ -952,19 +952,19 @@ public partial class GameManager : Node, IController
|
|||||||
// 恢复游戏状态
|
// 恢复游戏状态
|
||||||
RestoreGameState(saveData);
|
RestoreGameState(saveData);
|
||||||
|
|
||||||
Context.SendEvent(new GameLoadedEvent { SlotId = slotId });
|
this.SendEvent(new GameLoadedEvent { SlotId = slotId });
|
||||||
Logger.Info("Game loaded successfully");
|
Logger.Info("Game loaded successfully");
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
Logger.Warning($"No save data found in slot {slotId}");
|
Logger.Warning($"No save data found in slot {slotId}");
|
||||||
Context.SendEvent(new GameLoadFailedEvent { SlotId = slotId });
|
this.SendEvent(new GameLoadFailedEvent { SlotId = slotId });
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
{
|
{
|
||||||
Logger.Error($"Failed to load game: {ex.Message}");
|
Logger.Error($"Failed to load game: {ex.Message}");
|
||||||
Context.SendEvent(new GameLoadFailedEvent { SlotId = slotId, Error = ex.Message });
|
this.SendEvent(new GameLoadFailedEvent { SlotId = slotId, Error = ex.Message });
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -977,13 +977,13 @@ public partial class GameManager : Node, IController
|
|||||||
var saveData = CreateSaveData();
|
var saveData = CreateSaveData();
|
||||||
_dataManager.SaveGame(slotId, saveData);
|
_dataManager.SaveGame(slotId, saveData);
|
||||||
|
|
||||||
Context.SendEvent(new GameSavedEvent { SlotId = slotId });
|
this.SendEvent(new GameSavedEvent { SlotId = slotId });
|
||||||
Logger.Info("Game saved successfully");
|
Logger.Info("Game saved successfully");
|
||||||
}
|
}
|
||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
{
|
{
|
||||||
Logger.Error($"Failed to save game: {ex.Message}");
|
Logger.Error($"Failed to save game: {ex.Message}");
|
||||||
Context.SendEvent(new GameSaveFailedEvent { SlotId = slotId, Error = ex.Message });
|
this.SendEvent(new GameSaveFailedEvent { SlotId = slotId, Error = ex.Message });
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1014,9 +1014,9 @@ public partial class GameManager : Node, IController
|
|||||||
gameWorld.AddChild(player);
|
gameWorld.AddChild(player);
|
||||||
|
|
||||||
// 恢复其他游戏状态
|
// 恢复其他游戏状态
|
||||||
Context.GetModel<PlayerModel>().Health.Value = saveData.PlayerHealth;
|
this.GetModel<PlayerModel>().Health.Value = saveData.PlayerHealth;
|
||||||
Context.GetModel<GameModel>().CurrentLevel.Value = saveData.CurrentLevel;
|
this.GetModel<GameModel>().CurrentLevel.Value = saveData.CurrentLevel;
|
||||||
Context.GetModel<InventoryModel>().LoadFromData(saveData.Inventory);
|
this.GetModel<InventoryModel>().LoadFromData(saveData.Inventory);
|
||||||
}
|
}
|
||||||
|
|
||||||
private SaveData CreateSaveData()
|
private SaveData CreateSaveData()
|
||||||
@ -1026,9 +1026,9 @@ public partial class GameManager : Node, IController
|
|||||||
return new SaveData
|
return new SaveData
|
||||||
{
|
{
|
||||||
PlayerPosition = player?.Position ?? Vector2.Zero,
|
PlayerPosition = player?.Position ?? Vector2.Zero,
|
||||||
PlayerHealth = Context.GetModel<PlayerModel>().Health.Value,
|
PlayerHealth = this.GetModel<PlayerModel>().Health.Value,
|
||||||
CurrentLevel = Context.GetModel<GameModel>().CurrentLevel.Value,
|
CurrentLevel = this.GetModel<GameModel>().CurrentLevel.Value,
|
||||||
Inventory = Context.GetModel<InventoryModel>().GetData(),
|
Inventory = this.GetModel<InventoryModel>().GetData(),
|
||||||
Timestamp = DateTime.UtcNow,
|
Timestamp = DateTime.UtcNow,
|
||||||
Version = 1
|
Version = 1
|
||||||
};
|
};
|
||||||
@ -1094,7 +1094,7 @@ public class AutoSaveSystem : AbstractSystem
|
|||||||
var saveData = CreateAutoSaveData();
|
var saveData = CreateAutoSaveData();
|
||||||
|
|
||||||
// 保存到自动存档槽
|
// 保存到自动存档槽
|
||||||
var storage = Context.GetUtility<IStorage>();
|
var storage = this.GetUtility<IStorage>();
|
||||||
storage.Write("autosave", saveData);
|
storage.Write("autosave", saveData);
|
||||||
storage.Write("autosave/timestamp", DateTime.UtcNow);
|
storage.Write("autosave/timestamp", DateTime.UtcNow);
|
||||||
|
|
||||||
@ -1330,7 +1330,7 @@ public class PlayerModule : AbstractModule
|
|||||||
private void OnPlayerDeath(PlayerDeathEvent e)
|
private void OnPlayerDeath(PlayerDeathEvent e)
|
||||||
{
|
{
|
||||||
// 触发保存模块的事件
|
// 触发保存模块的事件
|
||||||
Context.SendEvent(new RequestAutoSaveEvent { Reason = "Player Death" });
|
this.SendEvent(new RequestAutoSaveEvent { Reason = "Player Death" });
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|||||||
@ -164,10 +164,12 @@ public class GameSceneRegistry : IGameSceneRegistry
|
|||||||
使用场景路由进行导航:
|
使用场景路由进行导航:
|
||||||
|
|
||||||
```csharp
|
```csharp
|
||||||
public class GameController : IController
|
using GFramework.Core.Abstractions.controller;
|
||||||
{
|
using GFramework.SourceGenerators.Abstractions.rule;
|
||||||
public IArchitecture GetArchitecture() => GameArchitecture.Interface;
|
|
||||||
|
|
||||||
|
[ContextAware]
|
||||||
|
public partial class GameController : IController
|
||||||
|
{
|
||||||
public async Task StartGame()
|
public async Task StartGame()
|
||||||
{
|
{
|
||||||
var sceneRouter = this.GetSystem<ISceneRouter>();
|
var sceneRouter = this.GetSystem<ISceneRouter>();
|
||||||
@ -350,10 +352,12 @@ sceneRouter.AddTransitionHandler(new FadeTransitionHandler());
|
|||||||
### 场景栈管理
|
### 场景栈管理
|
||||||
|
|
||||||
```csharp
|
```csharp
|
||||||
public class SceneNavigationController : IController
|
using GFramework.Core.Abstractions.controller;
|
||||||
{
|
using GFramework.SourceGenerators.Abstractions.rule;
|
||||||
public IArchitecture GetArchitecture() => GameArchitecture.Interface;
|
|
||||||
|
|
||||||
|
[ContextAware]
|
||||||
|
public partial class SceneNavigationController : IController
|
||||||
|
{
|
||||||
public async Task NavigateToSettings()
|
public async Task NavigateToSettings()
|
||||||
{
|
{
|
||||||
var sceneRouter = this.GetSystem<ISceneRouter>();
|
var sceneRouter = this.GetSystem<ISceneRouter>();
|
||||||
@ -432,10 +436,12 @@ public class GameplayScene : IScene
|
|||||||
### 场景预加载
|
### 场景预加载
|
||||||
|
|
||||||
```csharp
|
```csharp
|
||||||
public class PreloadController : IController
|
using GFramework.Core.Abstractions.controller;
|
||||||
{
|
using GFramework.SourceGenerators.Abstractions.rule;
|
||||||
public IArchitecture GetArchitecture() => GameArchitecture.Interface;
|
|
||||||
|
|
||||||
|
[ContextAware]
|
||||||
|
public partial class PreloadController : IController
|
||||||
|
{
|
||||||
public async Task PreloadNextLevel()
|
public async Task PreloadNextLevel()
|
||||||
{
|
{
|
||||||
var sceneFactory = this.GetUtility<ISceneFactory>();
|
var sceneFactory = this.GetUtility<ISceneFactory>();
|
||||||
|
|||||||
@ -94,6 +94,8 @@ public class GameArchitecture : Architecture
|
|||||||
使用泛型 API 序列化对象:
|
使用泛型 API 序列化对象:
|
||||||
|
|
||||||
```csharp
|
```csharp
|
||||||
|
using GFramework.SourceGenerators.Abstractions.rule;
|
||||||
|
|
||||||
public class PlayerData
|
public class PlayerData
|
||||||
{
|
{
|
||||||
public string Name { get; set; }
|
public string Name { get; set; }
|
||||||
@ -101,10 +103,9 @@ public class PlayerData
|
|||||||
public int Experience { get; set; }
|
public int Experience { get; set; }
|
||||||
}
|
}
|
||||||
|
|
||||||
public class SaveController : IController
|
[ContextAware]
|
||||||
|
public partial class SaveController : IController
|
||||||
{
|
{
|
||||||
public IArchitecture GetArchitecture() => GameArchitecture.Interface;
|
|
||||||
|
|
||||||
public void SavePlayer()
|
public void SavePlayer()
|
||||||
{
|
{
|
||||||
var serializer = this.GetUtility<ISerializer>();
|
var serializer = this.GetUtility<ISerializer>();
|
||||||
@ -174,11 +175,11 @@ public void SerializeRuntimeType()
|
|||||||
```csharp
|
```csharp
|
||||||
using GFramework.Core.Abstractions.storage;
|
using GFramework.Core.Abstractions.storage;
|
||||||
using GFramework.Game.storage;
|
using GFramework.Game.storage;
|
||||||
|
using GFramework.SourceGenerators.Abstractions.rule;
|
||||||
|
|
||||||
public class DataManager : IController
|
[ContextAware]
|
||||||
|
public partial class DataManager : IController
|
||||||
{
|
{
|
||||||
public IArchitecture GetArchitecture() => GameArchitecture.Interface;
|
|
||||||
|
|
||||||
public async Task SaveData()
|
public async Task SaveData()
|
||||||
{
|
{
|
||||||
var serializer = this.GetUtility<ISerializer>();
|
var serializer = this.GetUtility<ISerializer>();
|
||||||
|
|||||||
@ -126,10 +126,12 @@ public class MainMenuPage : IUiPage
|
|||||||
使用 UI 路由进行导航:
|
使用 UI 路由进行导航:
|
||||||
|
|
||||||
```csharp
|
```csharp
|
||||||
public class UiController : IController
|
using GFramework.Core.Abstractions.controller;
|
||||||
{
|
using GFramework.SourceGenerators.Abstractions.rule;
|
||||||
public IArchitecture GetArchitecture() => GameArchitecture.Interface;
|
|
||||||
|
|
||||||
|
[ContextAware]
|
||||||
|
public partial class UiController : IController
|
||||||
|
{
|
||||||
public async Task ShowSettings()
|
public async Task ShowSettings()
|
||||||
{
|
{
|
||||||
var uiRouter = this.GetSystem<IUiRouter>();
|
var uiRouter = this.GetSystem<IUiRouter>();
|
||||||
@ -159,10 +161,9 @@ public class UiController : IController
|
|||||||
### 显示不同层级的 UI
|
### 显示不同层级的 UI
|
||||||
|
|
||||||
```csharp
|
```csharp
|
||||||
public class UiController : IController
|
[ContextAware]
|
||||||
|
public partial class UiController : IController
|
||||||
{
|
{
|
||||||
public IArchitecture GetArchitecture() => GameArchitecture.Interface;
|
|
||||||
|
|
||||||
public void ShowDialog()
|
public void ShowDialog()
|
||||||
{
|
{
|
||||||
var uiRouter = this.GetSystem<IUiRouter>();
|
var uiRouter = this.GetSystem<IUiRouter>();
|
||||||
@ -303,7 +304,11 @@ uiRouter.RegisterHandler(new FadeTransitionHandler());
|
|||||||
### UI 句柄管理
|
### UI 句柄管理
|
||||||
|
|
||||||
```csharp
|
```csharp
|
||||||
public class DialogController : IController
|
using GFramework.Core.Abstractions.controller;
|
||||||
|
using GFramework.SourceGenerators.Abstractions.rule;
|
||||||
|
|
||||||
|
[ContextAware]
|
||||||
|
public partial class DialogController : IController
|
||||||
{
|
{
|
||||||
private UiHandle? _dialogHandle;
|
private UiHandle? _dialogHandle;
|
||||||
|
|
||||||
@ -332,7 +337,11 @@ public class DialogController : IController
|
|||||||
### UI 栈管理
|
### UI 栈管理
|
||||||
|
|
||||||
```csharp
|
```csharp
|
||||||
public class NavigationController : IController
|
using GFramework.Core.Abstractions.controller;
|
||||||
|
using GFramework.SourceGenerators.Abstractions.rule;
|
||||||
|
|
||||||
|
[ContextAware]
|
||||||
|
public partial class NavigationController : IController
|
||||||
{
|
{
|
||||||
public void ShowUiStack()
|
public void ShowUiStack()
|
||||||
{
|
{
|
||||||
@ -364,7 +373,11 @@ public class NavigationController : IController
|
|||||||
### 多层级 UI 管理
|
### 多层级 UI 管理
|
||||||
|
|
||||||
```csharp
|
```csharp
|
||||||
public class LayerController : IController
|
using GFramework.Core.Abstractions.controller;
|
||||||
|
using GFramework.SourceGenerators.Abstractions.rule;
|
||||||
|
|
||||||
|
[ContextAware]
|
||||||
|
public partial class LayerController : IController
|
||||||
{
|
{
|
||||||
public void ShowMultipleToasts()
|
public void ShowMultipleToasts()
|
||||||
{
|
{
|
||||||
|
|||||||
@ -151,17 +151,19 @@ public class EnemyDamagedEvent : IEvent
|
|||||||
实现控制器来连接 UI 和业务逻辑:
|
实现控制器来连接 UI 和业务逻辑:
|
||||||
|
|
||||||
```csharp
|
```csharp
|
||||||
public class GameController : IController
|
using GFramework.Core.Abstractions.controller;
|
||||||
|
using GFramework.SourceGenerators.Abstractions.rule;
|
||||||
|
|
||||||
|
[ContextAware]
|
||||||
|
public partial class GameController : IController
|
||||||
{
|
{
|
||||||
private IArchitecture _architecture;
|
|
||||||
private PlayerModel _playerModel;
|
private PlayerModel _playerModel;
|
||||||
private GameStateModel _gameStateModel;
|
private GameStateModel _gameStateModel;
|
||||||
|
|
||||||
public GameController(IArchitecture architecture)
|
public void Initialize()
|
||||||
{
|
{
|
||||||
_architecture = architecture;
|
_playerModel = this.GetModel<PlayerModel>();
|
||||||
_playerModel = architecture.GetModel<PlayerModel>();
|
_gameStateModel = this.GetModel<GameStateModel>();
|
||||||
_gameStateModel = architecture.GetModel<GameStateModel>();
|
|
||||||
|
|
||||||
// 初始化事件监听
|
// 初始化事件监听
|
||||||
InitializeEventListeners();
|
InitializeEventListeners();
|
||||||
@ -178,18 +180,18 @@ public class GameController : IController
|
|||||||
public void StartGame()
|
public void StartGame()
|
||||||
{
|
{
|
||||||
_gameStateModel.IsGameRunning.Value = true;
|
_gameStateModel.IsGameRunning.Value = true;
|
||||||
_architecture.SendEvent(new GameStartEvent());
|
this.SendEvent(new GameStartEvent());
|
||||||
Console.WriteLine("Game started!");
|
Console.WriteLine("Game started!");
|
||||||
}
|
}
|
||||||
|
|
||||||
public void MovePlayer(Vector2 direction)
|
public void MovePlayer(Vector2 direction)
|
||||||
{
|
{
|
||||||
_architecture.SendCommand(new MovePlayerCommand { Direction = direction });
|
this.SendCommand(new MovePlayerCommand { Direction = direction });
|
||||||
}
|
}
|
||||||
|
|
||||||
public void PlayerAttack(Vector2 target)
|
public void PlayerAttack(Vector2 target)
|
||||||
{
|
{
|
||||||
_architecture.SendCommand(new AttackCommand { TargetPosition = target });
|
this.SendCommand(new AttackCommand { TargetPosition = target });
|
||||||
}
|
}
|
||||||
|
|
||||||
// UI 更新回调
|
// UI 更新回调
|
||||||
@ -270,7 +272,8 @@ class Program
|
|||||||
architecture.Initialize();
|
architecture.Initialize();
|
||||||
|
|
||||||
// 创建控制器
|
// 创建控制器
|
||||||
var gameController = new GameController(architecture);
|
var gameController = new GameController();
|
||||||
|
gameController.Initialize();
|
||||||
|
|
||||||
// 开始游戏
|
// 开始游戏
|
||||||
gameController.StartGame();
|
gameController.StartGame();
|
||||||
|
|||||||
@ -340,13 +340,15 @@ public class GameArchitecture : AbstractArchitecture
|
|||||||
|
|
||||||
```csharp
|
```csharp
|
||||||
using Godot;
|
using Godot;
|
||||||
using GFramework.Godot.extensions;
|
using GFramework.Core.Abstractions.controller;
|
||||||
|
using GFramework.SourceGenerators.Abstractions.rule;
|
||||||
|
|
||||||
public partial class Player : CharacterBody2D
|
[ContextAware]
|
||||||
|
public partial class Player : CharacterBody2D, IController
|
||||||
{
|
{
|
||||||
public override void _Ready()
|
public override void _Ready()
|
||||||
{
|
{
|
||||||
// 通过扩展方法访问架构组件
|
// 使用扩展方法访问架构([ContextAware] 实现 IContextAware 接口)
|
||||||
var playerModel = this.GetModel<PlayerModel>();
|
var playerModel = this.GetModel<PlayerModel>();
|
||||||
var gameplaySystem = this.GetSystem<GameplaySystem>();
|
var gameplaySystem = this.GetSystem<GameplaySystem>();
|
||||||
|
|
||||||
@ -407,14 +409,24 @@ public class UiArchitecture : AbstractArchitecture
|
|||||||
}
|
}
|
||||||
|
|
||||||
// 在不同节点中使用不同架构
|
// 在不同节点中使用不同架构
|
||||||
|
[ContextAware]
|
||||||
public partial class GameNode : Node, IController
|
public partial class GameNode : Node, IController
|
||||||
{
|
{
|
||||||
public IArchitecture GetArchitecture() => GameArchitecture.Interface;
|
// 配置使用 GameArchitecture 的上下文提供者
|
||||||
|
static GameNode()
|
||||||
|
{
|
||||||
|
SetContextProvider(new GameContextProvider());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[ContextAware]
|
||||||
public partial class UiNode : Control, IController
|
public partial class UiNode : Control, IController
|
||||||
{
|
{
|
||||||
public IArchitecture GetArchitecture() => UiArchitecture.Interface;
|
// 配置使用 UiArchitecture 的上下文提供者
|
||||||
|
static UiNode()
|
||||||
|
{
|
||||||
|
SetContextProvider(new UiContextProvider());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
@ -504,17 +516,20 @@ public partial class GameRoot : Node
|
|||||||
### 问题:如何在节点中访问架构?
|
### 问题:如何在节点中访问架构?
|
||||||
|
|
||||||
**解答**:
|
**解答**:
|
||||||
实现 `IController` 接口或使用扩展方法:
|
使用 `[ContextAware]` 特性或直接使用单例:
|
||||||
|
|
||||||
```csharp
|
```csharp
|
||||||
// 方式 1: 实现 IController
|
using GFramework.SourceGenerators.Abstractions.rule;
|
||||||
|
|
||||||
|
// 方式 1: 使用 [ContextAware] 特性(推荐)
|
||||||
|
[ContextAware]
|
||||||
public partial class Player : Node, IController
|
public partial class Player : Node, IController
|
||||||
{
|
{
|
||||||
public IArchitecture GetArchitecture() => GameArchitecture.Interface;
|
|
||||||
|
|
||||||
public override void _Ready()
|
public override void _Ready()
|
||||||
{
|
{
|
||||||
|
// 使用扩展方法访问架构([ContextAware] 实现 IContextAware 接口)
|
||||||
var model = this.GetModel<PlayerModel>();
|
var model = this.GetModel<PlayerModel>();
|
||||||
|
var system = this.GetSystem<GameplaySystem>();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -528,6 +543,13 @@ public partial class Enemy : Node
|
|||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
|
**注意**:
|
||||||
|
|
||||||
|
- `IController` 是标记接口,不包含任何方法
|
||||||
|
- 架构访问能力由 `[ContextAware]` 特性提供
|
||||||
|
- `[ContextAware]` 会自动生成 `Context` 属性和实现 `IContextAware` 接口
|
||||||
|
- 扩展方法(如 `this.GetModel()`)基于 `IContextAware` 接口,而非 `IController`
|
||||||
|
|
||||||
### 问题:架构锚点节点是什么?
|
### 问题:架构锚点节点是什么?
|
||||||
|
|
||||||
**解答**:
|
**解答**:
|
||||||
|
|||||||
@ -75,7 +75,7 @@ private System.Collections.IEnumerator WaitUntilCondition()
|
|||||||
GD.Print("等待生命值恢复");
|
GD.Print("等待生命值恢复");
|
||||||
|
|
||||||
// 等待生命值大于 50
|
// 等待生命值大于 50
|
||||||
var playerModel = Context.GetModel<PlayerModel>();
|
var playerModel = this.GetModel<PlayerModel>();
|
||||||
yield return new WaitUntil(() => playerModel.Health.Value > 50);
|
yield return new WaitUntil(() => playerModel.Health.Value > 50);
|
||||||
|
|
||||||
GD.Print("生命值已恢复!");
|
GD.Print("生命值已恢复!");
|
||||||
@ -140,7 +140,7 @@ private System.Collections.IEnumerator EndOfFrameExample()
|
|||||||
```csharp
|
```csharp
|
||||||
private System.Collections.IEnumerator WaitUntilExample()
|
private System.Collections.IEnumerator WaitUntilExample()
|
||||||
{
|
{
|
||||||
var health = Context.GetModel<PlayerModel>().Health;
|
var health = this.GetModel<PlayerModel>().Health;
|
||||||
|
|
||||||
// 持续等待直到条件满足
|
// 持续等待直到条件满足
|
||||||
yield return new WaitUntil(() => health.Value > 0);
|
yield return new WaitUntil(() => health.Value > 0);
|
||||||
@ -156,7 +156,7 @@ private System.Collections.IEnumerator WaitUntilExample()
|
|||||||
```csharp
|
```csharp
|
||||||
private System.Collections.IEnumerator WaitWhileExample()
|
private System.Collections.IEnumerator WaitWhileExample()
|
||||||
{
|
{
|
||||||
var gameState = Context.GetModel<GameModel>();
|
var gameState = this.GetModel<GameModel>();
|
||||||
|
|
||||||
// 等待游戏不再暂停
|
// 等待游戏不再暂停
|
||||||
yield return new WaitWhile(() => gameState.IsPaused.Value);
|
yield return new WaitWhile(() => gameState.IsPaused.Value);
|
||||||
@ -174,7 +174,7 @@ private System.Collections.IEnumerator WaitWhileExample()
|
|||||||
```csharp
|
```csharp
|
||||||
private System.Collections.IEnumerator CombinedWait()
|
private System.Collections.IEnumerator CombinedWait()
|
||||||
{
|
{
|
||||||
var health = Context.GetModel<PlayerModel>().Health;
|
var health = this.GetModel<PlayerModel>().Health;
|
||||||
var button = GetNode<Button>("Button");
|
var button = GetNode<Button>("Button");
|
||||||
|
|
||||||
// 等待生命值恢复或按钮点击(任一条件满足即可)
|
// 等待生命值恢复或按钮点击(任一条件满足即可)
|
||||||
|
|||||||
@ -162,7 +162,7 @@ public partial class PlayerController : Node, IController
|
|||||||
public override void _Ready()
|
public override void _Ready()
|
||||||
{
|
{
|
||||||
// 获取模型引用
|
// 获取模型引用
|
||||||
_playerModel = Context.GetModel<PlayerModel>();
|
_playerModel = this.GetModel<PlayerModel>();
|
||||||
|
|
||||||
// 注册事件监听,自动与节点生命周期绑定
|
// 注册事件监听,自动与节点生命周期绑定
|
||||||
this.RegisterEvent<PlayerInputEvent>(OnPlayerInput)
|
this.RegisterEvent<PlayerInputEvent>(OnPlayerInput)
|
||||||
@ -185,7 +185,7 @@ public partial class PlayerController : Node, IController
|
|||||||
MovePlayer(1, 0);
|
MovePlayer(1, 0);
|
||||||
break;
|
break;
|
||||||
case "attack":
|
case "attack":
|
||||||
Context.SendCommand(new AttackCommand());
|
this.SendCommand(new AttackCommand());
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -312,7 +312,7 @@ public partial class UIController : Node, IController
|
|||||||
// Godot 信号 -> 框架事件
|
// Godot 信号 -> 框架事件
|
||||||
this.CreateSignalBuilder(Button.SignalName.Pressed)
|
this.CreateSignalBuilder(Button.SignalName.Pressed)
|
||||||
.Connect(() => {
|
.Connect(() => {
|
||||||
Context.SendEvent(new UIButtonClickEvent { ButtonId = "start_game" });
|
this.SendEvent(new UIButtonClickEvent { ButtonId = "start_game" });
|
||||||
})
|
})
|
||||||
.UnRegisterWhenNodeExitTree(this);
|
.UnRegisterWhenNodeExitTree(this);
|
||||||
|
|
||||||
@ -392,7 +392,7 @@ public partial class WeaponController : Node, IController
|
|||||||
|
|
||||||
protected override void OnInit()
|
protected override void OnInit()
|
||||||
{
|
{
|
||||||
_bulletPool = Context.GetSystem<BulletPoolSystem>();
|
_bulletPool = this.GetSystem<BulletPoolSystem>();
|
||||||
}
|
}
|
||||||
|
|
||||||
public void Shoot(Vector3 direction)
|
public void Shoot(Vector3 direction)
|
||||||
@ -528,7 +528,7 @@ public partial class GameController : Node, IController
|
|||||||
Logger.Debug("Starting game");
|
Logger.Debug("Starting game");
|
||||||
|
|
||||||
// 发送游戏开始事件
|
// 发送游戏开始事件
|
||||||
Context.SendEvent(new GameStartEvent());
|
this.SendEvent(new GameStartEvent());
|
||||||
|
|
||||||
Logger.Info("Game started");
|
Logger.Info("Game started");
|
||||||
}
|
}
|
||||||
@ -536,7 +536,7 @@ public partial class GameController : Node, IController
|
|||||||
public void PauseGame()
|
public void PauseGame()
|
||||||
{
|
{
|
||||||
Logger.Info("Game paused");
|
Logger.Info("Game paused");
|
||||||
Context.SendEvent(new GamePauseEvent());
|
this.SendEvent(new GamePauseEvent());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
@ -610,7 +610,7 @@ public partial class PlayerController : CharacterBody2D, IController
|
|||||||
|
|
||||||
public override void _Ready()
|
public override void _Ready()
|
||||||
{
|
{
|
||||||
_playerModel = Context.GetModel<PlayerModel>();
|
_playerModel = this.GetModel<PlayerModel>();
|
||||||
|
|
||||||
// 输入处理
|
// 输入处理
|
||||||
SetProcessInput(true);
|
SetProcessInput(true);
|
||||||
@ -639,7 +639,7 @@ public partial class PlayerController : CharacterBody2D, IController
|
|||||||
{
|
{
|
||||||
if (CanShoot())
|
if (CanShoot())
|
||||||
{
|
{
|
||||||
var bulletPool = Context.GetSystem<BulletPoolSystem>();
|
var bulletPool = this.GetSystem<BulletPoolSystem>();
|
||||||
var bullet = bulletPool.Spawn("player");
|
var bullet = bulletPool.Spawn("player");
|
||||||
|
|
||||||
if (bullet != null)
|
if (bullet != null)
|
||||||
@ -648,7 +648,7 @@ public partial class PlayerController : CharacterBody2D, IController
|
|||||||
bullet.Initialize(GlobalPosition, direction.Normalized());
|
bullet.Initialize(GlobalPosition, direction.Normalized());
|
||||||
GetTree().Root.AddChild(bullet);
|
GetTree().Root.AddChild(bullet);
|
||||||
|
|
||||||
Context.SendEvent(new BulletFiredEvent());
|
this.SendEvent(new BulletFiredEvent());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -666,7 +666,7 @@ public partial class PlayerController : CharacterBody2D, IController
|
|||||||
private void Die()
|
private void Die()
|
||||||
{
|
{
|
||||||
Logger.Info("Player died");
|
Logger.Info("Player died");
|
||||||
Context.SendEvent(new PlayerDeathEvent());
|
this.SendEvent(new PlayerDeathEvent());
|
||||||
QueueFreeX();
|
QueueFreeX();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -29,17 +29,17 @@ public partial class PlayerController : IController
|
|||||||
{
|
{
|
||||||
public void Initialize()
|
public void Initialize()
|
||||||
{
|
{
|
||||||
// Context 属性自动生成,提供架构上下文访问
|
// 使用扩展方法访问架构([ContextAware] 实现 IContextAware 接口)
|
||||||
var playerModel = Context.GetModel<PlayerModel>();
|
var playerModel = this.GetModel<PlayerModel>();
|
||||||
var combatSystem = Context.GetSystem<CombatSystem>();
|
var combatSystem = this.GetSystem<CombatSystem>();
|
||||||
|
|
||||||
Context.SendEvent(new PlayerInitializedEvent());
|
this.SendEvent(new PlayerInitializedEvent());
|
||||||
}
|
}
|
||||||
|
|
||||||
public void Attack(Enemy target)
|
public void Attack(Enemy target)
|
||||||
{
|
{
|
||||||
var damage = Context.GetUtility<DamageCalculator>().Calculate(this, target);
|
var damage = this.GetUtility<DamageCalculator>().Calculate(this, target);
|
||||||
Context.SendCommand(new DealDamageCommand(target, damage));
|
this.SendCommand(new DealDamageCommand(target, damage));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
@ -218,8 +218,8 @@ public partial class GameFlowController : IController
|
|||||||
{
|
{
|
||||||
public async Task StartGame()
|
public async Task StartGame()
|
||||||
{
|
{
|
||||||
var saveSystem = Context.GetSystem<SaveSystem>();
|
var saveSystem = this.GetSystem<SaveSystem>();
|
||||||
var uiSystem = Context.GetSystem<UISystem>();
|
var uiSystem = this.GetSystem<UISystem>();
|
||||||
|
|
||||||
await saveSystem.LoadAsync();
|
await saveSystem.LoadAsync();
|
||||||
await uiSystem.ShowMainMenuAsync();
|
await uiSystem.ShowMainMenuAsync();
|
||||||
@ -227,6 +227,32 @@ public partial class GameFlowController : IController
|
|||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
|
### 与 IController 配合使用
|
||||||
|
|
||||||
|
在 Godot 项目中,控制器通常同时实现 `IController` 和使用 `[ContextAware]`:
|
||||||
|
|
||||||
|
```csharp
|
||||||
|
using GFramework.Core.Abstractions.controller;
|
||||||
|
using GFramework.SourceGenerators.Abstractions.rule;
|
||||||
|
|
||||||
|
[ContextAware]
|
||||||
|
public partial class PlayerController : Node, IController
|
||||||
|
{
|
||||||
|
public override void _Ready()
|
||||||
|
{
|
||||||
|
// 使用扩展方法访问架构([ContextAware] 实现 IContextAware 接口)
|
||||||
|
var playerModel = this.GetModel<PlayerModel>();
|
||||||
|
var combatSystem = this.GetSystem<CombatSystem>();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
**说明**:
|
||||||
|
|
||||||
|
- `IController` 是标记接口,标识这是一个控制器
|
||||||
|
- `[ContextAware]` 提供架构访问能力
|
||||||
|
- 两者配合使用是推荐的模式
|
||||||
|
|
||||||
### 何时继承 ContextAwareBase
|
### 何时继承 ContextAwareBase
|
||||||
|
|
||||||
如果类需要更多框架功能(如生命周期管理),应继承 `ContextAwareBase`:
|
如果类需要更多框架功能(如生命周期管理),应继承 `ContextAwareBase`:
|
||||||
@ -238,7 +264,7 @@ public class PlayerModel : AbstractModel
|
|||||||
// AbstractModel 已经继承了 ContextAwareBase
|
// AbstractModel 已经继承了 ContextAwareBase
|
||||||
protected override void OnInit()
|
protected override void OnInit()
|
||||||
{
|
{
|
||||||
var config = Context.GetUtility<ConfigLoader>().Load<PlayerConfig>();
|
var config = this.GetUtility<ConfigLoader>().Load<PlayerConfig>();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -248,7 +274,7 @@ public partial class SimpleHelper
|
|||||||
{
|
{
|
||||||
public void DoSomething()
|
public void DoSomething()
|
||||||
{
|
{
|
||||||
Context.SendEvent(new SomethingHappenedEvent());
|
this.SendEvent(new SomethingHappenedEvent());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
@ -308,13 +334,13 @@ public partial class MyController
|
|||||||
// ❌ 错误:构造函数执行时上下文可能未初始化
|
// ❌ 错误:构造函数执行时上下文可能未初始化
|
||||||
public MyController()
|
public MyController()
|
||||||
{
|
{
|
||||||
var model = Context.GetModel<SomeModel>(); // 可能为 null
|
var model = this.GetModel<SomeModel>(); // 可能为 null
|
||||||
}
|
}
|
||||||
|
|
||||||
// ✅ 正确:在初始化方法中访问
|
// ✅ 正确:在初始化方法中访问
|
||||||
public void Initialize()
|
public void Initialize()
|
||||||
{
|
{
|
||||||
var model = Context.GetModel<SomeModel>(); // 安全
|
var model = this.GetModel<SomeModel>(); // 安全
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
@ -327,8 +353,8 @@ public partial class MyController
|
|||||||
{
|
{
|
||||||
public void DoSomething()
|
public void DoSomething()
|
||||||
{
|
{
|
||||||
// ✅ 推荐:使用生成的 Context 属性
|
// ✅ 推荐:使用扩展方法
|
||||||
var model = Context.GetModel<SomeModel>();
|
var model = this.GetModel<SomeModel>();
|
||||||
|
|
||||||
// ❌ 不推荐:显式调用接口方法
|
// ❌ 不推荐:显式调用接口方法
|
||||||
var context = ((IContextAware)this).GetContext();
|
var context = ((IContextAware)this).GetContext();
|
||||||
|
|||||||
@ -164,19 +164,19 @@ public static partial class MathHelper
|
|||||||
### 基础使用
|
### 基础使用
|
||||||
|
|
||||||
```csharp
|
```csharp
|
||||||
using GFramework.SourceGenerators.Abstractions.rule;
|
|
||||||
using GFramework.Core.Abstractions.controller;
|
using GFramework.Core.Abstractions.controller;
|
||||||
|
using GFramework.SourceGenerators.Abstractions.rule;
|
||||||
|
|
||||||
[ContextAware]
|
[ContextAware]
|
||||||
public partial class PlayerController : IController
|
public partial class PlayerController : IController
|
||||||
{
|
{
|
||||||
public void Initialize()
|
public void Initialize()
|
||||||
{
|
{
|
||||||
// Context 属性自动生成,提供架构上下文访问
|
// 使用扩展方法访问架构([ContextAware] 实现 IContextAware 接口)
|
||||||
var playerModel = Context.GetModel<PlayerModel>();
|
var playerModel = this.GetModel<PlayerModel>();
|
||||||
var combatSystem = Context.GetSystem<CombatSystem>();
|
var combatSystem = this.GetSystem<CombatSystem>();
|
||||||
|
|
||||||
Context.SendEvent(new PlayerInitializedEvent());
|
this.SendEvent(new PlayerInitializedEvent());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
@ -272,6 +272,10 @@ public async Task TestPlayerController()
|
|||||||
### 与其他属性组合
|
### 与其他属性组合
|
||||||
|
|
||||||
```csharp
|
```csharp
|
||||||
|
using GFramework.Core.Abstractions.controller;
|
||||||
|
using GFramework.SourceGenerators.Abstractions.logging;
|
||||||
|
using GFramework.SourceGenerators.Abstractions.rule;
|
||||||
|
|
||||||
[Log]
|
[Log]
|
||||||
[ContextAware]
|
[ContextAware]
|
||||||
public partial class AdvancedController : IController
|
public partial class AdvancedController : IController
|
||||||
@ -280,10 +284,10 @@ public partial class AdvancedController : IController
|
|||||||
{
|
{
|
||||||
Logger.Info("Processing request");
|
Logger.Info("Processing request");
|
||||||
|
|
||||||
var model = Context.GetModel<PlayerModel>();
|
var model = this.GetModel<PlayerModel>();
|
||||||
Logger.Info($"Player health: {model.Health}");
|
Logger.Info($"Player health: {model.Health}");
|
||||||
|
|
||||||
Context.SendCommand(new ProcessCommand());
|
this.SendCommand(new ProcessCommand());
|
||||||
Logger.Debug("Command sent");
|
Logger.Debug("Command sent");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -486,7 +490,7 @@ public partial class EfficientController : IController
|
|||||||
public void Process()
|
public void Process()
|
||||||
{
|
{
|
||||||
Logger.Info("Processing"); // 0 分配
|
Logger.Info("Processing"); // 0 分配
|
||||||
var model = Context.GetModel<PlayerModel>(); // 0 分配
|
var model = this.GetModel<PlayerModel>(); // 0 分配
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -506,8 +510,9 @@ public class InefficientController : IController
|
|||||||
### 完整的游戏控制器示例
|
### 完整的游戏控制器示例
|
||||||
|
|
||||||
```csharp
|
```csharp
|
||||||
using GFramework.SourceGenerators.Attributes;
|
using GFramework.Core.Abstractions.controller;
|
||||||
using GFramework.Core.Abstractions;
|
using GFramework.SourceGenerators.Abstractions.logging;
|
||||||
|
using GFramework.SourceGenerators.Abstractions.rule;
|
||||||
|
|
||||||
[Log]
|
[Log]
|
||||||
[ContextAware]
|
[ContextAware]
|
||||||
@ -519,8 +524,8 @@ public partial class GameController : Node, IController
|
|||||||
public override void _Ready()
|
public override void _Ready()
|
||||||
{
|
{
|
||||||
// 初始化模型和系统引用
|
// 初始化模型和系统引用
|
||||||
_playerModel = Context.GetModel<PlayerModel>();
|
_playerModel = this.GetModel<PlayerModel>();
|
||||||
_combatSystem = Context.GetSystem<CombatSystem>();
|
_combatSystem = this.GetSystem<CombatSystem>();
|
||||||
|
|
||||||
// 监听事件
|
// 监听事件
|
||||||
this.RegisterEvent<PlayerInputEvent>(OnPlayerInput)
|
this.RegisterEvent<PlayerInputEvent>(OnPlayerInput)
|
||||||
@ -550,7 +555,7 @@ public partial class GameController : Node, IController
|
|||||||
{
|
{
|
||||||
Logger.Info("Player attacks");
|
Logger.Info("Player attacks");
|
||||||
_combatSystem.ProcessAttack();
|
_combatSystem.ProcessAttack();
|
||||||
Context.SendEvent(new AttackEvent());
|
this.SendEvent(new AttackEvent());
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@ -564,7 +569,7 @@ public partial class GameController : Node, IController
|
|||||||
{
|
{
|
||||||
Logger.Info("Player defends");
|
Logger.Info("Player defends");
|
||||||
_playerModel.IsDefending.Value = true;
|
_playerModel.IsDefending.Value = true;
|
||||||
Context.SendEvent(new DefendEvent());
|
this.SendEvent(new DefendEvent());
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@ -595,6 +600,10 @@ public enum CharacterState
|
|||||||
Dead
|
Dead
|
||||||
}
|
}
|
||||||
|
|
||||||
|
using GFramework.Core.Abstractions.controller;
|
||||||
|
using GFramework.SourceGenerators.Abstractions.logging;
|
||||||
|
using GFramework.SourceGenerators.Abstractions.rule;
|
||||||
|
|
||||||
[Log]
|
[Log]
|
||||||
[ContextAware]
|
[ContextAware]
|
||||||
public partial class CharacterController : Node, IController
|
public partial class CharacterController : Node, IController
|
||||||
@ -603,7 +612,7 @@ public partial class CharacterController : Node, IController
|
|||||||
|
|
||||||
public override void _Ready()
|
public override void _Ready()
|
||||||
{
|
{
|
||||||
_characterModel = Context.GetModel<CharacterModel>();
|
_characterModel = this.GetModel<CharacterModel>();
|
||||||
|
|
||||||
// 监听状态变化
|
// 监听状态变化
|
||||||
_characterModel.State.Register(OnStateChanged);
|
_characterModel.State.Register(OnStateChanged);
|
||||||
@ -649,7 +658,7 @@ public partial class CharacterController : Node, IController
|
|||||||
Logger.Info("Character died");
|
Logger.Info("Character died");
|
||||||
DisableInput();
|
DisableInput();
|
||||||
PlayDeathAnimation();
|
PlayDeathAnimation();
|
||||||
Context.SendEvent(new CharacterDeathEvent());
|
this.SendEvent(new CharacterDeathEvent());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
@ -783,14 +792,14 @@ public partial class RobustComponent : IComponent
|
|||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
var model = Context.GetModel<RiskyModel>();
|
var model = this.GetModel<RiskyModel>();
|
||||||
model.PerformRiskyOperation();
|
model.PerformRiskyOperation();
|
||||||
Logger.Info("Operation completed successfully");
|
Logger.Info("Operation completed successfully");
|
||||||
}
|
}
|
||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
{
|
{
|
||||||
Logger.Error($"Operation failed: {ex.Message}");
|
Logger.Error($"Operation failed: {ex.Message}");
|
||||||
Context.SendEvent(new OperationFailedEvent { Error = ex.Message });
|
this.SendEvent(new OperationFailedEvent { Error = ex.Message });
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -164,6 +164,10 @@ public partial class MySystem : AbstractSystem
|
|||||||
### 游戏控制器
|
### 游戏控制器
|
||||||
|
|
||||||
```csharp
|
```csharp
|
||||||
|
using GFramework.Core.Abstractions.controller;
|
||||||
|
using GFramework.SourceGenerators.Abstractions.logging;
|
||||||
|
using GFramework.SourceGenerators.Abstractions.rule;
|
||||||
|
|
||||||
[Log]
|
[Log]
|
||||||
[ContextAware]
|
[ContextAware]
|
||||||
public partial class PlayerController : IController
|
public partial class PlayerController : IController
|
||||||
|
|||||||
@ -168,7 +168,7 @@ public partial class PlayerService : IController
|
|||||||
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
Context.SendCommand(command);
|
this.SendCommand(command);
|
||||||
Logger.Info($"Player {name} created successfully");
|
Logger.Info($"Player {name} created successfully");
|
||||||
}
|
}
|
||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
@ -181,7 +181,7 @@ public partial class PlayerService : IController
|
|||||||
public PlayerData GetPlayer(string name)
|
public PlayerData GetPlayer(string name)
|
||||||
{
|
{
|
||||||
var query = new GetPlayerQuery { PlayerName = name };
|
var query = new GetPlayerQuery { PlayerName = name };
|
||||||
return Context.SendQuery(query);
|
return this.SendQuery(query);
|
||||||
}
|
}
|
||||||
|
|
||||||
public List<PlayerData> GetAllPlayers(PlayerClass? classFilter = null, int? minLevel = null)
|
public List<PlayerData> GetAllPlayers(PlayerClass? classFilter = null, int? minLevel = null)
|
||||||
@ -191,13 +191,13 @@ public partial class PlayerService : IController
|
|||||||
FilterByClass = classFilter,
|
FilterByClass = classFilter,
|
||||||
MinLevel = minLevel
|
MinLevel = minLevel
|
||||||
};
|
};
|
||||||
return Context.SendQuery(query);
|
return this.SendQuery(query);
|
||||||
}
|
}
|
||||||
|
|
||||||
public PlayerStatistics GetPlayerStatistics(string playerName)
|
public PlayerStatistics GetPlayerStatistics(string playerName)
|
||||||
{
|
{
|
||||||
var query = new GetPlayerStatisticsQuery { PlayerName = playerName };
|
var query = new GetPlayerStatisticsQuery { PlayerName = playerName };
|
||||||
return Context.SendQuery(query);
|
return this.SendQuery(query);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
@ -1046,13 +1046,13 @@ public class PluginManager : IPluginContext
|
|||||||
}
|
}
|
||||||
|
|
||||||
// 尝试从架构中获取
|
// 尝试从架构中获取
|
||||||
return _architecture.Context.GetUtility<T>();
|
return _architecture.this.GetUtility<T>();
|
||||||
}
|
}
|
||||||
|
|
||||||
public void RegisterEventHandler<T>(IEventHandler<T> handler) where T : IEvent
|
public void RegisterEventHandler<T>(IEventHandler<T> handler) where T : IEvent
|
||||||
{
|
{
|
||||||
_eventHandlers.Add(handler);
|
_eventHandlers.Add(handler);
|
||||||
_architecture.Context.RegisterEvent<T>(handler.Handle);
|
_architecture.this.RegisterEvent<T>(handler.Handle);
|
||||||
_logger.Debug($"Event handler for {typeof(T).Name} registered by plugin system");
|
_logger.Debug($"Event handler for {typeof(T).Name} registered by plugin system");
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1167,7 +1167,7 @@ public class ChatService : IChatService
|
|||||||
chatChannel.AddMessage(chatMessage);
|
chatChannel.AddMessage(chatMessage);
|
||||||
|
|
||||||
// 发送事件
|
// 发送事件
|
||||||
_architecture.Context.SendEvent(new ChatMessageReceivedEvent(chatMessage));
|
_architecture.this.SendEvent(new ChatMessageReceivedEvent(chatMessage));
|
||||||
}
|
}
|
||||||
|
|
||||||
public void SendSystemMessage(string message)
|
public void SendSystemMessage(string message)
|
||||||
@ -1181,7 +1181,7 @@ public class ChatService : IChatService
|
|||||||
};
|
};
|
||||||
|
|
||||||
_channels["global"].AddMessage(systemMessage);
|
_channels["global"].AddMessage(systemMessage);
|
||||||
_architecture.Context.SendEvent(new ChatMessageReceivedEvent(systemMessage));
|
_architecture.this.SendEvent(new ChatMessageReceivedEvent(systemMessage));
|
||||||
}
|
}
|
||||||
|
|
||||||
private string FilterMessage(string message)
|
private string FilterMessage(string message)
|
||||||
@ -1444,7 +1444,7 @@ public class NetworkManager : Node, INetworkManager
|
|||||||
private void HandlePlayerPosition(PlayerPositionMessage message)
|
private void HandlePlayerPosition(PlayerPositionMessage message)
|
||||||
{
|
{
|
||||||
// 更新其他玩家位置
|
// 更新其他玩家位置
|
||||||
Context.SendEvent(new NetworkPlayerPositionEvent
|
this.SendEvent(new NetworkPlayerPositionEvent
|
||||||
{
|
{
|
||||||
PlayerId = message.PlayerId,
|
PlayerId = message.PlayerId,
|
||||||
Position = new Vector2(message.X, message.Y)
|
Position = new Vector2(message.X, message.Y)
|
||||||
@ -1454,7 +1454,7 @@ public class NetworkManager : Node, INetworkManager
|
|||||||
private void HandleChatMessage(ChatMessageMessage message)
|
private void HandleChatMessage(ChatMessageMessage message)
|
||||||
{
|
{
|
||||||
// 显示聊天消息
|
// 显示聊天消息
|
||||||
Context.SendEvent(new NetworkChatEvent
|
this.SendEvent(new NetworkChatEvent
|
||||||
{
|
{
|
||||||
PlayerName = message.PlayerName,
|
PlayerName = message.PlayerName,
|
||||||
Message = message.Content,
|
Message = message.Content,
|
||||||
@ -1465,7 +1465,7 @@ public class NetworkManager : Node, INetworkManager
|
|||||||
private void HandlePlayerAction(PlayerActionMessage message)
|
private void HandlePlayerAction(PlayerActionMessage message)
|
||||||
{
|
{
|
||||||
// 处理玩家动作
|
// 处理玩家动作
|
||||||
Context.SendEvent(new NetworkPlayerActionEvent
|
this.SendEvent(new NetworkPlayerActionEvent
|
||||||
{
|
{
|
||||||
PlayerId = message.PlayerId,
|
PlayerId = message.PlayerId,
|
||||||
Action = message.Action,
|
Action = message.Action,
|
||||||
@ -1476,7 +1476,7 @@ public class NetworkManager : Node, INetworkManager
|
|||||||
private void HandleGameState(GameStateMessage message)
|
private void HandleGameState(GameStateMessage message)
|
||||||
{
|
{
|
||||||
// 更新游戏状态
|
// 更新游戏状态
|
||||||
Context.SendEvent(new NetworkGameStateEvent
|
this.SendEvent(new NetworkGameStateEvent
|
||||||
{
|
{
|
||||||
State = message.State,
|
State = message.State,
|
||||||
Data = message.Data
|
Data = message.Data
|
||||||
@ -1574,7 +1574,7 @@ public partial class NetworkController : Node, IController
|
|||||||
{
|
{
|
||||||
var message = new PlayerPositionMessage
|
var message = new PlayerPositionMessage
|
||||||
{
|
{
|
||||||
PlayerId = Context.GetModel<PlayerModel>().PlayerId,
|
PlayerId = this.GetModel<PlayerModel>().PlayerId,
|
||||||
X = position.X,
|
X = position.X,
|
||||||
Y = position.Y,
|
Y = position.Y,
|
||||||
Rotation = 0f // 根据实际需要设置
|
Rotation = 0f // 根据实际需要设置
|
||||||
@ -1587,7 +1587,7 @@ public partial class NetworkController : Node, IController
|
|||||||
{
|
{
|
||||||
var chatMessage = new ChatMessageMessage
|
var chatMessage = new ChatMessageMessage
|
||||||
{
|
{
|
||||||
PlayerName = Context.GetModel<PlayerModel>().Name,
|
PlayerName = this.GetModel<PlayerModel>().Name,
|
||||||
Content = message,
|
Content = message,
|
||||||
Channel = channel
|
Channel = channel
|
||||||
};
|
};
|
||||||
@ -1598,13 +1598,13 @@ public partial class NetworkController : Node, IController
|
|||||||
private void OnNetworkConnected()
|
private void OnNetworkConnected()
|
||||||
{
|
{
|
||||||
Logger.Info("Connected to network server");
|
Logger.Info("Connected to network server");
|
||||||
Context.SendEvent(new NetworkConnectedEvent());
|
this.SendEvent(new NetworkConnectedEvent());
|
||||||
}
|
}
|
||||||
|
|
||||||
private void OnNetworkDisconnected(string reason)
|
private void OnNetworkDisconnected(string reason)
|
||||||
{
|
{
|
||||||
Logger.Info($"Disconnected from network server: {reason}");
|
Logger.Info($"Disconnected from network server: {reason}");
|
||||||
Context.SendEvent(new NetworkDisconnectedEvent { Reason = reason });
|
this.SendEvent(new NetworkDisconnectedEvent { Reason = reason });
|
||||||
}
|
}
|
||||||
|
|
||||||
private void OnNetworkMessageReceived(NetworkMessage message)
|
private void OnNetworkMessageReceived(NetworkMessage message)
|
||||||
@ -1615,7 +1615,7 @@ public partial class NetworkController : Node, IController
|
|||||||
private void OnConnectionFailed(string error)
|
private void OnConnectionFailed(string error)
|
||||||
{
|
{
|
||||||
Logger.Error($"Network connection failed: {error}");
|
Logger.Error($"Network connection failed: {error}");
|
||||||
Context.SendEvent(new NetworkConnectionFailedEvent { Error = error });
|
this.SendEvent(new NetworkConnectionFailedEvent { Error = error });
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|||||||
@ -473,14 +473,15 @@ namespace MyShooterGame.Systems
|
|||||||
```csharp
|
```csharp
|
||||||
// Scripts/Controllers/PlayerController.cs
|
// Scripts/Controllers/PlayerController.cs
|
||||||
using GFramework.Core.Abstractions.controller;
|
using GFramework.Core.Abstractions.controller;
|
||||||
using GFramework.Core.Abstractions.architecture;
|
|
||||||
using GFramework.Core.extensions;
|
using GFramework.Core.extensions;
|
||||||
|
using GFramework.SourceGenerators.Abstractions.rule;
|
||||||
using MyShooterGame.Architecture;
|
using MyShooterGame.Architecture;
|
||||||
using MyShooterGame.Models;
|
using MyShooterGame.Models;
|
||||||
using Godot;
|
using Godot;
|
||||||
|
|
||||||
namespace MyShooterGame.Controllers
|
namespace MyShooterGame.Controllers
|
||||||
{
|
{
|
||||||
|
[ContextAware]
|
||||||
public partial class PlayerController : CharacterBody2D, IController
|
public partial class PlayerController : CharacterBody2D, IController
|
||||||
{
|
{
|
||||||
[Export] public float Speed = 300f;
|
[Export] public float Speed = 300f;
|
||||||
@ -489,11 +490,9 @@ namespace MyShooterGame.Controllers
|
|||||||
private float _shootCooldown = 0f;
|
private float _shootCooldown = 0f;
|
||||||
private const float ShootInterval = 0.2f;
|
private const float ShootInterval = 0.2f;
|
||||||
|
|
||||||
public IArchitecture GetArchitecture() => GameArchitecture.Interface;
|
|
||||||
|
|
||||||
public override void _Ready()
|
public override void _Ready()
|
||||||
{
|
{
|
||||||
// 监听玩家死亡
|
// 监听玩家死亡(使用扩展方法访问架构([ContextAware] 实现 IContextAware 接口))
|
||||||
var playerModel = this.GetModel<PlayerModel>();
|
var playerModel = this.GetModel<PlayerModel>();
|
||||||
playerModel.IsAlive.RegisterOnValueChanged(isAlive =>
|
playerModel.IsAlive.RegisterOnValueChanged(isAlive =>
|
||||||
{
|
{
|
||||||
@ -630,15 +629,14 @@ public partial class Main : Node
|
|||||||
// Scripts/UI/MenuController.cs
|
// Scripts/UI/MenuController.cs
|
||||||
using Godot;
|
using Godot;
|
||||||
using GFramework.Core.Abstractions.controller;
|
using GFramework.Core.Abstractions.controller;
|
||||||
using GFramework.Core.Abstractions.architecture;
|
|
||||||
using GFramework.Core.extensions;
|
using GFramework.Core.extensions;
|
||||||
|
using GFramework.SourceGenerators.Abstractions.rule;
|
||||||
using MyShooterGame.Architecture;
|
using MyShooterGame.Architecture;
|
||||||
using MyShooterGame.Systems;
|
using MyShooterGame.Systems;
|
||||||
|
|
||||||
|
[ContextAware]
|
||||||
public partial class MenuController : Control, IController
|
public partial class MenuController : Control, IController
|
||||||
{
|
{
|
||||||
public IArchitecture GetArchitecture() => GameArchitecture.Interface;
|
|
||||||
|
|
||||||
public override void _Ready()
|
public override void _Ready()
|
||||||
{
|
{
|
||||||
// 连接按钮信号
|
// 连接按钮信号
|
||||||
@ -650,7 +648,7 @@ public partial class MenuController : Control, IController
|
|||||||
{
|
{
|
||||||
GD.Print("开始游戏");
|
GD.Print("开始游戏");
|
||||||
|
|
||||||
// 初始化游戏
|
// 初始化游戏(使用扩展方法访问架构([ContextAware] 实现 IContextAware 接口))
|
||||||
var gameplaySystem = this.GetSystem<GameplaySystem>();
|
var gameplaySystem = this.GetSystem<GameplaySystem>();
|
||||||
gameplaySystem.StartNewGame();
|
gameplaySystem.StartNewGame();
|
||||||
|
|
||||||
@ -675,21 +673,21 @@ using Godot;
|
|||||||
using GFramework.Core.Abstractions.controller;
|
using GFramework.Core.Abstractions.controller;
|
||||||
using GFramework.Core.Abstractions.architecture;
|
using GFramework.Core.Abstractions.architecture;
|
||||||
using GFramework.Core.extensions;
|
using GFramework.Core.extensions;
|
||||||
|
using GFramework.SourceGenerators.Abstractions.rule;
|
||||||
using MyShooterGame.Architecture;
|
using MyShooterGame.Architecture;
|
||||||
using MyShooterGame.Systems;
|
using MyShooterGame.Systems;
|
||||||
using MyShooterGame.Models;
|
using MyShooterGame.Models;
|
||||||
|
|
||||||
|
[ContextAware]
|
||||||
public partial class GameScene : Node2D, IController
|
public partial class GameScene : Node2D, IController
|
||||||
{
|
{
|
||||||
[Export] public PackedScene EnemyScene;
|
[Export] public PackedScene EnemyScene;
|
||||||
|
|
||||||
private SpawnSystem _spawnSystem;
|
private SpawnSystem _spawnSystem;
|
||||||
|
|
||||||
public IArchitecture GetArchitecture() => GameArchitecture.Interface;
|
|
||||||
|
|
||||||
public override void _Ready()
|
public override void _Ready()
|
||||||
{
|
{
|
||||||
// 初始化生成系统
|
// 初始化生成系统(使用扩展方法访问架构([ContextAware] 实现 IContextAware 接口))
|
||||||
_spawnSystem = this.GetSystem<SpawnSystem>();
|
_spawnSystem = this.GetSystem<SpawnSystem>();
|
||||||
_spawnSystem.Initialize(this, EnemyScene);
|
_spawnSystem.Initialize(this, EnemyScene);
|
||||||
_spawnSystem.StartSpawning();
|
_spawnSystem.StartSpawning();
|
||||||
|
|||||||
@ -186,7 +186,7 @@ public partial class PlayerController : CharacterBody2D, IController
|
|||||||
public override void _Ready()
|
public override void _Ready()
|
||||||
{
|
{
|
||||||
// 设置上下文
|
// 设置上下文
|
||||||
_playerModel = Context.GetModel<PlayerModel>();
|
_playerModel = this.GetModel<PlayerModel>();
|
||||||
|
|
||||||
// 注册事件监听,自动与节点生命周期绑定
|
// 注册事件监听,自动与节点生命周期绑定
|
||||||
this.RegisterEvent<PlayerInputEvent>(OnPlayerInput)
|
this.RegisterEvent<PlayerInputEvent>(OnPlayerInput)
|
||||||
@ -396,7 +396,7 @@ public partial class SignalController : Node, IController
|
|||||||
_timer.Start();
|
_timer.Start();
|
||||||
|
|
||||||
// 发送框架事件
|
// 发送框架事件
|
||||||
Context.SendEvent(new ButtonClickEvent { ButtonId = "main_button" });
|
this.SendEvent(new ButtonClickEvent { ButtonId = "main_button" });
|
||||||
}
|
}
|
||||||
|
|
||||||
private void OnTimerTimeout()
|
private void OnTimerTimeout()
|
||||||
@ -407,7 +407,7 @@ public partial class SignalController : Node, IController
|
|||||||
_progressBar.Value += 10;
|
_progressBar.Value += 10;
|
||||||
|
|
||||||
// 发送框架事件
|
// 发送框架事件
|
||||||
Context.SendEvent(new TimerTimeoutEvent());
|
this.SendEvent(new TimerTimeoutEvent());
|
||||||
}
|
}
|
||||||
|
|
||||||
private void OnProgressChanged(double value)
|
private void OnProgressChanged(double value)
|
||||||
@ -415,7 +415,7 @@ public partial class SignalController : Node, IController
|
|||||||
Logger.Debug($"Progress changed: {value}");
|
Logger.Debug($"Progress changed: {value}");
|
||||||
|
|
||||||
// 发送框架事件
|
// 发送框架事件
|
||||||
Context.SendEvent(new ProgressChangeEvent { Value = value });
|
this.SendEvent(new ProgressChangeEvent { Value = value });
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
@ -450,7 +450,7 @@ public partial class SignalEventBridge : Node, IController
|
|||||||
// Godot 信号 -> 框架事件
|
// Godot 信号 -> 框架事件
|
||||||
this.CreateSignalBuilder(_uiButton.SignalName.Pressed)
|
this.CreateSignalBuilder(_uiButton.SignalName.Pressed)
|
||||||
.Connect(() => {
|
.Connect(() => {
|
||||||
Context.SendEvent(new UIActionEvent {
|
this.SendEvent(new UIActionEvent {
|
||||||
Action = "button_click",
|
Action = "button_click",
|
||||||
Source = "main_button"
|
Source = "main_button"
|
||||||
});
|
});
|
||||||
@ -459,7 +459,7 @@ public partial class SignalEventBridge : Node, IController
|
|||||||
|
|
||||||
this.CreateSignalBuilder(_healthBar.SignalName.HealthDepleted)
|
this.CreateSignalBuilder(_healthBar.SignalName.HealthDepleted)
|
||||||
.Connect(() => {
|
.Connect(() => {
|
||||||
Context.SendEvent(new PlayerDeathEvent { Source = "health_system" });
|
this.SendEvent(new PlayerDeathEvent { Source = "health_system" });
|
||||||
})
|
})
|
||||||
.UnRegisterWhenNodeExitTree(this);
|
.UnRegisterWhenNodeExitTree(this);
|
||||||
}
|
}
|
||||||
@ -599,7 +599,7 @@ public partial class SmartResourceLoader : Node, IController
|
|||||||
Logger.Info($"Resource loaded: {request.Path}");
|
Logger.Info($"Resource loaded: {request.Path}");
|
||||||
|
|
||||||
// 发送资源加载完成事件
|
// 发送资源加载完成事件
|
||||||
Context.SendEvent(new ResourceLoadedEvent {
|
this.SendEvent(new ResourceLoadedEvent {
|
||||||
Path = request.Path,
|
Path = request.Path,
|
||||||
Resource = resource
|
Resource = resource
|
||||||
});
|
});
|
||||||
@ -608,7 +608,7 @@ public partial class SmartResourceLoader : Node, IController
|
|||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
{
|
{
|
||||||
Logger.Error($"Failed to load resource {request.Path}: {ex.Message}");
|
Logger.Error($"Failed to load resource {request.Path}: {ex.Message}");
|
||||||
Context.SendEvent(new ResourceLoadFailedEvent {
|
this.SendEvent(new ResourceLoadFailedEvent {
|
||||||
Path = request.Path,
|
Path = request.Path,
|
||||||
Error = ex.Message
|
Error = ex.Message
|
||||||
});
|
});
|
||||||
@ -751,7 +751,7 @@ public partial class SceneResourcePreloader : Node, IController
|
|||||||
|
|
||||||
foreach (var assetPath in resourceSet.RequiredAssets)
|
foreach (var assetPath in resourceSet.RequiredAssets)
|
||||||
{
|
{
|
||||||
Context.SendEvent(new ResourceLoadRequestEvent {
|
this.SendEvent(new ResourceLoadRequestEvent {
|
||||||
Path = assetPath,
|
Path = assetPath,
|
||||||
Priority = ResourcePriority.High
|
Priority = ResourcePriority.High
|
||||||
});
|
});
|
||||||
@ -977,7 +977,7 @@ public partial class MemoryOptimizedController : Node, IController
|
|||||||
Logger.Warning($"High memory usage detected: {memoryUsage / 1024 / 1024} MB");
|
Logger.Warning($"High memory usage detected: {memoryUsage / 1024 / 1024} MB");
|
||||||
|
|
||||||
// 触发内存清理
|
// 触发内存清理
|
||||||
Context.SendEvent(new HighMemoryUsageEvent {
|
this.SendEvent(new HighMemoryUsageEvent {
|
||||||
CurrentUsage = memoryUsage,
|
CurrentUsage = memoryUsage,
|
||||||
Threshold = threshold
|
Threshold = threshold
|
||||||
});
|
});
|
||||||
@ -1163,7 +1163,7 @@ public class PlayingState : IGameState
|
|||||||
public void Enter(StateMachineController controller)
|
public void Enter(StateMachineController controller)
|
||||||
{
|
{
|
||||||
controller.GetTree().Paused = false;
|
controller.GetTree().Paused = false;
|
||||||
controller.Context.SendEvent(new GameStartEvent());
|
controller.this.SendEvent(new GameStartEvent());
|
||||||
}
|
}
|
||||||
|
|
||||||
public void Update(StateMachineController controller, double delta) { }
|
public void Update(StateMachineController controller, double delta) { }
|
||||||
@ -1178,7 +1178,7 @@ public class PlayingState : IGameState
|
|||||||
|
|
||||||
public void Exit(StateMachineController controller)
|
public void Exit(StateMachineController controller)
|
||||||
{
|
{
|
||||||
controller.Context.SendEvent(new GamePauseEvent());
|
controller.this.SendEvent(new GamePauseEvent());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|||||||
@ -323,18 +323,17 @@ namespace MyGame.Systems
|
|||||||
|
|
||||||
```csharp
|
```csharp
|
||||||
using GFramework.Core.Abstractions.pause;
|
using GFramework.Core.Abstractions.pause;
|
||||||
using GFramework.Core.extensions;
|
|
||||||
using GFramework.Core.Abstractions.controller;
|
using GFramework.Core.Abstractions.controller;
|
||||||
|
using GFramework.SourceGenerators.Abstractions.rule;
|
||||||
|
|
||||||
namespace MyGame.Controllers
|
namespace MyGame.Controllers
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 暂停控制器,管理复杂的暂停场景
|
/// 暂停控制器,管理复杂的暂停场景
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public class PauseController : IController
|
[ContextAware]
|
||||||
|
public partial class PauseController : IController
|
||||||
{
|
{
|
||||||
public IArchitecture GetArchitecture() => GameArchitecture.Interface;
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 显示暂停状态信息
|
/// 显示暂停状态信息
|
||||||
/// </summary>
|
/// </summary>
|
||||||
@ -664,8 +663,8 @@ namespace MyGame
|
|||||||
|
|
||||||
```csharp
|
```csharp
|
||||||
using GFramework.Core.Abstractions.pause;
|
using GFramework.Core.Abstractions.pause;
|
||||||
using GFramework.Core.extensions;
|
|
||||||
using GFramework.Core.Abstractions.controller;
|
using GFramework.Core.Abstractions.controller;
|
||||||
|
using GFramework.SourceGenerators.Abstractions.rule;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
namespace MyGame.Controllers
|
namespace MyGame.Controllers
|
||||||
@ -673,10 +672,9 @@ namespace MyGame.Controllers
|
|||||||
/// <summary>
|
/// <summary>
|
||||||
/// 游戏场景控制器
|
/// 游戏场景控制器
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public class GameSceneController : IController
|
[ContextAware]
|
||||||
|
public partial class GameSceneController : IController
|
||||||
{
|
{
|
||||||
public IArchitecture GetArchitecture() => GameArchitecture.Interface;
|
|
||||||
|
|
||||||
private PauseToken? _pauseMenuToken;
|
private PauseToken? _pauseMenuToken;
|
||||||
private PauseToken? _dialogToken;
|
private PauseToken? _dialogToken;
|
||||||
|
|
||||||
|
|||||||
@ -398,13 +398,13 @@ using GFramework.Core.Abstractions.state;
|
|||||||
using GFramework.Core.extensions;
|
using GFramework.Core.extensions;
|
||||||
using MyGame.States;
|
using MyGame.States;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
|
using GFramework.SourceGenerators.Abstractions.rule;
|
||||||
|
|
||||||
namespace MyGame.Controllers
|
namespace MyGame.Controllers
|
||||||
{
|
{
|
||||||
public class GameFlowController : IController
|
[ContextAware]
|
||||||
|
public partial class GameFlowController : IController
|
||||||
{
|
{
|
||||||
public IArchitecture GetArchitecture() => GameArchitecture.Interface;
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 开始游戏
|
/// 开始游戏
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
|||||||
@ -832,7 +832,7 @@ public class ArchitectureIntegrationTests
|
|||||||
await _architecture.DestroyAsync();
|
await _architecture.DestroyAsync();
|
||||||
|
|
||||||
// Assert
|
// Assert
|
||||||
var system = _architecture.Context.GetSystem<TestSystem>();
|
var system = _architecture.this.GetSystem<TestSystem>();
|
||||||
Assert.That(system!.DestroyCalled, Is.True);
|
Assert.That(system!.DestroyCalled, Is.True);
|
||||||
Assert.That(_architecture.CurrentPhase, Is.EqualTo(ArchitecturePhase.Destroyed));
|
Assert.That(_architecture.CurrentPhase, Is.EqualTo(ArchitecturePhase.Destroyed));
|
||||||
}
|
}
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user