Files
better-genshin-impact/BetterGenshinImpact/Service/GearTask/Execution/GearTaskNodeExecutionContext.cs
辉鸭蛋 7f7a34e9ba feat(gear-task): 引入事件驱动的任务执行与历史记录系统
- 新增 IGearTaskEventBus 接口及默认实现,用于解耦执行器与记录器、UI 投影等消费者
- 新增 IGearTaskResumable 接口,支持任务节点内部恢复(如 Pathing 任务可恢复至特定路径点)
- 重构任务执行流程,使用 GearTaskExecutionRunner 替代旧的 GearTaskExecutionManager
- 实现基于磁盘 JSON 的历史记录存储(IGearTaskHistoryStore),支持执行记录的保存、加载与清理
- 为 PathingGearTask 添加恢复能力,通过 PathingGearTaskResumeState 记录断点状态
- 在 PathExecutor 中集成运行时事件通知,支持路径点进入、完成、传送等事件的发布
- 统一执行事件模型(GearTaskExecutionEvent),包含任务定义、节点路径、时间戳等元数据
- 服务注册更新,使用新的执行器、事件总线、历史记录器等组件
2026-05-11 01:57:29 +08:00

125 lines
3.5 KiB
C#

using System.Threading;
using System.Threading.Tasks;
using BetterGenshinImpact.Model.Gear.Tasks;
namespace BetterGenshinImpact.Service.GearTask.Execution;
/// <summary>
/// 单个任务节点在一次执行中的上下文。
/// 它负责把节点元数据与事件发布能力打包传给具体任务实例。
/// </summary>
public sealed class GearTaskNodeExecutionContext
{
private readonly IGearTaskEventBus _eventBus;
public GearTaskNodeExecutionContext(
IGearTaskEventBus eventBus,
string recordId,
string taskDefinitionName,
string taskDefinitionFileKey,
string nodeId,
string? parentNodeId,
string taskName,
string taskType,
string taskPath,
int nodeDepth,
int nodeOrder,
string? resumeTokenJson)
{
_eventBus = eventBus;
RecordId = recordId;
TaskDefinitionName = taskDefinitionName;
TaskDefinitionFileKey = taskDefinitionFileKey;
NodeId = nodeId;
ParentNodeId = parentNodeId;
TaskName = taskName;
TaskType = taskType;
TaskPath = taskPath;
NodeDepth = nodeDepth;
NodeOrder = nodeOrder;
ResumeTokenJson = resumeTokenJson;
}
/// <summary>
/// 使用任务节点和运行上下文创建节点执行上下文。
/// </summary>
public static GearTaskNodeExecutionContext Create(
IGearTaskEventBus eventBus,
BaseGearTask task,
GearTaskExecutionRunContext runContext,
string nodeId,
string? parentNodeId,
int nodeDepth,
int nodeOrder,
string? resumeTokenJson)
{
return new GearTaskNodeExecutionContext(
eventBus,
runContext.RecordId,
runContext.TaskDefinitionName,
runContext.TaskDefinitionFileKey,
nodeId,
parentNodeId,
task.Name,
task.Type,
GearTaskExecutionPathFormatter.FormatTaskPath(task.FilePath),
nodeDepth,
nodeOrder,
resumeTokenJson);
}
public string RecordId { get; }
public string TaskDefinitionName { get; }
public string TaskDefinitionFileKey { get; }
public string NodeId { get; }
public string? ParentNodeId { get; }
public string TaskName { get; }
public string TaskType { get; }
public string TaskPath { get; }
public int NodeDepth { get; }
public int NodeOrder { get; }
/// <summary>
/// 从历史记录恢复时传入的节点级恢复令牌。
/// 由实现了 IGearTaskResumable 的任务自行解释。
/// </summary>
public string? ResumeTokenJson { get; }
/// <summary>
/// 基于当前节点信息构造一条事件,避免各任务重复填公共字段。
/// </summary>
public T CreateEvent<T>() where T : GearTaskExecutionEvent, new()
{
return new T
{
RecordId = RecordId,
TaskDefinitionName = TaskDefinitionName,
TaskDefinitionFileKey = TaskDefinitionFileKey,
NodeId = NodeId,
ParentNodeId = ParentNodeId,
TaskName = TaskName,
TaskType = TaskType,
TaskPath = TaskPath,
NodeDepth = NodeDepth,
NodeOrder = NodeOrder,
};
}
/// <summary>
/// 发布当前节点相关事件。
/// </summary>
public ValueTask PublishAsync(GearTaskExecutionEvent evt, CancellationToken ct = default)
{
return _eventBus.PublishAsync(evt, ct);
}
}