source: branches/2521_ProblemRefactoring/HeuristicLab.Parameters/3.3/ReferenceParameter.cs @ 17532

Last change on this file since 17532 was 17532, checked in by mkommend, 2 years ago

#2521: Added first implementation of new reference parameter and corrected fixed value parameter.

File size: 8.4 KB
Line 
1#region License Information
2/* HeuristicLab
3 * Copyright (C) Heuristic and Evolutionary Algorithms Laboratory (HEAL)
4 *
5 * This file is part of HeuristicLab.
6 *
7 * HeuristicLab is free software: you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation, either version 3 of the License, or
10 * (at your option) any later version.
11 *
12 * HeuristicLab is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15 * GNU General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License
18 * along with HeuristicLab. If not, see <http://www.gnu.org/licenses/>.
19 */
20#endregion
21
22using System;
23using System.Drawing;
24using HEAL.Attic;
25using HeuristicLab.Common;
26using HeuristicLab.Core;
27
28namespace HeuristicLab.Parameters {
29  [Item("ReferenceParameter", "A base class for reference parameters that forward to other (referenced) parameters.")]
30  [StorableType("39CE4123-E41C-4935-90FE-91F6A629178A")]
31  public abstract class ReferenceParameter : Parameter, IValueParameter {
32    public override Image ItemImage {
33      get {
34        if (Value != null) return Value.ItemImage;
35        else return base.ItemImage;
36      }
37    }
38
39    public IItem Value {
40      get => GetActualValue();
41      set => SetActualValue(value);
42    }
43
44    [Storable]
45    public IValueParameter ReferencedParameter { get; }
46
47    public bool ReadOnly {
48      get => ReferencedParameter.ReadOnly;
49      set => ReferencedParameter.ReadOnly = value;
50    }
51
52    [Storable(DefaultValue = true)]
53    private bool getsCollected;
54    public bool GetsCollected {
55      get { return getsCollected; }
56      set {
57        if (value != getsCollected) {
58          getsCollected = value;
59          OnGetsCollectedChanged();
60        }
61      }
62    }
63
64    protected ReferenceParameter(IValueParameter referencedParameter) : this(referencedParameter.Name, referencedParameter) { }
65    protected ReferenceParameter(string name, IValueParameter referencedParameter) : this(name, referencedParameter.Description, referencedParameter) { }
66    protected ReferenceParameter(string name, string description, IValueParameter referencedParameter) : this(name, description, referencedParameter, referencedParameter.DataType) { }
67    protected ReferenceParameter(string name, string description, IValueParameter referencedParameter, Type dataType) : base(name, description, dataType) {
68      ReferencedParameter = referencedParameter ?? throw new ArgumentNullException("referencedParameter");
69      RegisterEvents();
70    }
71
72    [StorableConstructor]
73    protected ReferenceParameter(StorableConstructorFlag _) : base(_) { }
74
75    [StorableHook(HookType.AfterDeserialization)]
76    private void AfterDeserialization() {
77      RegisterEvents();
78    }
79
80    protected ReferenceParameter(ReferenceParameter original, Cloner cloner) : base(original, cloner) {
81      ReferencedParameter = cloner.Clone(original.ReferencedParameter);
82      RegisterEvents();
83    }
84
85    private void RegisterEvents() {
86      ReferencedParameter.ToStringChanged += (o, e) => OnToStringChanged();
87      ReferencedParameter.ItemImageChanged += (o, e) => OnItemImageChanged();
88    }
89
90    protected override IItem GetActualValue() {
91      return ReferencedParameter.ActualValue;
92    }
93    protected override void SetActualValue(IItem value) {
94      ReferencedParameter.ActualValue = value;
95    }
96
97    public override string ToString() {
98      return Name + ": " + (Value != null ? Value.ToString() : "null");
99    }
100
101
102    #region event handlers
103    // code for forwarding of events adapted from https://stackoverflow.com/questions/1065355/forwarding-events-in-c-sharp
104    private EventHandler valueChanged;
105    public event EventHandler ValueChanged {
106      add { // only subscribe when we have a subscriber ourselves
107        bool firstSubscription = valueChanged == null;
108        valueChanged += value;
109        if (firstSubscription && valueChanged != null) //only subscribe once
110          ReferencedParameter.ValueChanged += OnReferencedParameterValueChanged;
111      }
112      remove { // unsubscribe if we have no more subscribers
113        valueChanged -= value;
114        if (valueChanged == null) ReferencedParameter.ValueChanged -= OnReferencedParameterValueChanged;
115      }
116    }
117    private void OnReferencedParameterValueChanged(object sender, EventArgs args) {
118      valueChanged?.Invoke(this, args); // note "this", not "sender" as sender would be the referenced parameter
119    }
120
121    private EventHandler readOnlyChanged;
122    public event EventHandler ReadOnlyChanged {
123      add { // only subscribe when we have a subscriber ourselves
124        bool firstSubscription = readOnlyChanged == null;
125        readOnlyChanged += value;
126        if (firstSubscription && readOnlyChanged != null) //only subscribe once
127          ReferencedParameter.ReadOnlyChanged += OnReferencedParameterReadOnlyChanged;
128      }
129      remove { // unsubscribe if we have no more subscribers
130        readOnlyChanged -= value;
131        if (readOnlyChanged == null) ReferencedParameter.ReadOnlyChanged -= OnReferencedParameterReadOnlyChanged;
132      }
133    }
134    private void OnReferencedParameterReadOnlyChanged(object sender, EventArgs args) {
135      readOnlyChanged?.Invoke(this, args); // note "this", not "sender" as sender would be the referenced parameter
136    }
137
138    public event EventHandler GetsCollectedChanged;
139    private void OnGetsCollectedChanged() {
140      GetsCollectedChanged?.Invoke(this, EventArgs.Empty);
141    }
142    #endregion
143  }
144
145
146  [Item("ReferenceParameter<T>", "ValueParameter<T> that forwards to another (referenced) ValueParameter<T>).")]
147  [StorableType("6DD59BE5-C618-4AD4-90FE-0FAAF15650C3")]
148  public sealed class ReferenceParameter<T> : ReferenceParameter, IValueParameter<T>
149    where T : class, IItem {
150
151    public new T Value {
152      get => ReferencedParameter.Value;
153      set => ReferencedParameter.Value = value;
154    }
155
156    public new IValueParameter<T> ReferencedParameter { get => (IValueParameter<T>)base.ReferencedParameter; }
157
158    public ReferenceParameter(IValueParameter<T> referencedParameter) : this(referencedParameter.Name, referencedParameter) { }
159    public ReferenceParameter(string name, IValueParameter<T> referencedParameter) : this(name, referencedParameter.Description, referencedParameter) { }
160    public ReferenceParameter(string name, string description, IValueParameter<T> referencedParameter) : base(name, description, referencedParameter) { }
161
162    [StorableConstructor]
163    private ReferenceParameter(StorableConstructorFlag _) : base(_) { }
164    private ReferenceParameter(ReferenceParameter<T> original, Cloner cloner) : base(original, cloner) { }
165
166    public override IDeepCloneable Clone(Cloner cloner) {
167      return new ReferenceParameter<T>(this, cloner);
168    }
169
170    public void ForceValue(T value) { ReferencedParameter.ForceValue(value); }
171  }
172
173
174  [Item("ReferenceParameter<T,U>", "ValueParameter<T> that forwards to another (referenced) ValueParameter<U>).")]
175  [StorableType("83FEA704-6AED-4D76-B25A-B469E0E9187A")]
176  public sealed class ReferenceParameter<T, U> : ReferenceParameter, IValueParameter<T>
177    where T : class, U
178    where U : class, IItem {
179
180    public new T Value {
181      get => (T)ReferencedParameter.Value;
182      set => ReferencedParameter.Value = value;
183    }
184
185    public new IValueParameter<U> ReferencedParameter { get => (IValueParameter<U>)base.ReferencedParameter; }
186
187    public ReferenceParameter(IValueParameter<U> referencedParameter) : this(referencedParameter.Name, referencedParameter) { }
188    public ReferenceParameter(string name, IValueParameter<U> referencedParameter) : this(name, referencedParameter.Description, referencedParameter) { }
189    public ReferenceParameter(string name, string description, IValueParameter<U> referencedParameter) : base(name, description, referencedParameter, typeof(T)) { }
190
191    [StorableConstructor]
192    private ReferenceParameter(StorableConstructorFlag _) : base(_) { }
193    private ReferenceParameter(ReferenceParameter<T, U> original, Cloner cloner) : base(original, cloner) { }
194
195    public override IDeepCloneable Clone(Cloner cloner) {
196      return new ReferenceParameter<T, U>(this, cloner);
197    }
198
199    public void ForceValue(T value) { ReferencedParameter.ForceValue(value); }
200  }
201}
Note: See TracBrowser for help on using the repository browser.