Free cookie consent management tool by TermsFeed Policy Generator

source: trunk/sources/HeuristicLab.Core/3.3/Scope.cs @ 2583

Last change on this file since 2583 was 2526, checked in by swagner, 15 years ago

Refactored cloning (#806)

File size: 11.7 KB
RevLine 
[2]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;
[1823]26using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
[2474]27using HeuristicLab.Common;
[2]28
29namespace HeuristicLab.Core {
[776]30  /// <summary>
31  /// Hierarchical container of variables (and of subscopes).
32  /// </summary>
[2]33  public class Scope : ItemBase, IScope {
[1667]34
[1727]35    [Storable]
[2]36    private IScope parent;
37
[1667]38    [Storable]
39    private string myName;
[776]40    /// <summary>
41    /// Gets the name of the current scope.
42    /// </summary>
[2]43    public string Name {
44      get { return myName; }
45    }
[1727]46   
[2]47    private IDictionary<string, IVariable> myVariables;
[1727]48    /// <inheritdoc/>   
[2]49    public ICollection<IVariable> Variables {
50      get { return myVariables.Values; }
51    }
[1667]52
[1727]53    [Storable(Name="Variables")]
54    private List<IVariable> VariablePersistence {
55      get { return new List<IVariable>(myVariables.Values); }
56      set {
[1732]57        myVariables.Clear();
[1727]58        foreach (IVariable var in value) {
59          AddVariable(var);
60        }
61      }
62    }
63   
[1667]64    [Storable]
[61]65    private IDictionary<string, string> myAliases;
[776]66    /// <inheritdoc/>
[63]67    public IEnumerable<KeyValuePair<string, string>> Aliases {
68      get { return myAliases; }
[61]69    }
[1667]70
71    [Storable]
[2]72    private List<IScope> mySubScopes;
[776]73    /// <summary>
74    /// Gets all subscopes of the current instance.
75    /// <note type="caution"> The subscopes are returned as read-only.</note>
76    /// </summary>
[2]77    public IList<IScope> SubScopes {
78      get { return mySubScopes.AsReadOnly(); }
79    }
80
[776]81    /// <summary>
82    /// Initializes a new instance of <see cref="Scope"/> having "Anonymous" as default name.
83    /// </summary>
[2]84    public Scope() {
85      myName = "Anonymous";
86      myVariables = new Dictionary<string, IVariable>();
[61]87      myAliases = new Dictionary<string, string>();
[2]88      mySubScopes = new List<IScope>();
89    }
[776]90    /// <summary>
91    /// Initializes a new instance of <see cref="Scope"/> with the given <paramref name="name"/>.
92    /// </summary>
93    /// <param name="name">The name of the scope.</param>
[2]94    public Scope(string name)
95      : this() {
96      if (name != null) myName = name;
97    }
98
[776]99    /// <inheritdoc/>
[2]100    public void SetParent(IScope scope) {
101      parent = scope;
102    }
103
[776]104    /// <inheritdoc/>
[2]105    public IVariable GetVariable(string name) {
106      IVariable variable;
107      if (myVariables.TryGetValue(name, out variable))
108        return variable;
109      else
110        return null;
111    }
[776]112    /// <inheritdoc/>
[2]113    public void AddVariable(IVariable variable) {
114      myVariables.Add(variable.Name, variable);
[2474]115      variable.NameChanging += new EventHandler<CancelEventArgs<string>>(Variable_NameChanging);
[2]116      variable.NameChanged += new EventHandler(Variable_NameChanged);
117      OnVariableAdded(variable);
118    }
119
[776]120    /// <inheritdoc/>
[2]121    public void RemoveVariable(string name) {
122      IVariable variable;
123      if (myVariables.TryGetValue(name, out variable)) {
[2474]124        variable.NameChanging -= new EventHandler<CancelEventArgs<string>>(Variable_NameChanging);
[2]125        variable.NameChanged -= new EventHandler(Variable_NameChanged);
126        myVariables.Remove(name);
127        OnVariableRemoved(variable);
128      }
129    }
[2474]130    private void Variable_NameChanging(object sender, CancelEventArgs<string> e) {
131      e.Cancel = myVariables.ContainsKey(e.Value);
[2]132    }
133    private void Variable_NameChanged(object sender, EventArgs e) {
134      IVariable variable = (IVariable)sender;
135      string oldName = null;
136      foreach (KeyValuePair<string, IVariable> element in myVariables) {
137        if (element.Value == variable)
138          oldName = element.Key;
139      }
140      myVariables.Remove(oldName);
141      myVariables.Add(variable.Name, variable);
142    }
[776]143    /// <inheritdoc cref="IScope.GetVariableValue&lt;T&gt;(string, bool)"/>
[2]144    public T GetVariableValue<T>(string name, bool recursiveLookup) where T : class, IItem {
145      return GetVariableValue<T>(name, recursiveLookup, true);
146    }
[776]147    /// <inheritdoc cref="IScope.GetVariableValue&lt;T&gt;(string, bool, bool)"/>
[2]148    public T GetVariableValue<T>(string name, bool recursiveLookup, bool throwOnError) where T : class, IItem {
149      return (T)GetVariableValue(name, recursiveLookup, throwOnError);
150    }
[776]151    /// <inheritdoc cref="IScope.GetVariableValue(string, bool)"/>
[2]152    public IItem GetVariableValue(string name, bool recursiveLookup) {
153      return GetVariableValue(name, recursiveLookup, true);
154    }
[776]155    /// <inheritdoc cref="IScope.GetVariableValue(string, bool, bool)"/>
[2]156    public IItem GetVariableValue(string name, bool recursiveLookup, bool throwOnError) {
157      IVariable variable;
[61]158      name = TranslateName(name);
[2]159      if (myVariables.TryGetValue(name, out variable)) {
160        return variable.Value;
161      } else {
162        if (recursiveLookup && (parent != null))
163          return parent.GetVariableValue(name, recursiveLookup, throwOnError);
164        else {
165          if (throwOnError)
166            throw new ArgumentException("Variable " + name + " not found");
167          else
168            return null;
169        }
170      }
171    }
[776]172    /// <inheritdoc/>
[61]173    public string TranslateName(string name) {
174      while (myAliases.ContainsKey(name))
175        name = myAliases[name];
176      if (parent != null)
177        name = parent.TranslateName(name);
178      return name;
179    }
[776]180    /// <inheritdoc/>
[61]181    public void AddAlias(string alias, string name) {
182      RemoveAlias(alias);
183      if (alias != name) {
184        myAliases.Add(alias, name);
185        OnAliasAdded(alias);
186      }
187    }
[776]188    /// <inheritdoc/>
[61]189    public void RemoveAlias(string alias) {
190      if (myAliases.ContainsKey(alias)) {
191        myAliases.Remove(alias);
192        OnAliasRemoved(alias);
193      }
194    }
195
[776]196    /// <inheritdoc/>
[2]197    public void AddSubScope(IScope scope) {
198      scope.SetParent(this);
199      mySubScopes.Add(scope);
200      OnSubScopeAdded(scope, mySubScopes.Count - 1);
201    }
[776]202    /// <inheritdoc/>
[2]203    public void RemoveSubScope(IScope scope) {
204      int index = mySubScopes.IndexOf(scope);
205      if (mySubScopes.Remove(scope)) {
206        scope.SetParent(null);
207        OnSubScopeRemoved(scope, index);
208      }
209    }
[776]210    /// <inheritdoc/>
[2]211    public void ReorderSubScopes(int[] sequence) {
212      IScope[] scopes = mySubScopes.ToArray();
213      mySubScopes.Clear();
214      for (int i = 0; i < scopes.Length; i++)
215        mySubScopes.Add(scopes[sequence[i]]);
216      OnSubScopesReordered();
217    }
[776]218    /// <inheritdoc/>
[2]219    public IScope GetScope(string name) {
220      if (Name == name) return this;
221      else {
222        for (int i = 0; i < mySubScopes.Count; i++) {
[261]223          IScope s = mySubScopes[i].GetScope(name);
[2]224          if (s != null) return s;
225        }
226      }
227      return null;
228    }
229
[776]230    /// <inheritdoc/>
[2]231    public void Clear() {
232      string[] variableNames = new string[Variables.Count];
233      int i = 0;
234      foreach (IVariable variable in Variables) {
235        variableNames[i] = variable.Name;
236        i++;
237      }
238      for (int j = 0; j < variableNames.Length; j++)
239        RemoveVariable(variableNames[j]);
240
[1667]241      KeyValuePair<string, string>[] aliases = new KeyValuePair<string, string>[myAliases.Count];
[63]242      myAliases.CopyTo(aliases, 0);
[61]243      for (int j = 0; j < aliases.Length; j++)
[63]244        RemoveAlias(aliases[j].Key);
[61]245
[2]246      while (SubScopes.Count > 0)
247        RemoveSubScope(SubScopes[0]);
248    }
249
[776]250    /// <inheritdoc/>
[2526]251    public override IItem Clone(ICloner cloner) {
252      Scope clone = (Scope)base.Clone(cloner);
[2]253      clone.myName = Name;
254
255      foreach (IVariable variable in myVariables.Values)
[2526]256        clone.AddVariable((IVariable)cloner.Clone(variable));
[61]257      foreach (KeyValuePair<string, string> alias in myAliases)
258        clone.AddAlias(alias.Key, alias.Value);
[2]259      for (int i = 0; i < SubScopes.Count; i++)
[2526]260        clone.AddSubScope((IScope)cloner.Clone(SubScopes[i]));
[2]261
262      return clone;
263    }
264
[776]265    /// <inheritdoc />
[2474]266    public event EventHandler<EventArgs<IVariable>> VariableAdded;
[776]267    /// <summary>
268    /// Fires a new <c>VariableAdded</c> event.
269    /// </summary>
270    /// <param name="variable">The variable that has been added.</param>
[2]271    protected virtual void OnVariableAdded(IVariable variable) {
272      if (VariableAdded != null)
[2474]273        VariableAdded(this, new EventArgs<IVariable>(variable));
[2]274    }
[776]275    /// <inheritdoc />
[2474]276    public event EventHandler<EventArgs<IVariable>> VariableRemoved;
[776]277    /// <summary>
278    /// Fires a new <c>VariableRemoved</c>.
279    /// </summary>
280    /// <param name="variable">The variable that has been deleted.</param>
[2]281    protected virtual void OnVariableRemoved(IVariable variable) {
282      if (VariableRemoved != null)
[2474]283        VariableRemoved(this, new EventArgs<IVariable>(variable));
[2]284    }
[776]285    /// <inheritdoc />
[2474]286    public event EventHandler<EventArgs<string>> AliasAdded;
[776]287    /// <summary>
288    /// Fires a new <c>AliasAdded</c> event.
289    /// </summary>
290    /// <param name="alias">The alias that has been added.</param>
[61]291    protected virtual void OnAliasAdded(string alias) {
292      if (AliasAdded != null)
[2474]293        AliasAdded(this, new EventArgs<string>(alias));
[61]294    }
[776]295    /// <inheritdoc/>
[2474]296    public event EventHandler<EventArgs<string>> AliasRemoved;
[776]297    /// <summary>
298    /// Fires a new <c>AliasRemoved</c> event.
299    /// </summary>
300    /// <param name="alias">The alias that has been deleted.</param>
[61]301    protected virtual void OnAliasRemoved(string alias) {
302      if (AliasRemoved != null)
[2474]303        AliasRemoved(this, new EventArgs<string>(alias));
[61]304    }
[776]305    /// <inheritdoc/>
[2474]306    public event EventHandler<EventArgs<IScope, int>> SubScopeAdded;
[776]307    /// <summary>
308    /// Fires a new <c>SubScopeAdded</c> event.
309    /// </summary>
310    /// <param name="scope">The sub scope that has been added.</param>
311    /// <param name="index">The index where the scope has been added.</param>
[2]312    protected virtual void OnSubScopeAdded(IScope scope, int index) {
313      if (SubScopeAdded != null)
[2474]314        SubScopeAdded(this, new EventArgs<IScope, int>(scope, index));
[2]315    }
[776]316    /// <inheritdoc/>
[2474]317    public event EventHandler<EventArgs<IScope, int>> SubScopeRemoved;
[776]318    /// <summary>
319    /// Fires a new <c>SubScopeRemoved</c> event.
320    /// </summary>
321    /// <param name="scope">The sub scope that has been deleted.</param>
322    /// <param name="index">The position of the sub scope.</param>
[2]323    protected virtual void OnSubScopeRemoved(IScope scope, int index) {
324      if (SubScopeRemoved != null)
[2474]325        SubScopeRemoved(this, new EventArgs<IScope, int>(scope, index));
[2]326    }
[776]327    /// <inheritdoc />
[2]328    public event EventHandler SubScopesReordered;
[776]329    /// <summary>
330    /// Fires a new <c>SubScopesReordered</c> event
331    /// </summary>
[2]332    protected virtual void OnSubScopesReordered() {
333      if (SubScopesReordered != null)
334        SubScopesReordered(this, new EventArgs());
335    }
336  }
337}
Note: See TracBrowser for help on using the repository browser.