Free cookie consent management tool by TermsFeed Policy Generator

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

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

#2521: fixed encoding change of JSSP, added tostring and itemimage change to ValueChanged event of ReferenceParameter

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