Free cookie consent management tool by TermsFeed Policy Generator

source: trunk/sources/HeuristicLab.Core/3.3/OperatorGraph.cs @ 2994

Last change on this file since 2994 was 2994, checked in by epitzer, 14 years ago

Make StorableClass attribute compulsory for StorableSerializer to work, add named property StorableClassType to choose between Empty and MarkedOnly, later other options will be added. (#548)

File size: 10.2 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.Text;
25using System.Xml;
26using System.Linq;
27using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
28using HeuristicLab.Common;
29using HeuristicLab.Collections;
30
31namespace HeuristicLab.Core {
32  /// <summary>
33  /// Represents a graph of operators.
34  /// </summary>
35  [Item("OperatorGraph", "Represents a graph of operators.")]
36  [Creatable("Algorithms")]
37  [StorableClass(StorableClassType.MarkedOnly)]
38  public class OperatorGraph : Item {
39    private OperatorSet operators;
40    /// <summary>
41    /// Gets all operators of the current instance.
42    /// </summary>
43    [Storable]
44    public OperatorSet Operators {
45      get { return operators; }
46      private set {
47        DeregisterOperatorsEvents();
48        operators = value;
49        RegisterOperatorsEvents();
50      }
51    }
52
53    [Storable]
54    private IOperator initialOperator;
55    /// <summary>
56    /// Gets or sets the initial operator (the starting one).
57    /// </summary>
58    /// <remarks>Calls <see cref="OnInitialOperatorChanged"/> in the setter.</remarks>
59    public IOperator InitialOperator {
60      get { return initialOperator; }
61      set {
62        if (initialOperator != value) {
63          if (value != null) Operators.Add(value);
64          initialOperator = value;
65          OnInitialOperatorChanged();
66        }
67      }
68    }
69
70    [Storable]
71    private IDeepCloneable visualizationInfo;
72    /// <summary>
73    /// Gets or sets the visualizationInfo.
74    /// </summary>
75    /// /// <remarks>The VisualizationInfo can only be set once and fires afterwards and InvalidOperationException</remarks>
76    public IDeepCloneable VisualizationInfo {
77      get { return visualizationInfo; }
78      set {
79        if (visualizationInfo != null)
80          throw new InvalidOperationException("The value of the property VisualizationInfo is already set and cannot be set again.");
81        visualizationInfo = value;
82      }
83    }
84
85    /// <summary>
86    /// Initializes a new instance of <see cref="OperatorGraph"/>.
87    /// </summary>
88    public OperatorGraph() {
89      Operators = new OperatorSet();
90      initialOperator = null;
91      visualizationInfo = null;
92    }
93
94    /// <summary>
95    /// Clones the current instance (deep clone).
96    /// </summary>
97    /// <remarks>Deep clone through <see cref="cloner.Clone"/> method of helper class
98    /// <see cref="Auxiliary"/>.</remarks>
99    /// <param name="clonedObjects">Dictionary of all already cloned objects. (Needed to avoid cycles.)</param>
100    /// <returns>The cloned object as <see cref="OperatorGraph"/>.</returns>
101    public override IDeepCloneable Clone(Cloner cloner) {
102      OperatorGraph clone = new OperatorGraph();
103      cloner.RegisterClonedObject(this, clone);
104      clone.Operators = (OperatorSet)cloner.Clone(operators);
105      clone.initialOperator = (IOperator)cloner.Clone(initialOperator);
106      clone.visualizationInfo = cloner.Clone(visualizationInfo);
107      return clone;
108    }
109
110    /// <inheritdoc/>
111    public event EventHandler InitialOperatorChanged;
112    /// <summary>
113    /// Fires a new <c>InitialOperatorChanged</c> event.
114    /// </summary>
115    protected virtual void OnInitialOperatorChanged() {
116      if (InitialOperatorChanged != null)
117        InitialOperatorChanged(this, EventArgs.Empty);
118    }
119
120    #region Operators Events
121    private void AddOperator(IOperator op) {
122      RegisterOperatorEvents(op);
123      foreach (IParameter param in op.Parameters)
124        AddParameter(param);
125    }
126    private void RemoveOperator(IOperator op) {
127      foreach (IParameter param in op.Parameters)
128        RemoveParameter(param);
129      DeregisterOperatorEvents(op);
130
131      // remove edges to removed operator
132      var opParams = from o in Operators
133                     from p in o.Parameters
134                     where p is IValueParameter<IOperator>
135                     where (((IValueParameter<IOperator>)p).Value != null) && (((IValueParameter<IOperator>)p).Value == op)
136                     select (IValueParameter<IOperator>)p;
137      foreach (IValueParameter<IOperator> opParam in opParams)
138        opParam.Value = null;
139    }
140    private void AddParameter(IParameter param) {
141      IValueParameter<IOperator> opParam = param as IValueParameter<IOperator>;
142      if (opParam != null) {
143        RegisterOperatorParameterEvents(opParam);
144        if (opParam.Value != null) Operators.Add(opParam.Value);
145      }
146    }
147    private void RemoveParameter(IParameter param) {
148      IValueParameter<IOperator> opParam = param as IValueParameter<IOperator>;
149      if (opParam != null) {
150        DeregisterOperatorParameterEvents(opParam);
151      }
152    }
153
154    private void RegisterOperatorsEvents() {
155      if (operators != null) {
156        operators.ItemsAdded += new CollectionItemsChangedEventHandler<IOperator>(Operators_ItemsAdded);
157        operators.ItemsRemoved += new CollectionItemsChangedEventHandler<IOperator>(Operators_ItemsRemoved);
158        operators.CollectionReset += new CollectionItemsChangedEventHandler<IOperator>(Operators_CollectionReset);
159        foreach (IOperator op in operators) {
160          RegisterOperatorEvents(op);
161          foreach (IParameter param in op.Parameters) {
162            IValueParameter<IOperator> opParam = param as IValueParameter<IOperator>;
163            if (opParam != null) RegisterOperatorParameterEvents(opParam);
164          }
165        }
166      }
167    }
168    private void DeregisterOperatorsEvents() {
169      if (operators != null) {
170        foreach (IOperator op in operators) {
171          foreach (IParameter param in op.Parameters) {
172            IValueParameter<IOperator> opParam = param as IValueParameter<IOperator>;
173            if (opParam != null) DeregisterOperatorParameterEvents(opParam);
174          }
175          DeregisterOperatorEvents(op);
176        }
177        operators.ItemsAdded -= new CollectionItemsChangedEventHandler<IOperator>(Operators_ItemsAdded);
178        operators.ItemsRemoved -= new CollectionItemsChangedEventHandler<IOperator>(Operators_ItemsRemoved);
179        operators.CollectionReset -= new CollectionItemsChangedEventHandler<IOperator>(Operators_CollectionReset);
180      }
181    }
182    private void RegisterOperatorEvents(IOperator op) {
183      op.Parameters.ItemsAdded += new CollectionItemsChangedEventHandler<IParameter>(Parameters_ItemsAdded);
184      op.Parameters.ItemsRemoved += new CollectionItemsChangedEventHandler<IParameter>(Parameters_ItemsRemoved);
185      op.Parameters.ItemsReplaced += new CollectionItemsChangedEventHandler<IParameter>(Parameters_ItemsReplaced);
186      op.Parameters.CollectionReset += new CollectionItemsChangedEventHandler<IParameter>(Parameters_CollectionReset);
187    }
188    private void DeregisterOperatorEvents(IOperator op) {
189      op.Parameters.ItemsAdded -= new CollectionItemsChangedEventHandler<IParameter>(Parameters_ItemsAdded);
190      op.Parameters.ItemsRemoved -= new CollectionItemsChangedEventHandler<IParameter>(Parameters_ItemsRemoved);
191      op.Parameters.ItemsReplaced -= new CollectionItemsChangedEventHandler<IParameter>(Parameters_ItemsReplaced);
192      op.Parameters.CollectionReset -= new CollectionItemsChangedEventHandler<IParameter>(Parameters_CollectionReset);
193    }
194    private void RegisterOperatorParameterEvents(IValueParameter<IOperator> opParam) {
195      opParam.ValueChanged += new EventHandler(opParam_ValueChanged);
196    }
197    private void DeregisterOperatorParameterEvents(IValueParameter<IOperator> opParam) {
198      opParam.ValueChanged -= new EventHandler(opParam_ValueChanged);
199    }
200
201    private void Operators_ItemsAdded(object sender, CollectionItemsChangedEventArgs<IOperator> e) {
202      foreach (IOperator op in e.Items)
203        AddOperator(op);
204    }
205    private void Operators_ItemsRemoved(object sender, CollectionItemsChangedEventArgs<IOperator> e) {
206      foreach (IOperator op in e.Items)
207        RemoveOperator(op);
208      if (!Operators.Contains(InitialOperator)) InitialOperator = null;
209    }
210    private void Operators_CollectionReset(object sender, CollectionItemsChangedEventArgs<IOperator> e) {
211      foreach (IOperator op in e.OldItems)
212        RemoveOperator(op);
213      foreach (IOperator op in e.Items)
214        AddOperator(op);
215      if (!Operators.Contains(InitialOperator)) InitialOperator = null;
216    }
217    private void Parameters_ItemsAdded(object sender, CollectionItemsChangedEventArgs<IParameter> e) {
218      foreach (IParameter param in e.Items)
219        AddParameter(param);
220    }
221    private void Parameters_ItemsRemoved(object sender, CollectionItemsChangedEventArgs<IParameter> e) {
222      foreach (IParameter param in e.Items)
223        RemoveParameter(param);
224    }
225    private void Parameters_ItemsReplaced(object sender, CollectionItemsChangedEventArgs<IParameter> e) {
226      foreach (IParameter param in e.OldItems)
227        RemoveParameter(param);
228      foreach (IParameter param in e.Items)
229        AddParameter(param);
230    }
231    private void Parameters_CollectionReset(object sender, CollectionItemsChangedEventArgs<IParameter> e) {
232      foreach (IParameter param in e.OldItems)
233        RemoveParameter(param);
234      foreach (IParameter param in e.Items)
235        AddParameter(param);
236    }
237    private void opParam_ValueChanged(object sender, EventArgs e) {
238      IValueParameter<IOperator> opParam = (IValueParameter<IOperator>)sender;
239      if (opParam.Value != null) Operators.Add(opParam.Value);
240    }
241    #endregion
242  }
243}
Note: See TracBrowser for help on using the repository browser.