using System.IO;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using SparkClient.Model.Common;
using SparkClient.Model.Helper;
using SparkClient.Model.Services;
using SparkClient.Views.Dialog;
namespace SparkClient.ViewModel.Grading;
public class GradingLoadingVM : BaseViewModel,IDisposable
{
private double _progress;
private SOCClientService _socClientService;
///
/// 进度
///
public double Progress
{
get => _progress;
set
{
_progress = value;
OnPropertyChanged(nameof(Progress));
}
}
public ICommand StopCommand { get; }
private string _diamondCode;
private string _diamnondType;
private bool _disposed;
private CancellationTokenSource _progressCts;
private CancellationTokenSource? _playbackCts;
#region 图片播放控制
private PlayStatus _currentStatus = PlayStatus.Stopped;
public PlayStatus CurrentStatus
{
get => _currentStatus;
set
{
_currentStatus = value;
OnPropertyChanged(nameof(CurrentStatus));
OnPropertyChanged(nameof(ButtonText)); // 状态变更时更新按钮文本
}
}
public string ButtonText => CurrentStatus switch
{
PlayStatus.Playing => "暂停",
PlayStatus.Paused => "继续",
_ => "重播" // Stopped 状态
};
private CancellationTokenSource _cts;
private int _playDelay = 200; // 默认播放速度
public ICommand PlayControlCommand { get; }
public ICommand PreviousCommand { get; }
public ICommand NextCommand { get; }
private int _currentIndex;
public int CurrentIndex
{
get => _currentIndex;
set
{
_currentIndex = value;
OnPropertyChanged(nameof(CurrentIndex));
UpdateCurrentImage();
}
}
public string[] ImagePaths { get; set; }
public ImageSource CurrentImage { get; private set; }
public bool ImageIsEnable { get; private set; }
#endregion
public GradingLoadingVM(string diamnondType, string diamondCode)
{
_diamondCode = diamondCode;
_diamnondType = diamnondType;
StopCommand = new RelayCommand(Stop);
PlayControlCommand = new RelayCommand(async _ => await HandlePlayControl());
PreviousCommand = new RelayCommand(_ => MovePrevious());
NextCommand = new RelayCommand(_ => MoveNext());
ImageIsEnable = false;
_progressCts = new CancellationTokenSource();
_playbackCts = new CancellationTokenSource();
}
///
/// 开始检测
///
public async Task Start()
{
//开始显示进度条
//切工仪通讯 拉取图片 延时...5秒
//播放图片
//图片拉取完毕---|
// var configValue = ConfigurationHelper.ReadConfigValue("ProgressTime");
// int iProgTime = int.TryParse(configValue, out var result) ? result : 50000;
// int stepTime = iProgTime / 97;
//
// for (int i = 0; i <= 97; i++)
// {
// _progressCts.Token.ThrowIfCancellationRequested();
// Progress = i;
// await Task.Delay(stepTime, _progressCts.Token);
// }
var progress = RunProgressAsync(_progressCts.Token);
_socClientService = new SOCClientService();
var processImage = _socClientService.ProcessImageCollectionAsync();
//通知页面可以播放图片
await processImage;
if (!"ok".Equals(processImage.Result.Status))
{
_progressCts.Cancel();
new MessageBox().Show(MultilingualHelper.getString(StatusCodes.GetConstantNameByValue(processImage.Result.Status)));
return -1;
}
LoadImages(processImage.Result.Images);
ImageIsEnable = true;
await progress;
return 0;
}
private void Stop(object param)
{
//询问?停止:忽略
}
private async Task RunProgressAsync(CancellationToken token)
{
var configValue = ConfigurationHelper.ReadConfigValue("ProgressTime");
int totalDuration = int.TryParse(configValue, out var result) ? result : 50000;
int stepTime = totalDuration / 97;
// 使用 IProgress 实现线程安全的进度报告
var progress = new Progress(value =>
{
if (!token.IsCancellationRequested)
Progress = value;
});
await Task.Run(async () =>
{
for (int i = 0; i <= 97; i++)
{
token.ThrowIfCancellationRequested();
// 报告进度
((IProgress)progress).Report(i);
// 使用可取消的延迟
await Task.Delay(stepTime, token);
}
}, token);
}
public void Dispose()
{
Dispose(true);
GC.SuppressFinalize(this);
}
protected virtual void Dispose(bool disposing)
{
if (_disposed) return;
if (disposing)
{
// 取消所有操作
_progressCts?.Cancel();
_playbackCts?.Cancel();
// 释放托管资源
_progressCts?.Dispose();
_playbackCts?.Dispose();
}
_disposed = true;
}
#region 图片播放处理
public void LoadImages(string folderPath)
{
ImagePaths = Directory.GetFiles(folderPath, "*.bmp");
CurrentIndex = 0;
CurrentStatus = PlayStatus.Stopped;
}
public void LoadImages(List folderPath)
{
ImagePaths = folderPath.ToArray();
CurrentIndex = 0;
CurrentStatus = PlayStatus.Stopped;
}
private async Task HandlePlayControl()
{
switch (CurrentStatus)
{
case PlayStatus.Stopped:
await StartPlayback(); // 开始或重播
break;
case PlayStatus.Playing:
PausePlayback(); // 暂停
break;
case PlayStatus.Paused:
await ResumePlayback();// 继续
break;
}
}
private async Task StartPlayback()
{
CurrentStatus = PlayStatus.Playing;
_cts = new CancellationTokenSource();
try
{
for (CurrentIndex = 0; CurrentIndex < ImagePaths.Length; CurrentIndex++)
{
if (_cts.Token.IsCancellationRequested) break;
await Task.Delay(_playDelay);
}
// 播放完成处理
if (CurrentIndex >= ImagePaths.Length)
{
CurrentStatus = PlayStatus.Stopped;
CurrentIndex = 0; // 重置为初始位置
}
}
catch (TaskCanceledException) { /* 正常取消处理 */ }
}
private void PausePlayback()
{
_cts?.Cancel();
CurrentStatus = PlayStatus.Paused;
}
private async Task ResumePlayback()
{
CurrentStatus = PlayStatus.Playing;
_cts = new CancellationTokenSource();
await StartPlayback();
}
private void UpdateCurrentImage()
{
if (ImagePaths == null || CurrentIndex < 0 || CurrentIndex >= ImagePaths.Length)
return;
var bitmap = new BitmapImage();
bitmap.BeginInit();
bitmap.CacheOption = BitmapCacheOption.OnLoad;
bitmap.UriSource = new Uri(ImagePaths[CurrentIndex]);
bitmap.EndInit();
bitmap.Freeze(); // 确保跨线程安全
CurrentImage = bitmap;
OnPropertyChanged(nameof(CurrentImage));
}
private void MovePrevious()
{
if (CurrentStatus == PlayStatus.Playing)
PausePlayback();
CurrentIndex = (CurrentIndex - 1 + ImagePaths.Length) % ImagePaths.Length;
}
private void MoveNext()
{
if (CurrentStatus == PlayStatus.Playing)
PausePlayback();
CurrentIndex = (CurrentIndex + 1) % ImagePaths.Length;
}
#endregion
}
public enum PlayStatus
{
Stopped, // 初始/停止状态
Playing, // 播放中
Paused // 暂停中
}