交运行工位桩:三口契约、运行服务、六态 VM、跨线程切 UI。
采集/PLC/Inspect 均为桩,验收 1–8 可测。不部署现场。
This commit is contained in:
@@ -0,0 +1,98 @@
|
||||
using System.ComponentModel;
|
||||
using System.Runtime.CompilerServices;
|
||||
using System.Windows.Input;
|
||||
using VisionHost.Contracts;
|
||||
|
||||
namespace VisionHost.Runtime;
|
||||
|
||||
public sealed class RelayCommand : ICommand
|
||||
{
|
||||
private readonly Action _exec;
|
||||
private readonly Func<bool>? _can;
|
||||
|
||||
public RelayCommand(Action exec, Func<bool>? can = null)
|
||||
{
|
||||
_exec = exec;
|
||||
_can = can;
|
||||
}
|
||||
|
||||
public event EventHandler? CanExecuteChanged;
|
||||
public bool CanExecute(object? parameter) => _can?.Invoke() ?? true;
|
||||
public void Execute(object? parameter) => _exec();
|
||||
public void RaiseCanExecuteChanged() => CanExecuteChanged?.Invoke(this, EventArgs.Empty);
|
||||
}
|
||||
|
||||
public sealed class RunViewModel : INotifyPropertyChanged, IDisposable
|
||||
{
|
||||
private readonly RunService _run;
|
||||
private readonly IUiDispatch _ui;
|
||||
private StationSnapshot _s;
|
||||
private int _disposed;
|
||||
|
||||
public RunViewModel(RunService run, IUiDispatch? ui = null)
|
||||
{
|
||||
_run = run;
|
||||
_ui = ui ?? new SynchronizationContextDispatch();
|
||||
_s = run.Snapshot();
|
||||
StartCommand = new RelayCommand(() => _run.RequestStart(), () => CanStart);
|
||||
StopCommand = new RelayCommand(() => _run.RequestStop(), () => CanStop);
|
||||
_run.Changed += OnChanged;
|
||||
}
|
||||
|
||||
public static RunViewModel CreateStub(IUserConfirm? confirm = null, IUiDispatch? ui = null)
|
||||
{
|
||||
var cam = new StubFrameSource();
|
||||
var run = new RunService(
|
||||
cam,
|
||||
cam,
|
||||
new StubInspectService(),
|
||||
new StubPlcIo(),
|
||||
confirm ?? new AlwaysConfirm(),
|
||||
new RuntimeOptions());
|
||||
return new RunViewModel(run, ui);
|
||||
}
|
||||
|
||||
public event PropertyChangedEventHandler? PropertyChanged;
|
||||
|
||||
public ICommand StartCommand { get; }
|
||||
public ICommand StopCommand { get; }
|
||||
|
||||
public RunState RunState => _s.RunState;
|
||||
public string RecipeName => _s.RecipeName;
|
||||
public string ConnectionText => _s.ConnectionText;
|
||||
public object? LiveImage => _s.LiveImage;
|
||||
public object? OverlayImage => _s.OverlayImage;
|
||||
public string BadgeText => _s.BadgeText;
|
||||
public string LastResultText => _s.LastResultText;
|
||||
public string LastResultBrush => _s.LastResultBrush;
|
||||
public int OkCount => _s.OkCount;
|
||||
public int NgCount => _s.NgCount;
|
||||
public int TotalCount => _s.TotalCount;
|
||||
public string AlarmText => _s.AlarmText;
|
||||
public string AlarmBrush => _s.AlarmBrush;
|
||||
public bool CanStart => _s.CanStart;
|
||||
public bool CanStop => _s.CanStop;
|
||||
|
||||
public RunService Service => _run;
|
||||
|
||||
private void OnChanged() => _ui.Post(ApplyOnUi);
|
||||
|
||||
private void ApplyOnUi()
|
||||
{
|
||||
if (Volatile.Read(ref _disposed) != 0) return;
|
||||
_s = _run.Snapshot();
|
||||
OnPropertyChanged(string.Empty);
|
||||
((RelayCommand)StartCommand).RaiseCanExecuteChanged();
|
||||
((RelayCommand)StopCommand).RaiseCanExecuteChanged();
|
||||
}
|
||||
|
||||
private void OnPropertyChanged([CallerMemberName] string? name = null)
|
||||
=> PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(name));
|
||||
|
||||
public void Dispose()
|
||||
{
|
||||
if (Interlocked.Exchange(ref _disposed, 1) != 0) return;
|
||||
_run.Changed -= OnChanged;
|
||||
_run.Dispose();
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user