Free cookie consent management tool by TermsFeed Policy Generator

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

Last change on this file since 1727 was 1727, checked in by epitzer, 15 years ago

Register event listeners during deserialization. (#603)

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