using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Threading;
using System.Threading.Tasks;
using BetterGenshinImpact.Model.Gear;
using BetterGenshinImpact.Model.Gear.Tasks;
using BetterGenshinImpact.ViewModel.Pages.Component;
using Microsoft.Extensions.Logging;
using Microsoft.Extensions.DependencyInjection;
using CommunityToolkit.Mvvm.ComponentModel;
namespace BetterGenshinImpact.Service;
///
/// 齿轮任务执行器,负责从 JSON 数据解析任务并执行
///
public partial class GearTaskExecutor : ObservableObject
{
private readonly ILogger _logger;
private readonly GearTaskStorageService _storageService;
private readonly GearTaskConverter _taskConverter;
private readonly GearTaskExecutionManager _executionManager;
private readonly IServiceProvider _serviceProvider;
[ObservableProperty]
private bool _isExecuting;
[ObservableProperty]
private string _currentTaskName = string.Empty;
[ObservableProperty]
private double _progress;
[ObservableProperty]
private string _statusMessage = string.Empty;
public GearTaskExecutor(
ILogger logger,
GearTaskStorageService storageService,
GearTaskConverter taskConverter,
GearTaskExecutionManager executionManager,
IServiceProvider serviceProvider)
{
_logger = logger;
_storageService = storageService;
_taskConverter = taskConverter;
_executionManager = executionManager;
_serviceProvider = serviceProvider;
// 订阅执行管理器事件
_executionManager.ProgressChanged += OnProgressChanged;
_executionManager.PropertyChanged += OnExecutionManagerPropertyChanged;
}
///
/// 从 JSON 文件加载并执行任务定义
///
/// 任务定义名称
/// 取消令牌
///
public async Task ExecuteTaskDefinitionAsync(string taskDefinitionName, CancellationToken ct = default)
{
if (IsExecuting)
{
throw new InvalidOperationException("任务执行器正在运行中,请等待当前任务完成");
}
try
{
IsExecuting = true;
StatusMessage = "正在加载任务定义...";
Progress = 0;
// 从存储服务加载任务定义
var taskDefinitionViewModel = await _storageService.LoadTaskDefinitionAsync(taskDefinitionName);
if (taskDefinitionViewModel == null)
{
throw new ArgumentException($"未找到任务定义: {taskDefinitionName}");
}
if (taskDefinitionViewModel.RootTask == null)
{
throw new InvalidOperationException($"任务定义 '{taskDefinitionName}' 没有根任务");
}
_logger.LogInformation("开始执行任务定义: {TaskDefinitionName}", taskDefinitionName);
// 转换为可执行的任务
var rootTaskData = ConvertViewModelToData(taskDefinitionViewModel.RootTask);
var rootTask = await _taskConverter.ConvertTaskDataAsync(rootTaskData);
// 使用执行管理器执行任务
await _executionManager.ExecuteWithTrackingAsync(rootTask, ct);
StatusMessage = "任务执行完成";
Progress = 100;
_logger.LogInformation("任务定义执行完成: {TaskDefinitionName}", taskDefinitionName);
}
catch (OperationCanceledException)
{
StatusMessage = "任务执行已取消";
_logger.LogInformation("任务定义执行已取消: {TaskDefinitionName}", taskDefinitionName);
throw;
}
catch (Exception ex)
{
StatusMessage = $"任务执行失败: {ex.Message}";
_logger.LogError(ex, "执行任务定义时发生错误: {TaskDefinitionName}", taskDefinitionName);
throw;
}
finally
{
IsExecuting = false;
}
}
///
/// 直接执行 GearTaskData
///
/// 任务数据
/// 取消令牌
///
public async Task ExecuteTaskDataAsync(GearTaskData taskData, CancellationToken ct = default)
{
if (IsExecuting)
{
throw new InvalidOperationException("任务执行器正在运行中,请等待当前任务完成");
}
try
{
IsExecuting = true;
StatusMessage = "正在执行任务...";
Progress = 0;
_logger.LogInformation("开始执行任务: {TaskName}", taskData.Name);
// 转换为可执行的任务
var executableTask = await _taskConverter.ConvertTaskDataAsync(taskData);
// 使用执行管理器执行任务
await _executionManager.ExecuteWithTrackingAsync(executableTask, ct);
StatusMessage = "任务执行完成";
Progress = 100;
_logger.LogInformation("任务执行完成: {TaskName}", taskData.Name);
}
catch (OperationCanceledException)
{
StatusMessage = "任务执行已取消";
_logger.LogInformation("任务执行已取消: {TaskName}", taskData.Name);
throw;
}
catch (Exception ex)
{
StatusMessage = $"任务执行失败: {ex.Message}";
_logger.LogError(ex, "执行任务时发生错误: {TaskName}", taskData.Name);
throw;
}
finally
{
IsExecuting = false;
}
}
///
/// 停止当前执行的任务
///
public void StopExecution()
{
if (IsExecuting)
{
StatusMessage = "正在停止任务执行...";
_logger.LogInformation("用户请求停止任务执行");
_executionManager.CancelExecution();
}
}
///
/// 处理进度变化事件
///
/// 事件发送者
/// 进度值
private void OnProgressChanged(object? sender, double progress)
{
Progress = progress;
}
///
/// 处理执行管理器属性变化事件
///
/// 事件发送者
/// 属性变化事件参数
private void OnExecutionManagerPropertyChanged(object? sender, PropertyChangedEventArgs e)
{
switch (e.PropertyName)
{
case nameof(GearTaskExecutionManager.CurrentTaskInfo):
if (_executionManager.CurrentTaskInfo != null)
{
CurrentTaskName = _executionManager.CurrentTaskInfo.TaskName;
}
break;
case nameof(GearTaskExecutionManager.OverallStatusMessage):
StatusMessage = _executionManager.OverallStatusMessage;
break;
case nameof(GearTaskExecutionManager.IsExecuting):
IsExecuting = _executionManager.IsExecuting;
break;
}
}
///
/// 获取执行统计信息
///
/// 统计信息
public TaskExecutionStatistics GetExecutionStatistics()
{
return _executionManager.GetStatistics();
}
///
/// 获取当前任务执行信息
///
/// 当前任务信息
public TaskExecutionInfo? GetCurrentTaskInfo()
{
return _executionManager.CurrentTaskInfo;
}
///
/// 获取根任务执行信息
///
///
public TaskExecutionInfo? GetRootTaskInfo()
{
return _executionManager.RootTaskInfo;
}
///
/// 将 GearTaskViewModel 转换为 GearTaskData
///
/// 视图模型
/// 任务数据
private GearTaskData ConvertViewModelToData(GearTaskViewModel viewModel)
{
var taskData = new GearTaskData
{
Name = viewModel.Name,
TaskType = viewModel.TaskType,
IsEnabled = viewModel.IsEnabled,
IsDirectory = viewModel.IsDirectory,
Parameters = viewModel.Parameters,
CreatedTime = viewModel.CreatedTime,
ModifiedTime = viewModel.ModifiedTime,
Priority = viewModel.Priority,
};
// 递归转换子任务
if (viewModel.Children?.Count > 0)
{
taskData.Children = new List();
foreach (var child in viewModel.Children)
{
taskData.Children.Add(ConvertViewModelToData(child));
}
}
return taskData;
}
}
///
/// 空任务实现,用于已禁用的任务
///
internal class EmptyGearTask : BaseGearTask
{
public override Task Run(CancellationToken ct)
{
return Task.CompletedTask;
}
}