using CommunityToolkit.Mvvm.ComponentModel; using NationalInstruments.TestStand.Interop.API; using Plugin.SeqEditor.Constant; using System.Collections.ObjectModel; using System.Runtime.InteropServices; namespace Plugin.SeqEditor.Entity { public partial class StepUI : ObservableObject { ~StepUI() { if (step != null) { Marshal.ReleaseComObject(step); } } public Step step { get; private set; } public Sequence sequence { get; private set; } public event EventHandler SettingChanged; public int IndexInSequence { get { return step.StepIndex; } } public int? CustomIndex { get; set; } public StepUI(Step step, Sequence sequence) { this.step = step; this.sequence = sequence; } public void UpdatePropertyChanged(string name) { OnPropertyChanged(name); } protected new void OnPropertyChanged(string name) { base.OnPropertyChanged(name); SettingChanged?.Invoke(this, name); } public string Name { get => step?.Name; set { if (step != null) { step.Name = value; OnPropertyChanged(nameof(Name)); } } } public string Id { get => step?.UniqueStepId; } public string Description { get => step?.Description; } public string RunMode { get { var t = step?.GetRunModeEx(); return t; } set { if (step != null) { step.SetRunModeEx(value); OnPropertyChanged(nameof(RunMode)); } } } public string Type { get => step?.StepType?.Name; } public bool CanChangeAdapter { get => step?.CanChangeAdapter() ?? true; } public string Adapter { get => step?.AdapterKeyName; set { if (step != null) { step.ChangeAdapter(value); OnPropertyChanged(nameof(RunMode)); } } } public bool HasLow => Type == StepTypeStr.NumericLimitTest || Type == StepTypeStr.StringValueTest; public bool HasHigh => Type == StepTypeStr.NumericLimitTest; public string Low { get { if (Type == StepTypeStr.NumericLimitTest) { return step?.AsPropertyObject()?.GetValNumber("Limits.Low", 0).ToString(); } else if (Type == StepTypeStr.StringValueTest) { var value = step?.AsPropertyObject()?.GetValString("Limits.String", 0); if (string.IsNullOrEmpty(value)) { value = step?.AsPropertyObject()?.GetValString("Limits.StringExpr", 0); } return value; } return null; } set { if (step != null && HasLow) { if (Type == StepTypeStr.NumericLimitTest) { double.TryParse(value, out double tmp); step?.AsPropertyObject().SetValNumber("Limits.Low", 0, tmp); } else if (Type == StepTypeStr.StringValueTest) { step?.AsPropertyObject()?.SetValString("Limits.String", 0, value); step?.AsPropertyObject()?.SetValString("Limits.StringExpr", 0, null); step?.AsPropertyObject()?.SetValBoolean("Limits.UseStringExpr", 0, false); } UpdatePropertyChanged("Low"); UpdatePropertyChanged("Description"); } } } public double? High { get => HasHigh ? step?.AsPropertyObject()?.GetValNumber("Limits.High", 0) : null; set { if (step != null && HasHigh) { step?.AsPropertyObject().SetValNumber("Limits.High", 0, value ?? 0); UpdatePropertyChanged("High"); UpdatePropertyChanged("Description"); } } } public StepGroups StepGroup { get { return step.StepGroup; } } [ObservableProperty] private string group; [ObservableProperty] public ObservableCollection children = new(); public string LoopType { get => step?.AsPropertyObject()?.GetValString("TS.LoopType", 0); set { if (step != null) { if (value == "FixedNumLoops") { step.AsPropertyObject().SetValString("TS.LoopType", 0, value); step.AsPropertyObject().SetValString("TS.LoopWhile", 0, "RunState.LoopIndex < 10"); step.AsPropertyObject().SetValString("TS.LoopStatus", 0, "RunState.LoopNumPassed / RunState.LoopNumIterations < 1 ? \"Failed\" : \"Passed\""); } else if (value == "PassFailCount") { step.AsPropertyObject().SetValString("TS.LoopType", 0, value); step.AsPropertyObject().SetValString("TS.LoopWhile", 0, "RunState.LoopIndex < 100 && RunState.LoopNumFailed < 10"); step.AsPropertyObject().SetValString("TS.LoopStatus", 0, "RunState.LoopNumFailed >= 10 ? \"Failed\" : \"Passed\""); } UpdatePropertyChanged("LoopType"); UpdatePropertyChanged("LoopCount"); UpdatePropertyChanged("LoopCondition"); UpdatePropertyChanged("LoopMax"); UpdatePropertyChanged("LoopDescription"); } } } public string LoopCount { get { if (step == null || step?.AsPropertyObject() == null) return null; string type = step.AsPropertyObject().GetValString("TS.LoopType", 0); string loopWhile; switch (type) { case "FixedNumLoops": loopWhile = step.AsPropertyObject().GetValString("TS.LoopWhile", 0); return loopWhile.Replace($"RunState.LoopIndex < ", ""); case "PassFailCount": loopWhile = step.AsPropertyObject().GetValString("TS.LoopWhile", 0); return loopWhile.Split(' ')[2]; default: return null; } } set { if (step != null) { string type = step.AsPropertyObject().GetValString("TS.LoopType", 0); switch (type) { case "FixedNumLoops": step.AsPropertyObject().SetValString("TS.LoopWhile", 0, $"RunState.LoopIndex < {value}"); UpdatePropertyChanged("LoopDescription"); return; case "PassFailCount": var field = LoopCondition == "pass" ? "LoopNumPassed" : "LoopNumFailed"; step.AsPropertyObject().SetValString("TS.LoopWhile", 0, $"RunState.LoopIndex < {value} && RunState.{field} < {LoopMax}"); UpdatePropertyChanged("LoopDescription"); return; default: return; } } } } public string LoopCondition { get { if (step == null || step?.AsPropertyObject() == null) return null; string type = step.AsPropertyObject().GetValString("TS.LoopType", 0); string loopStatus; switch (type) { case "FixedNumLoops": loopStatus = step.AsPropertyObject().GetValString("TS.LoopStatus", 0); return loopStatus.Split(' ')[3]; case "PassFailCount": loopStatus = step.AsPropertyObject().GetValString("TS.LoopStatus", 0); return loopStatus.Split(' ')[0] == "RunState.LoopNumPassed" ? "pass" : "fail"; default: return null; } } set { if (step != null) { string type = step.AsPropertyObject().GetValString("TS.LoopType", 0); switch (type) { case "FixedNumLoops": step.AsPropertyObject().SetValString("TS.LoopStatus", 0, $"RunState.LoopNumPassed / RunState.LoopNumIterations {value} {double.Parse(LoopMax) / 100} ? \"Failed\" : \"Passed\""); UpdatePropertyChanged("LoopDescription"); return; case "PassFailCount": var field = value == "pass" ? "LoopNumPassed" : "LoopNumFailed"; var sb = value == "pass" ? "\"Passed\" : \"Failed\"" : "\"Failed\" : \"Passed\""; step.AsPropertyObject().SetValString("TS.LoopWhile", 0, $"RunState.LoopIndex < {LoopCount} && RunState.{field} < {LoopMax}"); step.AsPropertyObject().SetValString("TS.LoopStatus", 0, $"RunState.{field} >= {LoopMax} ? {sb}"); UpdatePropertyChanged("LoopDescription"); return; default: return; } } } } public string LoopMax { get { if (step == null || step?.AsPropertyObject() == null) return null; string type = step.AsPropertyObject().GetValString("TS.LoopType", 0); string data; switch (type) { case "FixedNumLoops": data = step.AsPropertyObject().GetValString("TS.LoopStatus", 0); return (double.Parse(data.Split(' ')[4]) * 100).ToString(); case "PassFailCount": data = step.AsPropertyObject().GetValString("TS.LoopWhile", 0); return data.Split(' ')[6]; default: return null; } } set { if (step != null) { string type = step.AsPropertyObject().GetValString("TS.LoopType", 0); switch (type) { case "FixedNumLoops": step.AsPropertyObject().SetValString("TS.LoopStatus", 0, $"RunState.LoopNumPassed / RunState.LoopNumIterations {LoopCondition} {double.Parse(value) / 100} ? \"Failed\" : \"Passed\""); UpdatePropertyChanged("LoopDescription"); return; case "PassFailCount": var field = LoopCondition == "pass" ? "LoopNumPassed" : "LoopNumFailed"; step.AsPropertyObject().SetValString("TS.LoopWhile", 0, $"RunState.LoopIndex < {LoopCount} && RunState.{field} < {value}"); UpdatePropertyChanged("LoopDescription"); return; default: return; } } } } public string LoopDescription { get { if (step == null || step?.AsPropertyObject() == null) return null; string type = step.AsPropertyObject().GetValString("TS.LoopType", 0); switch (type) { case "FixedNumLoops": return $"循环{LoopCount}次,通过率{LoopCondition}{LoopMax}%时结果为PASS"; case "PassFailCount": return $"循环{LoopCount}次,{LoopCondition} {LoopMax}次以上结果为{LoopCondition}"; default: return null; } } set { } } public override string ToString() { return Name; } } }