Free cookie consent management tool by TermsFeed Policy Generator

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

Last change on this file was 17695, checked in by abeham, 4 years ago

#2521:

  • Moving solution creator parameter from problems to algorithms (breaking wiring in some HeuristicOptimizationProblems)
  • Disallowing evaluator or encoding changes in encoding-specific base problems (to avoid confusion in derived problems whether this needs to be handled or not)
  • Added private set to ReferenceParameter property (serialization)
File size: 9.1 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] public IValueParameter ReferencedParameter { get; private set; }
45
46    [Storable(DefaultValue = true)]
47    private bool readOnly;
48    public bool ReadOnly {
49      get { return readOnly; }
50      set {
51        if (value != readOnly) {
52          readOnly = value;
53          OnReadOnlyChanged();
54        }
55      }
56    }
57
58
59    [Storable(DefaultValue = true)]
60    private bool getsCollected;
61    public bool GetsCollected {
62      get { return getsCollected; }
63      set {
64        if (value != getsCollected) {
65          getsCollected = value;
66          OnGetsCollectedChanged();
67        }
68      }
69    }
70
71    protected ReferenceParameter(IValueParameter referencedParameter) : this(referencedParameter.Name, referencedParameter) { }
72    protected ReferenceParameter(string name, IValueParameter referencedParameter) : this(name, referencedParameter.Description, referencedParameter) { }
73    protected ReferenceParameter(string name, string description, IValueParameter referencedParameter) : this(name, description, referencedParameter, referencedParameter.DataType) { }
74    protected ReferenceParameter(string name, string description, IValueParameter referencedParameter, Type dataType) : base(name, description, dataType) {
75      ReferencedParameter = referencedParameter ?? throw new ArgumentNullException("referencedParameter");
76      RegisterEvents();
77    }
78
79    [StorableConstructor]
80    protected ReferenceParameter(StorableConstructorFlag _) : base(_) { }
81
82    [StorableHook(HookType.AfterDeserialization)]
83    private void AfterDeserialization() {
84      RegisterEvents();
85    }
86
87    protected ReferenceParameter(ReferenceParameter original, Cloner cloner) : base(original, cloner) {
88      ReferencedParameter = cloner.Clone(original.ReferencedParameter);
89      ReadOnly = original.ReadOnly;
90      GetsCollected = original.GetsCollected;
91
92      RegisterEvents();
93    }
94
95    private void RegisterEvents() {
96      ReferencedParameter.ToStringChanged += (o, e) => OnToStringChanged();
97      ReferencedParameter.ItemImageChanged += (o, e) => OnItemImageChanged();
98    }
99
100    protected override IItem GetActualValue() {
101      return ReferencedParameter.ActualValue;
102    }
103    protected override void SetActualValue(IItem value) {
104      ReferencedParameter.ActualValue = value;
105    }
106
107    public override string ToString() {
108      return Name + ": " + (Value != null ? Value.ToString() : "null");
109    }
110
111    // TODO: Remove
112    //protected void ChangeReference(IValueParameter newReference, bool retainData) {
113    //  IItem oldValue = Value;
114    //  var oldRef = ReferencedParameter;
115    //  oldRef.ToStringChanged -= (o, e) => OnToStringChanged();
116    //  oldRef.ItemImageChanged -= (o, e) => OnItemImageChanged();
117    //  if (valueChanged != null) oldRef.ValueChanged -= OnReferencedParameterValueChanged;
118    //  newReference.ToStringChanged += (o, e) => OnToStringChanged();
119    //  newReference.ItemImageChanged += (o, e) => OnItemImageChanged();
120    //  if (valueChanged != null) newReference.ValueChanged += OnReferencedParameterValueChanged;
121    //  ReferencedParameter = newReference;
122    //  oldRef.Value = (IItem)oldValue.Clone(); // This is problematic, e.g. FixedValueParameter !!! But necessary, otherwise the value holds reference to the old parameter
123    //  if (retainData) Value = oldValue;
124    //}
125
126
127    #region event handlers
128    // code for forwarding of events adapted from https://stackoverflow.com/questions/1065355/forwarding-events-in-c-sharp
129    private EventHandler valueChanged;
130    public event EventHandler ValueChanged {
131      add { // only subscribe when we have a subscriber ourselves
132        bool firstSubscription = valueChanged == null;
133        valueChanged += value;
134        if (firstSubscription && valueChanged != null) //only subscribe once
135          ReferencedParameter.ValueChanged += OnReferencedParameterValueChanged;
136      }
137      remove { // unsubscribe if we have no more subscribers
138        valueChanged -= value;
139        if (valueChanged == null) ReferencedParameter.ValueChanged -= OnReferencedParameterValueChanged;
140      }
141    }
142    private void OnReferencedParameterValueChanged(object sender, EventArgs args) {
143      valueChanged?.Invoke(this, args); // note "this", not "sender" as sender would be the referenced parameter
144      OnItemImageChanged();
145      OnToStringChanged();
146    }
147
148    public event EventHandler ReadOnlyChanged;
149    private void OnReadOnlyChanged() {
150      ReadOnlyChanged?.Invoke(this, EventArgs.Empty);
151    }
152
153    public event EventHandler GetsCollectedChanged;
154    private void OnGetsCollectedChanged() {
155      GetsCollectedChanged?.Invoke(this, EventArgs.Empty);
156    }
157    #endregion
158  }
159
160
161  [Item("ReferenceParameter", "ValueParameter<T> that forwards to another (referenced) ValueParameter<T>).")]
162  [StorableType("6DD59BE5-C618-4AD4-90FE-0FAAF15650C3")]
163  public sealed class ReferenceParameter<T> : ReferenceParameter, IValueParameter<T>
164    where T : class, IItem {
165
166    public new T Value {
167      get => ReferencedParameter.Value;
168      set => ReferencedParameter.Value = value;
169    }
170
171    public new IValueParameter<T> ReferencedParameter { get => (IValueParameter<T>)base.ReferencedParameter; }
172
173    public ReferenceParameter(IValueParameter<T> referencedParameter) : this(referencedParameter.Name, referencedParameter) { }
174    public ReferenceParameter(string name, IValueParameter<T> referencedParameter) : this(name, referencedParameter.Description, referencedParameter) { }
175    public ReferenceParameter(string name, string description, IValueParameter<T> referencedParameter) : base(name, description, referencedParameter) { }
176
177    [StorableConstructor]
178    private ReferenceParameter(StorableConstructorFlag _) : base(_) { }
179    private ReferenceParameter(ReferenceParameter<T> original, Cloner cloner) : base(original, cloner) { }
180
181    public override IDeepCloneable Clone(Cloner cloner) {
182      return new ReferenceParameter<T>(this, cloner);
183    }
184
185    // TODO: Remove
186    //public void ChangeReference(IValueParameter<T> newParameter, bool retainData) {
187    //  base.ChangeReference(newParameter, retainData);
188    //}
189  }
190
191
192  [Item("ReferenceParameter", "ValueParameter<T> that forwards to another (referenced) ValueParameter<U>).")]
193  [StorableType("83FEA704-6AED-4D76-B25A-B469E0E9187A")]
194  public sealed class ReferenceParameter<T, U> : ReferenceParameter, IValueParameter<T>
195    where T : class, U
196    where U : class, IItem {
197
198    public new T Value {
199      get => (T)ReferencedParameter.Value;
200      set => ReferencedParameter.Value = value;
201    }
202
203    public new IValueParameter<U> ReferencedParameter { get => (IValueParameter<U>)base.ReferencedParameter; }
204
205    public ReferenceParameter(IValueParameter<U> referencedParameter) : this(referencedParameter.Name, referencedParameter) { }
206    public ReferenceParameter(string name, IValueParameter<U> referencedParameter) : this(name, referencedParameter.Description, referencedParameter) { }
207    public ReferenceParameter(string name, string description, IValueParameter<U> referencedParameter) : base(name, description, referencedParameter, typeof(T)) { }
208
209    [StorableConstructor]
210    private ReferenceParameter(StorableConstructorFlag _) : base(_) { }
211    private ReferenceParameter(ReferenceParameter<T, U> original, Cloner cloner) : base(original, cloner) { }
212
213    public override IDeepCloneable Clone(Cloner cloner) {
214      return new ReferenceParameter<T, U>(this, cloner);
215    }
216
217    // TODO: Remove
218    //public void ChangeReference(IValueParameter<U> newParameter, bool retainData) {
219    //  base.ChangeReference(newParameter, retainData);
220    //}
221  }
222}
Note: See TracBrowser for help on using the repository browser.