Free cookie consent management tool by TermsFeed Policy Generator

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

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

Refactored cloning (#806)

File size: 11.7 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.Persistence.Default.CompositeSerializers.Storable;
27using HeuristicLab.Common;
28
29namespace HeuristicLab.Core {
30  /// <summary>
31  /// Hierarchical container of variables (and of subscopes).
32  /// </summary>
33  public class Scope : ItemBase, IScope {
34
35    [Storable]
36    private IScope parent;
37
38    [Storable]
39    private string myName;
40    /// <summary>
41    /// Gets the name of the current scope.
42    /// </summary>
43    public string Name {
44      get { return myName; }
45    }
46   
47    private IDictionary<string, IVariable> myVariables;
48    /// <inheritdoc/>   
49    public ICollection<IVariable> Variables {
50      get { return myVariables.Values; }
51    }
52
53    [Storable(Name="Variables")]
54    private List<IVariable> VariablePersistence {
55      get { return new List<IVariable>(myVariables.Values); }
56      set {
57        myVariables.Clear();
58        foreach (IVariable var in value) {
59          AddVariable(var);
60        }
61      }
62    }
63   
64    [Storable]
65    private IDictionary<string, string> myAliases;
66    /// <inheritdoc/>
67    public IEnumerable<KeyValuePair<string, string>> Aliases {
68      get { return myAliases; }
69    }
70
71    [Storable]
72    private List<IScope> mySubScopes;
73    /// <summary>
74    /// Gets all subscopes of the current instance.
75    /// <note type="caution"> The subscopes are returned as read-only.</note>
76    /// </summary>
77    public IList<IScope> SubScopes {
78      get { return mySubScopes.AsReadOnly(); }
79    }
80
81    /// <summary>
82    /// Initializes a new instance of <see cref="Scope"/> having "Anonymous" as default name.
83    /// </summary>
84    public Scope() {
85      myName = "Anonymous";
86      myVariables = new Dictionary<string, IVariable>();
87      myAliases = new Dictionary<string, string>();
88      mySubScopes = new List<IScope>();
89    }
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>
94    public Scope(string name)
95      : this() {
96      if (name != null) myName = name;
97    }
98
99    /// <inheritdoc/>
100    public void SetParent(IScope scope) {
101      parent = scope;
102    }
103
104    /// <inheritdoc/>
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    }
112    /// <inheritdoc/>
113    public void AddVariable(IVariable variable) {
114      myVariables.Add(variable.Name, variable);
115      variable.NameChanging += new EventHandler<CancelEventArgs<string>>(Variable_NameChanging);
116      variable.NameChanged += new EventHandler(Variable_NameChanged);
117      OnVariableAdded(variable);
118    }
119
120    /// <inheritdoc/>
121    public void RemoveVariable(string name) {
122      IVariable variable;
123      if (myVariables.TryGetValue(name, out variable)) {
124        variable.NameChanging -= new EventHandler<CancelEventArgs<string>>(Variable_NameChanging);
125        variable.NameChanged -= new EventHandler(Variable_NameChanged);
126        myVariables.Remove(name);
127        OnVariableRemoved(variable);
128      }
129    }
130    private void Variable_NameChanging(object sender, CancelEventArgs<string> e) {
131      e.Cancel = myVariables.ContainsKey(e.Value);
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    }
143    /// <inheritdoc cref="IScope.GetVariableValue&lt;T&gt;(string, bool)"/>
144    public T GetVariableValue<T>(string name, bool recursiveLookup) where T : class, IItem {
145      return GetVariableValue<T>(name, recursiveLookup, true);
146    }
147    /// <inheritdoc cref="IScope.GetVariableValue&lt;T&gt;(string, bool, bool)"/>
148    public T GetVariableValue<T>(string name, bool recursiveLookup, bool throwOnError) where T : class, IItem {
149      return (T)GetVariableValue(name, recursiveLookup, throwOnError);
150    }
151    /// <inheritdoc cref="IScope.GetVariableValue(string, bool)"/>
152    public IItem GetVariableValue(string name, bool recursiveLookup) {
153      return GetVariableValue(name, recursiveLookup, true);
154    }
155    /// <inheritdoc cref="IScope.GetVariableValue(string, bool, bool)"/>
156    public IItem GetVariableValue(string name, bool recursiveLookup, bool throwOnError) {
157      IVariable variable;
158      name = TranslateName(name);
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    }
172    /// <inheritdoc/>
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    }
180    /// <inheritdoc/>
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    }
188    /// <inheritdoc/>
189    public void RemoveAlias(string alias) {
190      if (myAliases.ContainsKey(alias)) {
191        myAliases.Remove(alias);
192        OnAliasRemoved(alias);
193      }
194    }
195
196    /// <inheritdoc/>
197    public void AddSubScope(IScope scope) {
198      scope.SetParent(this);
199      mySubScopes.Add(scope);
200      OnSubScopeAdded(scope, mySubScopes.Count - 1);
201    }
202    /// <inheritdoc/>
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    }
210    /// <inheritdoc/>
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    }
218    /// <inheritdoc/>
219    public IScope GetScope(string name) {
220      if (Name == name) return this;
221      else {
222        for (int i = 0; i < mySubScopes.Count; i++) {
223          IScope s = mySubScopes[i].GetScope(name);
224          if (s != null) return s;
225        }
226      }
227      return null;
228    }
229
230    /// <inheritdoc/>
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
241      KeyValuePair<string, string>[] aliases = new KeyValuePair<string, string>[myAliases.Count];
242      myAliases.CopyTo(aliases, 0);
243      for (int j = 0; j < aliases.Length; j++)
244        RemoveAlias(aliases[j].Key);
245
246      while (SubScopes.Count > 0)
247        RemoveSubScope(SubScopes[0]);
248    }
249
250    /// <inheritdoc/>
251    public override IItem Clone(ICloner cloner) {
252      Scope clone = (Scope)base.Clone(cloner);
253      clone.myName = Name;
254
255      foreach (IVariable variable in myVariables.Values)
256        clone.AddVariable((IVariable)cloner.Clone(variable));
257      foreach (KeyValuePair<string, string> alias in myAliases)
258        clone.AddAlias(alias.Key, alias.Value);
259      for (int i = 0; i < SubScopes.Count; i++)
260        clone.AddSubScope((IScope)cloner.Clone(SubScopes[i]));
261
262      return clone;
263    }
264
265    /// <inheritdoc />
266    public event EventHandler<EventArgs<IVariable>> VariableAdded;
267    /// <summary>
268    /// Fires a new <c>VariableAdded</c> event.
269    /// </summary>
270    /// <param name="variable">The variable that has been added.</param>
271    protected virtual void OnVariableAdded(IVariable variable) {
272      if (VariableAdded != null)
273        VariableAdded(this, new EventArgs<IVariable>(variable));
274    }
275    /// <inheritdoc />
276    public event EventHandler<EventArgs<IVariable>> VariableRemoved;
277    /// <summary>
278    /// Fires a new <c>VariableRemoved</c>.
279    /// </summary>
280    /// <param name="variable">The variable that has been deleted.</param>
281    protected virtual void OnVariableRemoved(IVariable variable) {
282      if (VariableRemoved != null)
283        VariableRemoved(this, new EventArgs<IVariable>(variable));
284    }
285    /// <inheritdoc />
286    public event EventHandler<EventArgs<string>> AliasAdded;
287    /// <summary>
288    /// Fires a new <c>AliasAdded</c> event.
289    /// </summary>
290    /// <param name="alias">The alias that has been added.</param>
291    protected virtual void OnAliasAdded(string alias) {
292      if (AliasAdded != null)
293        AliasAdded(this, new EventArgs<string>(alias));
294    }
295    /// <inheritdoc/>
296    public event EventHandler<EventArgs<string>> AliasRemoved;
297    /// <summary>
298    /// Fires a new <c>AliasRemoved</c> event.
299    /// </summary>
300    /// <param name="alias">The alias that has been deleted.</param>
301    protected virtual void OnAliasRemoved(string alias) {
302      if (AliasRemoved != null)
303        AliasRemoved(this, new EventArgs<string>(alias));
304    }
305    /// <inheritdoc/>
306    public event EventHandler<EventArgs<IScope, int>> SubScopeAdded;
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>
312    protected virtual void OnSubScopeAdded(IScope scope, int index) {
313      if (SubScopeAdded != null)
314        SubScopeAdded(this, new EventArgs<IScope, int>(scope, index));
315    }
316    /// <inheritdoc/>
317    public event EventHandler<EventArgs<IScope, int>> SubScopeRemoved;
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>
323    protected virtual void OnSubScopeRemoved(IScope scope, int index) {
324      if (SubScopeRemoved != null)
325        SubScopeRemoved(this, new EventArgs<IScope, int>(scope, index));
326    }
327    /// <inheritdoc />
328    public event EventHandler SubScopesReordered;
329    /// <summary>
330    /// Fires a new <c>SubScopesReordered</c> event
331    /// </summary>
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.