fix: restore test build and govern async callbacks
This commit is contained in:
@@ -1,3 +1,2 @@
|
||||
global using XplorePlane.Services.ImageProcessing;
|
||||
global using XplorePlane.Services.Logging;
|
||||
global using XplorePlane.Services.Pipeline;
|
||||
global using XplorePlane.Services.ImageProcessing;
|
||||
global using XplorePlane.Services.Pipeline;
|
||||
|
||||
@@ -32,7 +32,7 @@ namespace XplorePlane.Tests.Inspection
|
||||
|
||||
Assert.Equal("Detector", result.Source);
|
||||
Assert.Equal(2, result.Image.PixelWidth);
|
||||
harness.Motion.Verify(x => x.MoveAllToTarget(It.IsAny<Dictionary<AxisId, double>>()), Times.Once);
|
||||
harness.Motion.Verify(x => x.MoveAllToTarget(It.IsAny<Dictionary<AxisId, double>>(), false), Times.Once);
|
||||
harness.Detector.Verify(x => x.ApplyParametersAsync(0, 1, 10m, 2, It.IsAny<CancellationToken>()), Times.Once);
|
||||
harness.Detector.Verify(x => x.AcquireSingleFrameAsync(It.IsAny<CancellationToken>()), Times.Once);
|
||||
harness.Ray.Verify(x => x.SetVoltage(120), Times.Once);
|
||||
@@ -70,7 +70,7 @@ namespace XplorePlane.Tests.Inspection
|
||||
harness.Service.AcquireAsync(Machine(), Acquisition(), CancellationToken.None));
|
||||
|
||||
Assert.Contains("安全门", error.Message);
|
||||
harness.Motion.Verify(x => x.MoveAllToTarget(It.IsAny<Dictionary<AxisId, double>>()), Times.Never);
|
||||
harness.Motion.Verify(x => x.MoveAllToTarget(It.IsAny<Dictionary<AxisId, double>>(), false), Times.Never);
|
||||
harness.Ray.Verify(x => x.TurnOn(), Times.Never);
|
||||
harness.Motion.Verify(x => x.StopAll(), Times.Once);
|
||||
}
|
||||
@@ -84,7 +84,7 @@ namespace XplorePlane.Tests.Inspection
|
||||
harness.Service.AcquireAsync(Machine(), Acquisition(), CancellationToken.None));
|
||||
|
||||
Assert.Contains("探测器未连接", error.Message);
|
||||
harness.Motion.Verify(x => x.MoveAllToTarget(It.IsAny<Dictionary<AxisId, double>>()), Times.Never);
|
||||
harness.Motion.Verify(x => x.MoveAllToTarget(It.IsAny<Dictionary<AxisId, double>>(), false), Times.Never);
|
||||
harness.Ray.Verify(x => x.TurnOn(), Times.Never);
|
||||
}
|
||||
|
||||
@@ -113,7 +113,7 @@ namespace XplorePlane.Tests.Inspection
|
||||
bool detectorConnected = true)
|
||||
{
|
||||
var motion = new Mock<IMotionControlService>();
|
||||
motion.Setup(x => x.MoveAllToTarget(It.IsAny<Dictionary<AxisId, double>>()))
|
||||
motion.Setup(x => x.MoveAllToTarget(It.IsAny<Dictionary<AxisId, double>>(), false))
|
||||
.Returns(MotionResult.Ok());
|
||||
motion.Setup(x => x.MoveRotaryToTarget(It.IsAny<RotaryAxisId>(), It.IsAny<double>(), It.IsAny<double?>()))
|
||||
.Returns(MotionResult.Ok());
|
||||
|
||||
@@ -7,7 +7,7 @@ using XP.Common.Logging.Interfaces;
|
||||
using XplorePlane.Models;
|
||||
using XplorePlane.Services;
|
||||
using XplorePlane.Services.Storage;
|
||||
using XplorePlane.Services.Dialogs;
|
||||
using XplorePlane.Views.Dialogs;
|
||||
using XplorePlane.Tests.Helpers;
|
||||
using XplorePlane.ViewModels;
|
||||
using Xunit;
|
||||
|
||||
@@ -14,7 +14,7 @@ using XplorePlane.Models;
|
||||
using XplorePlane.Services;
|
||||
using XplorePlane.Services.Security;
|
||||
using XplorePlane.Services.Storage;
|
||||
using XplorePlane.Services.Dialogs;
|
||||
using XplorePlane.Views.Dialogs;
|
||||
using XplorePlane.Tests.Helpers;
|
||||
using XplorePlane.ViewModels;
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
using System.Linq;
|
||||
using XplorePlane.Services.Diagnostics;
|
||||
using XplorePlane.Services.Helpers;
|
||||
using Xunit;
|
||||
|
||||
namespace XplorePlane.Tests.Services
|
||||
|
||||
@@ -168,7 +168,7 @@ namespace XplorePlane.Tests.Services.Reporting
|
||||
new JsonTemplateEngine(Logger().Object),
|
||||
new ExpressionDataBinder(Logger().Object, loc.Object),
|
||||
new PageLayoutEngine(Logger().Object, new JsonTemplateEngine(Logger().Object)),
|
||||
new ITextPdfRenderer(Logger().Object, loc.Object));
|
||||
new ITextPdfRenderer(Logger().Object, loc.Object, new XP.ReportEngine.Configs.ReportConfig()));
|
||||
|
||||
var outputPath = Path.Combine(Path.GetTempPath(), $"cnc_report_test_{Guid.NewGuid():N}.pdf");
|
||||
|
||||
|
||||
@@ -16,7 +16,7 @@ using XP.Common.Logging.Interfaces;
|
||||
using XplorePlane.Models;
|
||||
using XplorePlane.Services.AppState;
|
||||
using XplorePlane.Services.Cnc;
|
||||
using XplorePlane.Services.Dialogs;
|
||||
using XplorePlane.Views.Dialogs;
|
||||
using XplorePlane.Services.Storage;
|
||||
using XplorePlane.Services;
|
||||
using XplorePlane.Services.Security;
|
||||
|
||||
@@ -10,7 +10,7 @@ using Xunit;
|
||||
using XplorePlane.Models;
|
||||
using XplorePlane.Services.Cnc;
|
||||
using XplorePlane.Services.Cnc.Matrix;
|
||||
using XplorePlane.Services.Dialogs;
|
||||
using XplorePlane.Views.Dialogs;
|
||||
using XplorePlane.ViewModels.Cnc;
|
||||
|
||||
namespace XplorePlane.Tests.ViewModels
|
||||
|
||||
@@ -224,7 +224,7 @@ namespace XplorePlane.Services.Hardware.Camera
|
||||
app?.Dispatcher.BeginInvoke(() => FrameArrived?.Invoke(this, bitmap));
|
||||
|
||||
// 链式触发下一帧
|
||||
TriggerNextLiveViewFrameAsync();
|
||||
_ = TriggerNextLiveViewFrameAsync();
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
@@ -237,7 +237,7 @@ namespace XplorePlane.Services.Hardware.Camera
|
||||
_logger.Warn($"相机采集错误: ErrorCode={e.ErrorCode}, {e.ErrorDescription}");
|
||||
}
|
||||
|
||||
private async void TriggerNextLiveViewFrameAsync()
|
||||
private async Task TriggerNextLiveViewFrameAsync()
|
||||
{
|
||||
if (!_liveViewRunning || _disposed)
|
||||
return;
|
||||
@@ -284,4 +284,4 @@ namespace XplorePlane.Services.Hardware.Camera
|
||||
_logger.Info("CameraService 已释放");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,20 @@
|
||||
using System;
|
||||
using System.Text.Json;
|
||||
using XplorePlane.Models.Inspection;
|
||||
|
||||
namespace XplorePlane.Services.Inspection
|
||||
{
|
||||
/// <summary>
|
||||
/// 检测定义快照工具。用于在执行前冻结包含可变 PipelineModel 的定义,避免后续编辑影响运行快照。
|
||||
/// </summary>
|
||||
public static class InspectionDefinitionSnapshot
|
||||
{
|
||||
public static InspectionDefinition Clone(InspectionDefinition source)
|
||||
{
|
||||
ArgumentNullException.ThrowIfNull(source);
|
||||
var json = JsonSerializer.Serialize(source);
|
||||
return JsonSerializer.Deserialize<InspectionDefinition>(json)
|
||||
?? throw new InvalidOperationException("无法创建检测定义快照。");
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -32,9 +32,10 @@ namespace XplorePlane.Services.Reporting
|
||||
/// <summary>
|
||||
/// CNC 报告上下文构建器实现 | CNC report context builder implementation
|
||||
/// </summary>
|
||||
public sealed class CncReportContextBuilder : ICncReportContextBuilder
|
||||
{
|
||||
private const string PassText = "PASS";
|
||||
public sealed class CncReportContextBuilder : ICncReportContextBuilder
|
||||
{
|
||||
public const string CncTemplateRelativePath = @"Templates\CncInspectionReportTemplate.json";
|
||||
private const string PassText = "PASS";
|
||||
private const string FailText = "FAIL";
|
||||
private const string EmptyText = "-";
|
||||
|
||||
@@ -595,4 +596,4 @@ namespace XplorePlane.Services.Reporting
|
||||
|
||||
#endregion 私有辅助 | Private helpers
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -201,6 +201,9 @@ namespace XplorePlane.ViewModels.Cnc
|
||||
}
|
||||
|
||||
private async void OnManualImageLoaded(ManualImageLoadedPayload payload)
|
||||
=> await OnManualImageLoadedAsync(payload);
|
||||
|
||||
private async Task OnManualImageLoadedAsync(ManualImageLoadedPayload payload)
|
||||
{
|
||||
if (payload?.Image == null || _currentProgram == null || IsRunning)
|
||||
return;
|
||||
|
||||
@@ -4,6 +4,7 @@
|
||||
using Prism.Commands;
|
||||
using Prism.Mvvm;
|
||||
using System;
|
||||
using System.Threading.Tasks;
|
||||
using System.Collections.Generic;
|
||||
using System.Collections.ObjectModel;
|
||||
using System.IO;
|
||||
@@ -51,7 +52,7 @@ namespace XplorePlane.ViewModels.ImageProcessing
|
||||
AvailableProcessors.Add(new ProcessorItem(key, _imageProcessingService.GetProcessorDisplayName(key)));
|
||||
|
||||
SelectProcessorCommand = new DelegateCommand<string>(OnSelectProcessor);
|
||||
ApplyProcessingCommand = new DelegateCommand(OnApplyProcessing);
|
||||
ApplyProcessingCommand = new DelegateCommand(async () => await OnApplyProcessingAsync());
|
||||
ResetImageCommand = new DelegateCommand(OnResetImage);
|
||||
LoadImageCommand = new DelegateCommand(OnLoadImage);
|
||||
SaveResultCommand = new DelegateCommand(OnSaveResult, () => CurrentImage != null);
|
||||
@@ -131,7 +132,7 @@ namespace XplorePlane.ViewModels.ImageProcessing
|
||||
}
|
||||
}
|
||||
|
||||
private async void OnApplyProcessing()
|
||||
private async Task OnApplyProcessingAsync()
|
||||
{
|
||||
if (CurrentImage == null || string.IsNullOrEmpty(SelectedProcessor)) return;
|
||||
|
||||
@@ -240,4 +241,4 @@ namespace XplorePlane.ViewModels.ImageProcessing
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -74,7 +74,7 @@ public class TemplateMatchBatchViewModel : BindableBase, IDisposable
|
||||
_assistant.PropertyChanged += OnAssistantPropertyChanged;
|
||||
|
||||
PickFolderCommand = new DelegateCommand(ExecutePickFolder);
|
||||
StartBatchCommand = new DelegateCommand(ExecuteStartBatch, CanStartBatch);
|
||||
StartBatchCommand = new DelegateCommand(async () => await ExecuteStartBatchAsync(), CanStartBatch);
|
||||
StopBatchCommand = new DelegateCommand(ExecuteStopBatch, () => _isRunning);
|
||||
OpenSelectedInMainViewportCommand = new DelegateCommand(ExecuteOpenSelectedInMainViewport, () => SelectedRow != null);
|
||||
}
|
||||
@@ -180,7 +180,7 @@ public class TemplateMatchBatchViewModel : BindableBase, IDisposable
|
||||
StartBatchCommand.RaiseCanExecuteChanged();
|
||||
}
|
||||
|
||||
private async void ExecuteStartBatch()
|
||||
private async Task ExecuteStartBatchAsync()
|
||||
{
|
||||
if (!CanStartBatch()) return;
|
||||
|
||||
@@ -347,4 +347,4 @@ public class TemplateMatchBatchViewModel : BindableBase, IDisposable
|
||||
_batchCts?.Dispose();
|
||||
_batchCts = null;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -53,7 +53,7 @@ namespace XplorePlane.ViewModels.Main
|
||||
|
||||
#region CNC 编辑动作分发(单例嵌入式面板)
|
||||
|
||||
private async void ExecuteCncEditorAction(Action<CncEditorViewModel> action)
|
||||
private void ExecuteCncEditorAction(Action<CncEditorViewModel> action)
|
||||
{
|
||||
ArgumentNullException.ThrowIfNull(action);
|
||||
try
|
||||
@@ -116,6 +116,9 @@ namespace XplorePlane.ViewModels.Main
|
||||
|
||||
/// <summary>响应"把实时流水线作为检测模块加入 CNC"请求。</summary>
|
||||
private async void OnAddPipelineToCncRequested(XplorePlane.Models.ImageProcessing.PipelineModel pipeline)
|
||||
=> await OnAddPipelineToCncRequestedAsync(pipeline);
|
||||
|
||||
private async Task OnAddPipelineToCncRequestedAsync(XplorePlane.Models.ImageProcessing.PipelineModel pipeline)
|
||||
{
|
||||
try
|
||||
{
|
||||
@@ -181,4 +184,4 @@ namespace XplorePlane.ViewModels.Main
|
||||
|
||||
#endregion 内置检测模块插入
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3,6 +3,7 @@ using Prism.Events;
|
||||
using Prism.Ioc;
|
||||
using Prism.Mvvm;
|
||||
using System;
|
||||
using System.Threading.Tasks;
|
||||
using System.Collections.Generic;
|
||||
using System.Collections.ObjectModel;
|
||||
using System.ComponentModel;
|
||||
@@ -733,7 +734,7 @@ namespace XplorePlane.ViewModels.Main
|
||||
OpenOverlaySettingsCommand = new DelegateCommand(ExecuteOpenOverlaySettings);
|
||||
OpenLibraryVersionsCommand = new DelegateCommand(() => _windowLauncher.Show(new Views.Help.LibraryVersionsWindow(), "关于"));
|
||||
OpenUserManualCommand = new DelegateCommand(ExecuteOpenUserManual);
|
||||
CheckForUpdateCommand = new DelegateCommand(ExecuteCheckForUpdate);
|
||||
CheckForUpdateCommand = new DelegateCommand(async () => await ExecuteCheckForUpdateAsync());
|
||||
OpenCameraSettingsCommand = new DelegateCommand(ExecuteOpenCameraSettings);
|
||||
OpenCameraChessboardCalibrationCommand = new DelegateCommand(ExecuteOpenCameraChessboardCalibration);
|
||||
OpenCameraCalibrationCommand = new DelegateCommand(ExecuteOpenCameraCalibration);
|
||||
@@ -798,8 +799,8 @@ namespace XplorePlane.ViewModels.Main
|
||||
BlackBackgroundDetectionCommand = new DelegateCommand(ExecuteBlackBackgroundDetection);
|
||||
OpenTemplateMatchAssistantCommand = new DelegateCommand(ExecuteOpenTemplateMatchAssistant);
|
||||
GrayscaleCommand = new DelegateCommand(ExecuteGrayscale);
|
||||
SharpenCommand = new DelegateCommand(ExecuteSharpen);
|
||||
EnhanceCommand = new DelegateCommand(ExecuteEnhance);
|
||||
SharpenCommand = new DelegateCommand(async () => await ExecuteSharpenAsync());
|
||||
EnhanceCommand = new DelegateCommand(async () => await ExecuteEnhanceAsync());
|
||||
EdgeLineFitCommand = new DelegateCommand(ExecuteEdgeLineFit);
|
||||
EdgeCircleFitCommand = new DelegateCommand(ExecuteEdgeCircleFit);
|
||||
|
||||
@@ -810,7 +811,7 @@ namespace XplorePlane.ViewModels.Main
|
||||
OpenMotionDebugCommand = new DelegateCommand(ExecuteOpenMotionDebug);
|
||||
RandomMoveAxesCommand = new DelegateCommand(ExecuteRandomMoveAxes);
|
||||
OpenCalibrationWizardCommand = new DelegateCommand(ExecuteOpenCalibrationWizard);
|
||||
OneClickInitializeCommand = new DelegateCommand(ExecuteOneClickInitialize);
|
||||
OneClickInitializeCommand = new DelegateCommand(async () => await ExecuteOneClickInitializeAsync());
|
||||
OpenPlcAddrConfigCommand = new DelegateCommand(ExecuteOpenPlcAddrConfig);
|
||||
OpenRaySourceConfigCommand = new DelegateCommand(ExecuteOpenRaySourceConfig);
|
||||
OpenReportConfigCommand = new DelegateCommand(ExecuteOpenReportConfig);
|
||||
@@ -957,7 +958,7 @@ namespace XplorePlane.ViewModels.Main
|
||||
}
|
||||
}
|
||||
|
||||
private async void ExecuteCheckForUpdate()
|
||||
private async Task ExecuteCheckForUpdateAsync()
|
||||
{
|
||||
try
|
||||
{
|
||||
@@ -1289,7 +1290,7 @@ namespace XplorePlane.ViewModels.Main
|
||||
throw new InvalidOperationException("导航相机有效视野与 StageX/StageY 轴行程没有可用交集。");
|
||||
}
|
||||
|
||||
private async void ExecuteOneClickInitialize()
|
||||
private async Task ExecuteOneClickInitializeAsync()
|
||||
{
|
||||
try
|
||||
{
|
||||
@@ -1468,7 +1469,7 @@ namespace XplorePlane.ViewModels.Main
|
||||
}
|
||||
}
|
||||
|
||||
private async void ExecuteSharpen()
|
||||
private async Task ExecuteSharpenAsync()
|
||||
{
|
||||
if (!CheckImageLoaded()) return;
|
||||
|
||||
@@ -1503,7 +1504,7 @@ namespace XplorePlane.ViewModels.Main
|
||||
}
|
||||
}
|
||||
|
||||
private async void ExecuteEnhance()
|
||||
private async Task ExecuteEnhanceAsync()
|
||||
{
|
||||
if (!CheckImageLoaded()) return;
|
||||
|
||||
|
||||
@@ -479,7 +479,7 @@ namespace XplorePlane.ViewModels.Main
|
||||
/// </summary>
|
||||
/// <param name="pixelX">图像像素 X</param>
|
||||
/// <param name="pixelY">图像像素 Y</param>
|
||||
public async void NavigateToPixel(double pixelX, double pixelY)
|
||||
public async Task NavigateToPixel(double pixelX, double pixelY)
|
||||
{
|
||||
if (!IsCalibrated)
|
||||
{
|
||||
|
||||
@@ -387,7 +387,7 @@ namespace XplorePlane.Views.Main
|
||||
return;
|
||||
}
|
||||
|
||||
_viewModel.NavigateToPixel(px, py);
|
||||
_ = _viewModel.NavigateToPixel(px, py);
|
||||
}
|
||||
|
||||
#region PiP (Picture-in-Picture) - 青框画中画
|
||||
|
||||
Reference in New Issue
Block a user