chr
2026-04-05 fe750b791d5b517cc4e9bc8e99a9a75139a0cfba
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
using System.Collections.Generic;
using System.ComponentModel;
using System.Linq;
using System.Xml.Serialization;
 
namespace OpenTap.Plugins.BasicSteps
{
 
    interface ISelectedParameters
    {
        IList<ParameterMemberData> SelectedParameters { get; }
    }
 
    public class MemberDataName
    {
        public string Group;
        public string Name;
 
        public MemberDataName(string name)
        {
            var split = name.Split('\\').Select(x => x.Trim())
                .Where(x => string.IsNullOrWhiteSpace(x) == false).ToArray();
            Name = split.LastOrDefault();
            Group = string.Join(" \\ ", split.Take(split.Length - 1));
        }
 
        public override bool Equals(object obj)
        {
            if (obj is MemberDataName other)
                return other.Name == Name && other.Group == Group;
            return false;
        }
 
        public override int GetHashCode() =>
            (Group?.GetHashCode() ?? 312321) * 73106 + (Name?.GetHashCode() ?? 60362190) * -32032;
 
        public override string ToString() => Name;
    }
    
    public abstract class SweepParameterStepBase : LoopTestStep, ISelectedParameters
    {
        internal IEnumerable<ParameterMemberData> SweepProperties => TypeData.GetTypeData(this)
            .GetMembers().OfType<ParameterMemberData>()
            .Where(p =>  p.IsParameterized(this) == false)
            .Where(x => x.HasAttribute<UnsweepableAttribute>() == false && x.Writable && x.Readable);
 
        internal IEnumerable<ParameterMemberData> SelectedMembers =>
            AvailableParameters.Where(x => Selected.ContainsKey(x.Name) && Selected[x.Name]);
 
        public virtual IEnumerable<ParameterMemberData> AvailableParameters => SweepProperties;
        
        readonly NotifyChangedList<ParameterMemberData> selectedProperties = new NotifyChangedList<ParameterMemberData>();
        
        [Browsable(false)]
        public Dictionary<string, bool> Selected { get; set; } = new Dictionary<string, bool>();
        void updateSelected(bool destructive = false)
        {
            var sweepProperties = AvailableParameters.ToHashSet();
            var sweepProps2 = sweepProperties.ToDictionary(x => x.Name);
            foreach (var prop in sweepProperties)
            {
                if (Selected.ContainsKey(prop.Name) == false)
                    Selected[prop.Name] = true;
            }
            foreach (var item in Selected.ToArray())
            {
                ParameterMemberData prop;
                sweepProps2.TryGetValue(item.Key, out prop);
                if (item.Value && prop != null)
                {
                    
                    if (selectedProperties.Contains(prop) == false)
                        selectedProperties.Add(prop);
                }
                else
                {
                    selectedProperties.RemoveIf(x => x.Name == item.Key);
                }
 
                if (destructive && prop == null)
                {
                    Selected.Remove(item.Key);
                }
            }
        }
 
        void onListChanged(IList<ParameterMemberData> list)
        {
            foreach (var item in Selected.Keys.ToArray())
            {
                Selected[item] = list.Any(x => x.Name == item);
            }
        }
        
        [AvailableValues(nameof(AvailableParameters))]
        [XmlIgnore]
        [Browsable(true)]
        [HideOnMultiSelectAttribute] //TODO: Add support for multi-selecting this property.
        [Unsweepable]
        [Display("Parameters", "These are the parameters that should be swept", "Sweep")]
        public IList<ParameterMemberData> SelectedParameters {
            get
            {
                updateSelected(true);
                selectedProperties.ChangedCallback = onListChanged;
                return selectedProperties;
            }
            set
            {
                updateSelected();
                onListChanged(value);
            } 
        }
 
        public string Parameters
        {
            get
            {
                var names = SelectedParameters.Select(x => x.GetDisplayAttribute().Name);
                return string.Join(", ", names);
            }
        }
 
        public SweepParameterStepBase()
        {
            Rules.Add(() => SelectedParameters.Count > 0, "No parameters selected to sweep", nameof(SelectedParameters));
        }
    }
}