Free cookie consent management tool by TermsFeed Policy Generator

source: trunk/sources/HeuristicLab.Optimization/3.3/RunCollection.cs @ 4375

Last change on this file since 4375 was 4375, checked in by mkommend, 14 years ago

Added registration of EventHandlers after deserialization (ticket #1184).

File size: 13.9 KB
Line 
1#region License Information
2/* HeuristicLab
3 * Copyright (C) 2002-2010 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.Collections.Generic;
24using System.Linq;
25using HeuristicLab.Collections;
26using HeuristicLab.Common;
27using HeuristicLab.Core;
28using HeuristicLab.Data;
29using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
30
31namespace HeuristicLab.Optimization {
32  [Item("Run Collection", "Represents a collection of runs.")]
33  [Creatable("Testing & Analysis")]
34  [StorableClass]
35  public class RunCollection : ItemCollection<IRun>, IStringConvertibleMatrix {
36    [StorableConstructor]
37    protected RunCollection(bool deserializing) : base(deserializing) { }
38    public RunCollection() : base() { Initialize(); }
39    public RunCollection(int capacity) : base(capacity) { Initialize(); }
40    public RunCollection(IEnumerable<IRun> collection) : base(collection) { Initialize(); this.OnItemsAdded(collection); }
41    private void Initialize() {
42      parameterNames = new List<string>();
43      resultNames = new List<string>();
44      dataTypes = new Dictionary<string, HashSet<Type>>();
45      constraints = new RunCollectionConstraintCollection();
46      RegisterConstraintsEvents();
47    }
48
49    [Storable]
50    private Dictionary<string, HashSet<Type>> dataTypes;
51    public IEnumerable<Type> GetDataType(string columnName) {
52      if (!dataTypes.ContainsKey(columnName))
53        return new Type[0];
54      return dataTypes[columnName];
55    }
56
57    [Storable]
58    private RunCollectionConstraintCollection constraints;
59    public RunCollectionConstraintCollection Constraints {
60      get { return constraints; }
61    }
62
63    protected override void OnCollectionReset(IEnumerable<IRun> items, IEnumerable<IRun> oldItems) {
64      parameterNames.Clear();
65      resultNames.Clear();
66      foreach (IRun run in items) {
67        foreach (KeyValuePair<string, IItem> parameter in run.Parameters)
68          AddParameter(parameter.Key, parameter.Value);
69        foreach (KeyValuePair<string, IItem> result in run.Results)
70          AddResult(result.Key, result.Value);
71      }
72      base.OnCollectionReset(items, oldItems);
73      OnReset();
74      columnNameCache = null;
75      OnColumnNamesChanged();
76      rowNamesCache = null;
77      OnRowNamesChanged();
78    }
79    protected override void OnItemsAdded(IEnumerable<IRun> items) {
80      bool columnNamesChanged = false;
81      foreach (IRun run in items) {
82        foreach (KeyValuePair<string, IItem> parameter in run.Parameters)
83          columnNamesChanged |= AddParameter(parameter.Key, parameter.Value);
84        foreach (KeyValuePair<string, IItem> result in run.Results)
85          columnNamesChanged |= AddResult(result.Key, result.Value);
86      }
87      base.OnItemsAdded(items);
88      OnReset();
89      if (columnNamesChanged) {
90        columnNameCache = null;
91        OnColumnNamesChanged();
92      }
93      rowNamesCache = null;
94      OnRowNamesChanged();
95      this.UpdateFiltering(false);
96    }
97    protected override void OnItemsRemoved(IEnumerable<IRun> items) {
98      bool columnNamesChanged = false;
99      foreach (IRun run in items) {
100        foreach (string parameterName in run.Parameters.Keys)
101          columnNamesChanged |= RemoveParameterName(parameterName);
102        foreach (string resultName in run.Results.Keys)
103          columnNamesChanged |= RemoveResultName(resultName);
104      }
105      base.OnItemsRemoved(items);
106      OnReset();
107      if (columnNamesChanged) {
108        columnNameCache = null;
109        OnColumnNamesChanged();
110      }
111      rowNamesCache = null;
112      OnRowNamesChanged();
113    }
114
115    private bool AddParameter(string name, IItem value) {
116      if (value == null)
117        return false;
118      if (!parameterNames.Contains(name)) {
119        parameterNames.Add(name);
120        dataTypes[name] = new HashSet<Type>();
121        dataTypes[name].Add(value.GetType());
122        return true;
123      }
124      dataTypes[name].Add(value.GetType());
125      return false;
126    }
127    private bool AddResult(string name, IItem value) {
128      if (value == null)
129        return false;
130      if (!resultNames.Contains(name)) {
131        resultNames.Add(name);
132        dataTypes[name] = new HashSet<Type>();
133        dataTypes[name].Add(value.GetType());
134        return true;
135      }
136      dataTypes[name].Add(value.GetType());
137      return false;
138    }
139    private bool RemoveParameterName(string name) {
140      if (!list.Any(x => x.Parameters.ContainsKey(name))) {
141        parameterNames.Remove(name);
142        return true;
143      }
144      return false;
145    }
146    private bool RemoveResultName(string name) {
147      if (!list.Any(x => x.Results.ContainsKey(name))) {
148        resultNames.Remove(name);
149        return true;
150      }
151      return false;
152    }
153
154    public IItem GetValue(int rowIndex, int columnIndex) {
155      IRun run = this.list[rowIndex];
156      return GetValue(run, columnIndex);
157    }
158
159    public IItem GetValue(IRun run, int columnIndex) {
160      string name = ((IStringConvertibleMatrix)this).ColumnNames.ElementAt(columnIndex);
161      return GetValue(run, name);
162    }
163
164    public IItem GetValue(IRun run, string columnName) {
165      IItem value = null;
166      if (run.Parameters.ContainsKey(columnName))
167        value = run.Parameters[columnName];
168      else if (run.Results.ContainsKey(columnName))
169        value = run.Results[columnName];
170      return value;
171    }
172
173    [StorableHook(HookType.AfterDeserialization)]
174    private void AfterDeserializationHook() {
175      if (constraints == null) constraints = new RunCollectionConstraintCollection();
176      RegisterConstraintsEvents();
177      RegisterConstraintEvents(constraints);
178      UpdateFiltering(true);
179    }
180
181    public override IDeepCloneable Clone(Cloner cloner) {
182      RunCollection clone = (RunCollection)base.Clone(cloner);
183      clone.resultNames = new List<string>(this.resultNames);
184      clone.parameterNames = new List<string>(this.parameterNames);
185      clone.dataTypes = new Dictionary<string, HashSet<Type>>();
186      foreach (string s in this.dataTypes.Keys)
187        clone.dataTypes[s] = new HashSet<Type>(this.dataTypes[s]);
188
189      clone.constraints = new RunCollectionConstraintCollection(this.constraints.Select(x => (IRunCollectionConstraint)cloner.Clone(x)));
190      foreach (IRunCollectionConstraint constraint in clone.constraints)
191        constraint.ConstrainedValue = clone;
192      clone.RegisterConstraintsEvents();
193      clone.RegisterConstraintEvents(clone.constraints);
194
195      clone.UpdateFiltering(true);
196      return clone;
197    }
198
199    #region IStringConvertibleMatrix Members
200    [Storable]
201    private List<string> parameterNames;
202    public IEnumerable<string> ParameterNames {
203      get { return this.parameterNames; }
204    }
205    [Storable]
206    private List<string> resultNames;
207    public IEnumerable<string> ResultNames {
208      get { return this.resultNames; }
209    }
210    int IStringConvertibleMatrix.Rows {
211      get { return this.Count; }
212      set { throw new NotSupportedException(); }
213    }
214    int IStringConvertibleMatrix.Columns {
215      get { return parameterNames.Count + resultNames.Count; }
216      set { throw new NotSupportedException(); }
217    }
218    private List<string> columnNameCache;
219    IEnumerable<string> IStringConvertibleMatrix.ColumnNames {
220      get {
221        if (columnNameCache == null) {
222          columnNameCache = new List<string>(parameterNames);
223          columnNameCache.AddRange(resultNames);
224          columnNameCache.Sort();
225        }
226        return columnNameCache;
227      }
228      set { throw new NotSupportedException(); }
229    }
230    private List<string> rowNamesCache;
231    IEnumerable<string> IStringConvertibleMatrix.RowNames {
232      get {
233        if (rowNamesCache == null)
234          rowNamesCache = list.Select(x => x.Name).ToList();
235        return rowNamesCache;
236      }
237      set { throw new NotSupportedException(); }
238    }
239    bool IStringConvertibleMatrix.SortableView {
240      get { return true; }
241      set { throw new NotSupportedException(); }
242    }
243    bool IStringConvertibleMatrix.ReadOnly {
244      get { return true; }
245    }
246
247    string IStringConvertibleMatrix.GetValue(int rowIndex, int columnIndex) {
248      IItem value = GetValue(rowIndex, columnIndex);
249      if (value == null)
250        return string.Empty;
251      return value.ToString();
252    }
253
254    public event EventHandler<EventArgs<int, int>> ItemChanged;
255    protected virtual void OnItemChanged(int rowIndex, int columnIndex) {
256      if (ItemChanged != null)
257        ItemChanged(this, new EventArgs<int, int>(rowIndex, columnIndex));
258      OnToStringChanged();
259    }
260    public event EventHandler Reset;
261    protected virtual void OnReset() {
262      if (Reset != null)
263        Reset(this, EventArgs.Empty);
264      OnToStringChanged();
265    }
266    public event EventHandler ColumnNamesChanged;
267    protected virtual void OnColumnNamesChanged() {
268      EventHandler handler = ColumnNamesChanged;
269      if (handler != null)
270        handler(this, EventArgs.Empty);
271    }
272    public event EventHandler RowNamesChanged;
273    protected virtual void OnRowNamesChanged() {
274      EventHandler handler = RowNamesChanged;
275      if (handler != null)
276        handler(this, EventArgs.Empty);
277    }
278    public event EventHandler SortableViewChanged;
279    protected virtual void OnSortableViewChanged() {
280      EventHandler handler = SortableViewChanged;
281      if (handler != null)
282        handler(this, EventArgs.Empty);
283    }
284
285    public bool Validate(string value, out string errorMessage) { throw new NotSupportedException(); }
286    public bool SetValue(string value, int rowIndex, int columnIndex) { throw new NotSupportedException(); }
287    #endregion
288
289    #region filtering
290    private void UpdateFiltering(bool reset) {
291      if (reset)
292        list.ForEach(r => r.Visible = true);
293      foreach (IRunCollectionConstraint constraint in this.constraints)
294        constraint.Check();
295    }
296
297    private void RegisterConstraintsEvents() {
298      constraints.ItemsAdded += new CollectionItemsChangedEventHandler<IRunCollectionConstraint>(Constraints_ItemsAdded);
299      constraints.ItemsRemoved += new CollectionItemsChangedEventHandler<IRunCollectionConstraint>(Constraints_ItemsRemoved);
300      constraints.CollectionReset += new CollectionItemsChangedEventHandler<IRunCollectionConstraint>(Constraints_CollectionReset);
301    }
302
303    protected virtual void RegisterConstraintEvents(IEnumerable<IRunCollectionConstraint> constraints) {
304      foreach (IRunCollectionConstraint constraint in constraints) {
305        constraint.ActiveChanged += new EventHandler(Constraint_ActiveChanged);
306        constraint.ConstrainedValueChanged += new EventHandler(Constraint_ConstrainedValueChanged);
307        constraint.ConstraintOperationChanged += new EventHandler(Constraint_ConstraintOperationChanged);
308        constraint.ConstraintDataChanged += new EventHandler(Constraint_ConstraintDataChanged);
309      }
310    }
311    protected virtual void DeregisterConstraintEvents(IEnumerable<IRunCollectionConstraint> constraints) {
312      foreach (IRunCollectionConstraint constraint in constraints) {
313        constraint.ActiveChanged -= new EventHandler(Constraint_ActiveChanged);
314        constraint.ConstrainedValueChanged -= new EventHandler(Constraint_ConstrainedValueChanged);
315        constraint.ConstraintOperationChanged -= new EventHandler(Constraint_ConstraintOperationChanged);
316        constraint.ConstraintDataChanged -= new EventHandler(Constraint_ConstraintDataChanged);
317      }
318    }
319
320    protected virtual void Constraints_CollectionReset(object sender, CollectionItemsChangedEventArgs<IRunCollectionConstraint> e) {
321      DeregisterConstraintEvents(e.OldItems);
322      RegisterConstraintEvents(e.Items);
323      this.UpdateFiltering(true);
324    }
325    protected virtual void Constraints_ItemsAdded(object sender, CollectionItemsChangedEventArgs<IRunCollectionConstraint> e) {
326      RegisterConstraintEvents(e.Items);
327      foreach (IRunCollectionConstraint constraint in e.Items)
328        constraint.ConstrainedValue = this;
329      this.UpdateFiltering(false);
330    }
331    protected virtual void Constraints_ItemsRemoved(object sender, CollectionItemsChangedEventArgs<IRunCollectionConstraint> e) {
332      DeregisterConstraintEvents(e.Items);
333      this.UpdateFiltering(true);
334    }
335    protected virtual void Constraint_ActiveChanged(object sender, EventArgs e) {
336      IRunCollectionConstraint constraint = (IRunCollectionConstraint)sender;
337      this.UpdateFiltering(!constraint.Active);
338    }
339    protected virtual void Constraint_ConstrainedValueChanged(object sender, EventArgs e) {
340      //mkommend: this method is intentionally left empty, because the constrainedValue is set in the ItemsAdded method
341    }
342    protected virtual void Constraint_ConstraintOperationChanged(object sender, EventArgs e) {
343      IRunCollectionConstraint constraint = (IRunCollectionConstraint)sender;
344      if (constraint.Active)
345        this.UpdateFiltering(true);
346    }
347    protected virtual void Constraint_ConstraintDataChanged(object sender, EventArgs e) {
348      IRunCollectionConstraint constraint = (IRunCollectionConstraint)sender;
349      if (constraint.Active)
350        this.UpdateFiltering(true);
351    }
352    #endregion
353  }
354}
Note: See TracBrowser for help on using the repository browser.