Free cookie consent management tool by TermsFeed Policy Generator

source: branches/Operator Architecture Refactoring/HeuristicLab.Operators/3.2/VariableInjector.cs @ 2634

Last change on this file since 2634 was 2027, checked in by swagner, 16 years ago

Refactoring of the operator architecture (#95)

File size: 9.3 KB
Line 
1#region License Information
2/* HeuristicLab
3 * Copyright (C) 2002-2008 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 HeuristicLab.Core;
27
28namespace HeuristicLab.Operators {
29  /// <summary>
30  /// Class to inject local variables into the scope.
31  /// </summary>
32  public class VariableInjector : OperatorBase, IVariablesContainer {
33    private Dictionary<string, IVariable> myVariables;
34    /// <summary>
35    /// Gets a collection of all variables of the current operator.
36    /// </summary>
37    public virtual ICollection<IVariable> Variables {
38      get { return myVariables.Values; }
39    }
40
41    /// <inheritdoc select="summary"/>
42    public override string Description {
43      get { return @"Injects new variable into a scope."; }
44    }
45
46    /// <summary>
47    /// Overrides the Parameters property so that a parameter is returned for each injected variable.
48    /// </summary>
49    public override ICollection<IParameter> Parameters {
50      get {
51        List<IParameter> parameters = new List<IParameter>();
52        foreach (IVariable variable in Variables)
53          parameters.Add(new Parameter(variable.Name, "Injected variable.", variable.Value.GetType(), ParameterType.Out));
54        return parameters;
55      }
56    }
57
58    /// <summary>
59    /// Initializes a new instance of <see cref="VariableInjector"/>.
60    /// </summary>
61    public VariableInjector()
62      : base() {
63      myVariables = new Dictionary<string, IVariable>();
64    }
65
66    /// <summary>
67    /// Clones the current instance (deep clone).
68    /// </summary>
69    /// <remarks>Deep clone performed with <see cref="Auxiliary.Clone"/> of helper class
70    /// <see cref="Auxiliary"/>.</remarks>
71    /// <param name="clonedObjects">Dictionary of all already cloned objects. (Needed to avoid cycles.)</param>
72    /// <returns>The cloned object as <see cref="VariableInjector"/>.</returns>
73    public override object Clone(IDictionary<Guid, object> clonedObjects) {
74      VariableInjector clone = (VariableInjector)base.Clone(clonedObjects);
75      foreach (IVariable variable in Variables)
76        clone.AddVariable((IVariable)Auxiliary.Clone(variable, clonedObjects));
77      return clone;
78    }
79
80    /// <summary>
81    /// Adds the specified variables to the given <paramref name="scope"/> (and removes them first,
82    /// if they already exist in the current scope).
83    /// </summary>
84    /// <param name="scope">The scope where to inject the variables.</param>
85    /// <returns><c>null</c>.</returns>
86    public override IOperation Apply(IEnvironment env, IScope scope) {
87      foreach (IVariable variable in Variables) {
88        if (scope.GetVariable(variable.Name) != null)
89          scope.RemoveVariable(variable.Name);
90        scope.AddVariable((IVariable)variable.Clone());
91      }
92      return null;
93    }
94
95    /// <summary>
96    /// Creates a new instance of <see cref="VariableInjectorView"/> to display the current instance.
97    /// </summary>
98    /// <returns>The created view as <see cref="VariableInjectorView"/>.</returns>
99    public override IView CreateView() {
100      return new VariableInjectorView(this);
101    }
102
103    /// <summary>
104    /// Gets a variable with the given <paramref name="name"/>.
105    /// </summary>
106    /// <param name="name">The name of the variable.</param>
107    /// <returns>The variable with the specified name.</returns>
108    public virtual IVariable GetVariable(string name) {
109      IVariable variable;
110      if (myVariables.TryGetValue(name, out variable))
111        return variable;
112      else
113        return null;
114    }
115    /// <summary>
116    /// Adds the specified <paramref name="variable"/> to the current instance.
117    /// </summary>
118    /// <param name="variable">The variable to add.</param>
119    public virtual void AddVariable(IVariable variable) {
120      myVariables.Add(variable.Name, variable);
121      variable.NameChanging += new EventHandler<NameChangingEventArgs>(Variable_NameChanging);
122      variable.NameChanged += new EventHandler(Variable_NameChanged);
123      OnVariableAdded(variable);
124    }
125    /// <summary>
126    /// Deletes the variable with the specified <paramref name="name"/>.
127    /// </summary>
128    /// <param name="name">The name of the variable to delete.</param>
129    public virtual void RemoveVariable(string name) {
130      IVariable variable;
131      if (myVariables.TryGetValue(name, out variable)) {
132        variable.NameChanging -= new EventHandler<NameChangingEventArgs>(Variable_NameChanging);
133        variable.NameChanged -= new EventHandler(Variable_NameChanged);
134        myVariables.Remove(name);
135        OnVariableRemoved(variable);
136      }
137    }
138    private void Variable_NameChanging(object sender, NameChangingEventArgs e) {
139      e.Cancel = myVariables.ContainsKey(e.Name);
140    }
141    private void Variable_NameChanged(object sender, EventArgs e) {
142      IVariable variable = (IVariable)sender;
143      string oldName = null;
144      foreach (KeyValuePair<string, IVariable> element in myVariables) {
145        if (element.Value == variable)
146          oldName = element.Key;
147      }
148      myVariables.Remove(oldName);
149      myVariables.Add(variable.Name, variable);
150    }
151
152    /// <summary>
153    /// Occurs when a variable has been added.
154    /// </summary>
155    public event EventHandler<VariableEventArgs> VariableAdded;
156    /// <summary>
157    /// Fires a new <c>VariableAdded</c> event.
158    /// </summary>
159    /// <param name="variable">The variable that has been added.</param>
160    protected virtual void OnVariableAdded(IVariable variable) {
161      if (VariableAdded != null)
162        VariableAdded(this, new VariableEventArgs(variable));
163    }
164    /// <summary>
165    /// Occurs when a variable has been deleted.
166    /// </summary>
167    public event EventHandler<VariableEventArgs> VariableRemoved;
168    /// <summary>
169    /// Fires a new <c>VariableRemoved</c> event.
170    /// </summary>
171    /// <param name="variable">The variable that has been removed</param>
172    protected virtual void OnVariableRemoved(IVariable variable) {
173      if (VariableRemoved != null)
174        VariableRemoved(this, new VariableEventArgs(variable));
175    }
176
177    #region Persistence Methods
178    /// <summary>
179    /// Saves the current instance as <see cref="XmlNode"/> in the specified <paramref name="document"/>.
180    /// </summary>
181    /// <remarks>
182    /// Calls <see cref="OperatorBase.GetXmlNode"/> of base class <see cref="OperatorBase"/>.
183    /// <br/>A quick overview how the single elements of the current instance are saved:
184    /// <list type="bullet">
185    /// <item>
186    /// <term>Variables: </term>
187    /// <description>Saved as child node with tag name <c>Variables</c>. All variables are themselves
188    /// saved as child nodes.</description>
189    /// </item>
190    /// </list>
191    /// </remarks>
192    /// <param name="name">The (tag)name of the <see cref="XmlNode"/>.</param>
193    /// <param name="document">The <see cref="XmlDocument"/> where to save the data.</param>
194    /// <param name="persistedObjects">The dictionary of all already persisted objects. (Needed to avoid cycles.)</param>
195    /// <returns>The saved <see cref="XmlNode"/>.</returns>
196    public override XmlNode GetXmlNode(string name, XmlDocument document, IDictionary<Guid, IStorable> persistedObjects) {
197      XmlNode node = base.GetXmlNode(name, document, persistedObjects);
198      XmlNode variablesNode = document.CreateNode(XmlNodeType.Element, "Variables", null);
199      foreach (IVariable variable in myVariables.Values)
200        variablesNode.AppendChild(PersistenceManager.Persist(variable, document, persistedObjects));
201      node.AppendChild(variablesNode);
202      return node;
203    }
204    /// <summary>
205    /// Loads the persisted variable injector from the specified <paramref name="node"/>.
206    /// </summary>
207    /// <remarks>Calls <see cref="OperatorBase.Populate"/> of base class
208    /// <see cref="OperatorBase"/>.
209    /// For informations how the different elements must be saved please see <see cref="GetXmlNode"/>.</remarks>
210    /// <param name="node">The <see cref="XmlNode"/> where the operation is saved.</param>
211    /// <param name="restoredObjects">A dictionary of all already restored objects. (Needed to avoid cycles.)</param>
212    public override void Populate(XmlNode node, IDictionary<Guid, IStorable> restoredObjects) {
213      base.Populate(node, restoredObjects);
214      XmlNode variablesNode = node.SelectSingleNode("Variables");
215      foreach (XmlNode variableNode in variablesNode.ChildNodes)
216        AddVariable((IVariable)PersistenceManager.Restore(variableNode, restoredObjects));
217    }
218    #endregion
219  }
220}
Note: See TracBrowser for help on using the repository browser.