Free cookie consent management tool by TermsFeed Policy Generator

source: branches/GeneralizedQAP/HeuristicLab.Operators.Views.GraphVisualization/3.3/OperatorGraphVisualization/OperatorGraphVisualizationInfo.cs @ 6685

Last change on this file since 6685 was 6685, checked in by abeham, 13 years ago

#1628

  • Updated branch from trunk
  • Changed ReferenceEqualityComparer<T> to become a non-generic class (generic implementation probably was only made because of lacking support for co- and contravariance in C# 3.5)
  • Added finished experiment from sample algorithms to the tests
  • Wrote a unit test to instantiate every IDeepCloneable type, clone it and compare the objects in the object graph for equal references
  • Wrote a unit test to load the experiment, clone it and compare again the objects in the object graph
  • Preliminary fix for a potential bug in ThreadSafeLog
  • Preliminary fix for a potential bug in OperatorGraphVisualizationInfo
  • Preliminary fix for a potential bug in Calculator (and added license headers)
  • Preliminary fix for a potential bug in ScrambleMove
File size: 20.8 KB
Line 
1#region License Information
2/* HeuristicLab
3 * Copyright (C) 2002-2011 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.Drawing;
25using System.Linq;
26using HeuristicLab.Collections;
27using HeuristicLab.Common;
28using HeuristicLab.Core;
29using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
30
31namespace HeuristicLab.Operators.Views.GraphVisualization {
32  [StorableClass]
33  public sealed class OperatorGraphVisualizationInfo : GraphVisualizationInfo {
34    [Storable]
35    private BidirectionalLookup<IOperator, IOperatorShapeInfo> operatorShapeInfoMapping;
36    private BidirectionalLookup<IOperator, IKeyedItemCollection<string, IParameter>> operatorParameterCollectionMapping;
37    private Dictionary<IParameter, IOperator> parameterOperatorMapping;
38
39    private OperatorGraphVisualizationInfo()
40      : base() {
41      this.operatorShapeInfoMapping = new BidirectionalLookup<IOperator, IOperatorShapeInfo>();
42      this.operatorParameterCollectionMapping = new BidirectionalLookup<IOperator, IKeyedItemCollection<string, IParameter>>();
43      this.parameterOperatorMapping = new Dictionary<IParameter, IOperator>();
44    }
45
46    [StorableConstructor]
47    private OperatorGraphVisualizationInfo(bool deserializing)
48      : base(deserializing) {
49      this.operatorParameterCollectionMapping = new BidirectionalLookup<IOperator, IKeyedItemCollection<string, IParameter>>();
50      this.parameterOperatorMapping = new Dictionary<IParameter, IOperator>();
51    }
52    private OperatorGraphVisualizationInfo(OperatorGraphVisualizationInfo original, Cloner cloner)
53      : base(original, cloner) {
54      operatorShapeInfoMapping = new BidirectionalLookup<IOperator, IOperatorShapeInfo>();
55      operatorParameterCollectionMapping = new BidirectionalLookup<IOperator, IKeyedItemCollection<string, IParameter>>();
56      parameterOperatorMapping = new Dictionary<IParameter, IOperator>();
57
58      operatorGraph = cloner.Clone(original.operatorGraph);
59      RegisterOperatorGraphEvents();
60      oldInitialShape = cloner.Clone(original.oldInitialShape);
61      oldInitialShapeColor = original.oldInitialShapeColor;
62
63      foreach (KeyValuePair<IOperator, IOperatorShapeInfo> pair in original.operatorShapeInfoMapping.FirstEnumerable) {
64        IOperator op = cloner.Clone(pair.Key);
65        IOperatorShapeInfo shapeInfo = cloner.Clone(pair.Value);
66        RegisterOperatorEvents(op);
67        operatorParameterCollectionMapping.Add(op, op.Parameters);
68        operatorShapeInfoMapping.Add(op, shapeInfo);
69      }
70
71      foreach (IOperator oper in operatorShapeInfoMapping.FirstValues) {
72        foreach (IParameter param in oper.Parameters) {
73          parameterOperatorMapping.Add(param, oper);
74          IValueParameter opParam = param as IValueParameter;
75          if (opParam != null && typeof(IOperator).IsAssignableFrom(param.DataType))
76            RegisterOperatorParameterEvents(opParam);
77          else
78            RegisterParameterEvents(param);
79        }
80      }
81    }
82    public override IDeepCloneable Clone(Cloner cloner) {
83      return new OperatorGraphVisualizationInfo(this, cloner);
84    }
85
86    public OperatorGraphVisualizationInfo(OperatorGraph operatorGraph)
87      : this() {
88      this.operatorGraph = operatorGraph;
89      this.RegisterOperatorGraphEvents();
90
91      foreach (IOperator op in operatorGraph.Operators)
92        if (!this.operatorShapeInfoMapping.ContainsFirst(op))  //could be added by referencing parameters
93          this.AddOperator(op);
94
95      this.UpdateInitialShape();
96    }
97
98    [StorableHook(HookType.AfterDeserialization)]
99    private void AfterDeserialization() {
100      this.operatorGraph.DeserializationFinished += new EventHandler(operatorGraph_DeserializationFinished);
101      if (oldInitialShapeColor.IsEmpty) oldInitialShapeColor = Color.LightBlue;
102
103      IOperator op;
104      IOperatorShapeInfo shapeInfo;
105      foreach (KeyValuePair<IOperator, IOperatorShapeInfo> pair in this.operatorShapeInfoMapping.FirstEnumerable) {
106        op = pair.Key;
107        shapeInfo = pair.Value;
108        shapeInfo.Icon = new Bitmap(op.ItemImage);
109        this.RegisterOperatorEvents(op);
110        this.operatorParameterCollectionMapping.Add(op, op.Parameters);
111      }
112
113      foreach (IOperator oper in this.operatorShapeInfoMapping.FirstValues) {
114        foreach (IParameter param in oper.Parameters) {
115          IValueParameter opParam = param as IValueParameter;
116          this.parameterOperatorMapping.Add(param, oper);
117          if (opParam != null && typeof(IOperator).IsAssignableFrom(param.DataType))
118            this.RegisterOperatorParameterEvents(opParam);
119          else
120            this.RegisterParameterEvents(param);
121        }
122      }
123    }
124
125    private void operatorGraph_DeserializationFinished(object sender, EventArgs e) {
126      this.RegisterOperatorGraphEvents();
127      this.operatorGraph.DeserializationFinished -= new EventHandler(operatorGraph_DeserializationFinished);
128    }
129
130    public IOperator GetOperatorForShapeInfo(IOperatorShapeInfo shapeInfo) {
131      return this.operatorShapeInfoMapping.GetBySecond(shapeInfo);
132    }
133
134    private void operatorGraph_InitialOperatorChanged(object sender, EventArgs e) {
135      this.UpdateInitialShape();
136    }
137
138    private void UpdateInitialShape() {
139      IOperatorShapeInfo old = this.oldInitialShape as OperatorShapeInfo;
140      if (old != null)
141        old.Color = oldInitialShapeColor;
142
143      OperatorShapeInfo newInitialShapeInfo = this.InitialShape as OperatorShapeInfo;
144      if (newInitialShapeInfo != null) {
145        oldInitialShapeColor = newInitialShapeInfo.Color;
146        newInitialShapeInfo.Color = Color.LightGreen;
147      }
148
149      oldInitialShape = this.InitialShape;
150      this.OnInitialShapeChanged();
151    }
152
153    private IShapeInfo oldInitialShape;
154    [Storable]
155    private Color oldInitialShapeColor;
156    public override IShapeInfo InitialShape {
157      get {
158        IOperator op = this.operatorGraph.InitialOperator;
159        if (op == null) return null;
160        return this.operatorShapeInfoMapping.GetByFirst(op);
161      }
162      set {
163        if (value == null)
164          this.OperatorGraph.InitialOperator = null;
165        else {
166          this.oldInitialShape = InitialShape;
167          IOperatorShapeInfo shapeInfo = (IOperatorShapeInfo)value;
168          this.OperatorGraph.InitialOperator = this.operatorShapeInfoMapping.GetBySecond(shapeInfo);
169        }
170      }
171    }
172
173    [Storable]
174    private OperatorGraph operatorGraph;
175    public OperatorGraph OperatorGraph {
176      get { return this.operatorGraph; }
177    }
178
179    private void RegisterOperatorGraphEvents() {
180      if (this.operatorGraph != null) {
181        this.operatorGraph.InitialOperatorChanged += new EventHandler(operatorGraph_InitialOperatorChanged);
182        this.operatorGraph.Operators.ItemsAdded += new HeuristicLab.Collections.CollectionItemsChangedEventHandler<IOperator>(Operators_ItemsAdded);
183        this.operatorGraph.Operators.ItemsRemoved += new HeuristicLab.Collections.CollectionItemsChangedEventHandler<IOperator>(Operators_ItemsRemoved);
184        this.operatorGraph.Operators.CollectionReset += new HeuristicLab.Collections.CollectionItemsChangedEventHandler<IOperator>(Operators_CollectionReset);
185      }
186    }
187
188    private void DeregisterOperatorGraphEvents() {
189      if (this.operatorGraph != null) {
190        this.operatorGraph.InitialOperatorChanged -= new EventHandler(operatorGraph_InitialOperatorChanged);
191        this.operatorGraph.Operators.ItemsAdded -= new HeuristicLab.Collections.CollectionItemsChangedEventHandler<IOperator>(Operators_ItemsAdded);
192        this.operatorGraph.Operators.ItemsRemoved -= new HeuristicLab.Collections.CollectionItemsChangedEventHandler<IOperator>(Operators_ItemsRemoved);
193        this.operatorGraph.Operators.CollectionReset -= new HeuristicLab.Collections.CollectionItemsChangedEventHandler<IOperator>(Operators_CollectionReset);
194      }
195    }
196
197    #region methods to manipulate operatorgraph by the shape info
198    public void AddShapeInfo(IOperator op, IOperatorShapeInfo shapeInfo) {
199      this.RegisterOperatorEvents(op);
200      this.operatorParameterCollectionMapping.Add(op, op.Parameters);
201      this.operatorShapeInfoMapping.Add(op, shapeInfo);
202      this.shapeInfos.Add(shapeInfo);
203
204      foreach (IParameter param in op.Parameters)
205        this.AddParameter(op, param);
206
207      this.operatorGraph.Operators.Add(op);
208    }
209
210    public override void RemoveShapeInfo(IShapeInfo shapeInfo) {
211      IOperatorShapeInfo opShapeInfo = (IOperatorShapeInfo)shapeInfo;
212      if (this.operatorShapeInfoMapping.ContainsSecond(opShapeInfo)) {
213        IOperator op = this.operatorShapeInfoMapping.GetBySecond(opShapeInfo);
214        this.operatorGraph.Operators.Remove(op);
215      }
216    }
217
218    public override void RemoveConnectionInfo(IConnectionInfo connectionInfo) {
219      IOperatorShapeInfo shapeInfo = (IOperatorShapeInfo)connectionInfo.From;
220      IOperator op = this.operatorShapeInfoMapping.GetBySecond(shapeInfo);
221      IValueParameter param = (IValueParameter)op.Parameters[connectionInfo.ConnectorFrom];
222      param.Value = null;
223    }
224
225    public override void AddConnectionInfo(IConnectionInfo connectionInfo) {
226      IOperatorShapeInfo shapeInfo = (IOperatorShapeInfo)connectionInfo.From;
227      IOperator op = this.operatorShapeInfoMapping.GetBySecond(shapeInfo);
228      IOperatorShapeInfo shapeInfoTo = (IOperatorShapeInfo)connectionInfo.To;
229      IOperator opTo = this.operatorShapeInfoMapping.GetBySecond(shapeInfoTo);
230      IValueParameter param = (IValueParameter)op.Parameters.Where(p => p.Name == connectionInfo.ConnectorFrom).SingleOrDefault();
231      if (param != null)
232        param.Value = opTo;
233    }
234    #endregion
235
236    #region operator events
237    private void AddOperator(IOperator op) {
238      if (!this.operatorShapeInfoMapping.ContainsFirst(op)) {
239        this.RegisterOperatorEvents(op);
240        IOperatorShapeInfo shapeInfo = OperatorShapeInfoFactory.CreateOperatorShapeInfo(op);
241        this.operatorParameterCollectionMapping.Add(op, op.Parameters);
242        this.operatorShapeInfoMapping.Add(op, shapeInfo);
243        this.shapeInfos.Add(shapeInfo);
244        foreach (IParameter param in op.Parameters)
245          this.AddParameter(op, param);
246      }
247    }
248    private void RemoveOperator(IOperator op) {
249      this.DeregisterOperatorEvents(op);
250      foreach (IParameter param in op.Parameters)
251        this.RemoveParameter(op, param);
252
253      IOperatorShapeInfo shapeInfo = this.operatorShapeInfoMapping.GetByFirst(op);
254      this.operatorParameterCollectionMapping.RemoveByFirst(op);
255      this.operatorShapeInfoMapping.RemoveByFirst(op);
256      this.shapeInfos.Remove(shapeInfo);
257    }
258
259    private void OperatorBreakpointChanged(object sender, EventArgs e) {
260      IOperator op = (IOperator)sender;
261      IOperatorShapeInfo operatorShapeInfo = this.operatorShapeInfoMapping.GetByFirst(op);
262      if (op.Breakpoint) {
263        operatorShapeInfo.LineColor = Color.Red;
264        operatorShapeInfo.LineWidth = 2;
265      } else {
266        operatorShapeInfo.LineColor = Color.Black;
267        operatorShapeInfo.LineWidth = 1;
268      }
269    }
270
271    private void OperatorItemImageChanged(object sender, EventArgs e) {
272      IOperator op = (IOperator)sender;
273      IOperatorShapeInfo operatorShapeInfo = this.operatorShapeInfoMapping.GetByFirst(op);
274      operatorShapeInfo.Icon = new Bitmap(op.ItemImage);
275    }
276
277    private void OperatorNameChanged(object sender, EventArgs e) {
278      IOperator op = (IOperator)sender;
279      IOperatorShapeInfo operatorShapeInfo = this.operatorShapeInfoMapping.GetByFirst(op);
280      operatorShapeInfo.Title = op.Name;
281    }
282
283    private void Operators_ItemsAdded(object sender, HeuristicLab.Collections.CollectionItemsChangedEventArgs<IOperator> e) {
284      foreach (IOperator op in e.Items)
285        this.AddOperator(op);
286    }
287    private void Operators_ItemsRemoved(object sender, HeuristicLab.Collections.CollectionItemsChangedEventArgs<IOperator> e) {
288      foreach (IOperator op in e.Items)
289        this.RemoveOperator(op);
290    }
291    private void Operators_CollectionReset(object sender, HeuristicLab.Collections.CollectionItemsChangedEventArgs<IOperator> e) {
292      foreach (IOperator op in e.OldItems)
293        this.RemoveOperator(op);
294      foreach (IOperator op in e.Items)
295        this.AddOperator(op);
296    }
297
298    private void RegisterOperatorEvents(IOperator op) {
299      op.Parameters.ItemsAdded += new CollectionItemsChangedEventHandler<IParameter>(Parameters_ItemsAdded);
300      op.Parameters.ItemsRemoved += new CollectionItemsChangedEventHandler<IParameter>(Parameters_ItemsRemoved);
301      op.Parameters.ItemsReplaced += new CollectionItemsChangedEventHandler<IParameter>(Parameters_ItemsReplaced);
302      op.Parameters.CollectionReset += new CollectionItemsChangedEventHandler<IParameter>(Parameters_CollectionReset);
303      op.NameChanged += new EventHandler(OperatorNameChanged);
304      op.ItemImageChanged += new EventHandler(OperatorItemImageChanged);
305      op.BreakpointChanged += new EventHandler(OperatorBreakpointChanged);
306    }
307
308    private void DeregisterOperatorEvents(IOperator op) {
309      op.Parameters.ItemsAdded -= new CollectionItemsChangedEventHandler<IParameter>(Parameters_ItemsAdded);
310      op.Parameters.ItemsRemoved -= new CollectionItemsChangedEventHandler<IParameter>(Parameters_ItemsRemoved);
311      op.Parameters.ItemsReplaced -= new CollectionItemsChangedEventHandler<IParameter>(Parameters_ItemsReplaced);
312      op.Parameters.CollectionReset -= new CollectionItemsChangedEventHandler<IParameter>(Parameters_CollectionReset);
313      op.NameChanged -= new EventHandler(OperatorNameChanged);
314      op.ItemImageChanged -= new EventHandler(OperatorItemImageChanged);
315      op.BreakpointChanged -= new EventHandler(OperatorBreakpointChanged);
316    }
317    #endregion
318
319    #region parameter events
320    private void AddParameter(IOperator op, IParameter param) {
321      this.parameterOperatorMapping.Add(param, op);
322      IValueParameter opParam = param as IValueParameter;
323      if (opParam != null && typeof(IOperator).IsAssignableFrom(param.DataType)) {
324        this.RegisterOperatorParameterEvents(opParam);
325        IOperatorShapeInfo shapeInfoFrom = this.operatorShapeInfoMapping.GetByFirst(op);
326        shapeInfoFrom.AddConnector(param.Name);
327
328        if (opParam.Value != null) {
329          if (!this.operatorShapeInfoMapping.ContainsFirst((IOperator)opParam.Value))
330            this.AddOperator((IOperator)opParam.Value);
331          IOperatorShapeInfo shapeInfoTo = this.operatorShapeInfoMapping.GetByFirst((IOperator)opParam.Value);
332          this.connectionInfos.Add(new ConnectionInfo(shapeInfoFrom, param.Name, shapeInfoTo, OperatorShapeInfoFactory.PredecessorConnector));
333        }
334      } else
335        this.RegisterParameterEvents(param);
336    }
337
338    private void RemoveParameter(IOperator op, IParameter param) {
339      IValueParameter opParam = param as IValueParameter;
340      if (opParam != null && typeof(IOperator).IsAssignableFrom(param.DataType)) {
341        this.DeregisterOperatorParameterEvents(opParam);
342        IOperatorShapeInfo shapeInfo = this.operatorShapeInfoMapping.GetByFirst(op);
343        this.connectionInfos.RemoveWhere(c => c.From == shapeInfo && c.ConnectorFrom == param.Name);
344        this.connectionInfos.RemoveWhere(c => c.To == shapeInfo && c.ConnectorTo == param.Name);
345        shapeInfo.RemoveConnector(param.Name);
346      } else
347        this.DeregisterParameterEvents(param);
348
349      this.parameterOperatorMapping.Remove(param);
350    }
351
352    private void opParam_ValueChanged(object sender, EventArgs e) {
353      IValueParameter opParam = (IValueParameter)sender;
354      if (this.parameterOperatorMapping.ContainsKey(opParam)) {
355        IOperator op = this.parameterOperatorMapping[opParam];
356        IOperatorShapeInfo shapeInfoFrom = this.operatorShapeInfoMapping.GetByFirst(op);
357        KeyValuePair<IOperatorShapeInfo, string> connectionFrom = new KeyValuePair<IOperatorShapeInfo, string>(shapeInfoFrom, opParam.Name);
358
359        this.connectionInfos.RemoveWhere(c => c.From == shapeInfoFrom && c.ConnectorFrom == opParam.Name);
360        if (opParam.Value != null) {
361          if (!this.operatorShapeInfoMapping.ContainsFirst((IOperator)opParam.Value))
362            this.AddOperator((IOperator)opParam.Value);
363          IOperatorShapeInfo shapeInfoTo = this.operatorShapeInfoMapping.GetByFirst((IOperator)opParam.Value);
364          base.AddConnectionInfo(new ConnectionInfo(shapeInfoFrom, opParam.Name, shapeInfoTo, OperatorShapeInfoFactory.PredecessorConnector));
365        }
366      }
367    }
368
369    private void Parameters_ItemsAdded(object sender, CollectionItemsChangedEventArgs<IParameter> e) {
370      IKeyedItemCollection<string, IParameter> parameterCollection = sender as IKeyedItemCollection<string, IParameter>;
371      IOperator op = this.operatorParameterCollectionMapping.GetBySecond(parameterCollection);
372      foreach (IParameter param in e.Items)
373        AddParameter(op, param);
374      this.UpdateParameterLabels(op);
375    }
376    private void Parameters_ItemsRemoved(object sender, CollectionItemsChangedEventArgs<IParameter> e) {
377      IKeyedItemCollection<string, IParameter> parameterCollection = sender as IKeyedItemCollection<string, IParameter>;
378      IOperator op = this.operatorParameterCollectionMapping.GetBySecond(parameterCollection);
379      foreach (IParameter param in e.Items)
380        RemoveParameter(op, param);
381      this.UpdateParameterLabels(op);
382    }
383    private void Parameters_ItemsReplaced(object sender, CollectionItemsChangedEventArgs<IParameter> e) {
384      IKeyedItemCollection<string, IParameter> parameterCollection = sender as IKeyedItemCollection<string, IParameter>;
385      IOperator op = this.operatorParameterCollectionMapping.GetBySecond(parameterCollection);
386      foreach (IParameter param in e.OldItems)
387        RemoveParameter(op, param);
388      foreach (IParameter param in e.Items)
389        AddParameter(op, param);
390      this.UpdateParameterLabels(op);
391    }
392    private void Parameters_CollectionReset(object sender, CollectionItemsChangedEventArgs<IParameter> e) {
393      IKeyedItemCollection<string, IParameter> parameterCollection = sender as IKeyedItemCollection<string, IParameter>;
394      IOperator op = this.operatorParameterCollectionMapping.GetBySecond(parameterCollection);
395      foreach (IParameter param in e.OldItems)
396        RemoveParameter(op, param);
397      foreach (IParameter param in e.Items)
398        AddParameter(op, param);
399      this.UpdateParameterLabels(op);
400    }
401
402    private void RegisterOperatorParameterEvents(IValueParameter opParam) {
403      opParam.ValueChanged += new EventHandler(opParam_ValueChanged);
404    }
405    private void DeregisterOperatorParameterEvents(IValueParameter opParam) {
406      opParam.ValueChanged -= new EventHandler(opParam_ValueChanged);
407    }
408    private void RegisterParameterEvents(IParameter param) {
409      param.ToStringChanged += new EventHandler(param_ToStringChanged);
410      param.NameChanged += new EventHandler(param_NameChanged);
411    }
412    private void DeregisterParameterEvents(IParameter param) {
413      param.ToStringChanged -= new EventHandler(param_ToStringChanged);
414      param.NameChanged -= new EventHandler(param_NameChanged);
415    }
416
417    private void param_NameChanged(object sender, EventArgs e) {
418      IParameter param = (IParameter)sender;
419      IOperator op = this.parameterOperatorMapping[param];
420      this.UpdateParameterLabels(op);
421    }
422    private void param_ToStringChanged(object sender, EventArgs e) {
423      IParameter param = (IParameter)sender;
424      IOperator op = this.parameterOperatorMapping[param];
425      this.UpdateParameterLabels(op);
426    }
427
428    private void UpdateParameterLabels(IOperator op) {
429      IEnumerable<IParameter> parameters = op.Parameters.Where(p => !(p is IValueParameter && typeof(IOperator).IsAssignableFrom(p.DataType)));
430      IOperatorShapeInfo operatorShapeInfo = this.operatorShapeInfoMapping.GetByFirst(op);
431      if (parameters.Count() > 0)
432        operatorShapeInfo.UpdateLabels(parameters.Select(p => p.ToString()));
433      else
434        operatorShapeInfo.UpdateLabels(new List<string>());
435    }
436    #endregion
437  }
438}
Note: See TracBrowser for help on using the repository browser.