using OpenTap; using OpenTap.Addin; using OpenTap.Addin.Entity; using OpenTap.Addin.Util; using System.Collections.ObjectModel; using UILib; namespace OpenTapEditor { public class RunningVarContext : NotifyBase { private TestPlanRun planRun; public TestPlanRun PlanRun { get => planRun; set { planRun = value; } } private Dictionary, ObservableCollection> runtimeCache = new Dictionary, ObservableCollection>(); public ObservableCollection CreateRuntime(ObservableCollection key, string name) { if (!runtimeCache.ContainsKey(key)) { var temp = RunningVar.FromTest(this, name, false, key); runtimeCache[key] = temp; } return runtimeCache[key]; } public event EventHandler NotifyUpdate; private void Resolver_DataChanged(object sender, string e) { NotifyUpdate?.Invoke(this, e); } private ObservableCollection children = new ObservableCollection(); public ObservableCollection Children { get => children; set { Set(ref children, value); } } public void RefreshPlan(TestPlanRun planRun, TestPlan plan, TestStepList list) { if (PlanRun != null) { PlanRun.Resolver.DataChanged -= Resolver_DataChanged; } PlanRun = planRun; PlanRun.Resolver.DataChanged += Resolver_DataChanged; //Dettach(Children[0]); //Dettach(Children[1]); //Dettach(Children[2]); //Children[0] = new RunningVar() //{ // context = this, // Name = ConstNames.LocalsName, // IsArray = false, // Type = TestVariableType.Container, // //Children = RunningVar.FromTest(this, ConstNames.LocalsName, false, list.Variables) // Children = CreateRuntime(list.Variables, ConstNames.LocalsName) //}; //Children[1] = new RunningVar() //{ // context = this, // Name = ConstNames.ParametersName, // IsArray = false, // Type = TestVariableType.Container, // //Children = RunningVar.FromTest(this, ConstNames.ParametersName, false, list.Parameters) // Children = CreateRuntime(list.Parameters, ConstNames.ParametersName) //}; Children[0].Children = CreateRuntime(list.Variables, ConstNames.LocalsName); Children[1].Children = CreateRuntime(list.Parameters, ConstNames.ParametersName); Children[2].Children = CreateRuntime(plan.Variables, ConstNames.FileGlobalsName); //RunningVar.FromTest(this, ConstNames.FileGlobalsName, false, plan.Variables); NotifyUpdate?.Invoke(this, RunningVar.ALL); } private void Dettach(object runVar) { if (runVar is IEnumerable list) { if (list == null || list.Count() <= 0) { return; } foreach (var data in list) { Dettach(data); } } else if (runVar is RunningVar rVar) { rVar.Dettach(this); Dettach(rVar.Children); } } public void Release() { if (PlanRun != null) { PlanRun.Resolver.DataChanged -= Resolver_DataChanged; } Dettach(Children); foreach (var val in runtimeCache.Values) { Dettach(val); } runtimeCache.Clear(); } } public class RunningVar : NotifyBase { internal const string ALL = "*"; internal RunningVarContext context; private string id; private void VariableResolver_DataChanged(object? sender, string e) { //if (e == ALL || e.Contains(id)) //{ //} Set(nameof(Value)); } private string name; public string Name { get => name; set { Set(ref name, value); } } public bool IsArray { get; set; } private TestVariableType type; public TestVariableType Type { get => type; set { Set(ref type, value); } } private string contextName; public string ContextName { get => contextName; set { Set(ref contextName, value); Set(nameof(Title)); } } public string Title { get { if (string.IsNullOrEmpty(ContextName)) return Name; return $"{Name} ({ContextName})"; } set { Set(ref name, value); Set(nameof(Title)); } } public string Value { get { if (IsArray || Type == TestVariableType.Container) { return null; } return context.PlanRun.Resolver.Resolve(context.PlanRun, null, id)?.ToString(); } set { if (GetValue(value, out var v)) { context.PlanRun.Resolver.Update(context.PlanRun, null, id, v); } } } private ObservableCollection children = new ObservableCollection(); public ObservableCollection Children { get => children; set { Set(ref children, value); } } public bool GetValue(string valueStr, out dynamic value) { value = null; if (IsArray) { return false; } if (Type == TestVariableType.Container || Type == TestVariableType.Refrence) { return false; } try { switch (this.Type) { case TestVariableType.String: value = valueStr; return true; case TestVariableType.Int: value = new NumberData(valueStr); return true; case TestVariableType.Double: value = new NumberData(valueStr); return true; case TestVariableType.Bool: value = bool.Parse(valueStr); return true; default: return false; } } catch (Exception ex) { return false; } } public void Dettach(RunningVarContext context) { context.NotifyUpdate -= this.VariableResolver_DataChanged; } public static ObservableCollection FromTest(RunningVarContext context, string parentKey, bool parentIsArray, ObservableCollection testVars) { ObservableCollection result = new ObservableCollection(); foreach (var tv in testVars) { var rv = FromTest(context, parentKey, parentIsArray, tv); result.Add(rv); } return result; } public static RunningVar FromTest(RunningVarContext context, string parentId, bool parentIsArray, TestVariable testVar) { var runningVar = new RunningVar(); runningVar.context = context; context.NotifyUpdate += runningVar.VariableResolver_DataChanged; if (string.IsNullOrEmpty(parentId)) { runningVar.id = testVar.Name; } else { if (parentIsArray) { runningVar.id = parentId + testVar.Name; } else { runningVar.id = parentId + "." + testVar.Name; } } runningVar.Name = testVar.Name; runningVar.IsArray = testVar.IsArray; runningVar.Type = testVar.Type; if (testVar.Children != null) { runningVar.Children = FromTest(context, runningVar.id, runningVar.IsArray, testVar.Children); } return runningVar; } } }