#region License Information /* HeuristicLab * Copyright (C) 2002-2008 Heuristic and Evolutionary Algorithms Laboratory (HEAL) * * This file is part of HeuristicLab. * * HeuristicLab is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * HeuristicLab is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with HeuristicLab. If not, see . */ #endregion using System; using System.Collections.Generic; using System.Text; using System.Xml; using HeuristicLab.Persistence.Default.CompositeSerializers.Storable; using HeuristicLab.Common; namespace HeuristicLab.Core { /// /// Hierarchical container of variables (and of subscopes). /// public class Scope : ItemBase, IScope { [Storable] private IScope parent; [Storable] private string myName; /// /// Gets the name of the current scope. /// public string Name { get { return myName; } } private IDictionary myVariables; /// public ICollection Variables { get { return myVariables.Values; } } [Storable(Name="Variables")] private List VariablePersistence { get { return new List(myVariables.Values); } set { myVariables.Clear(); foreach (IVariable var in value) { AddVariable(var); } } } [Storable] private IDictionary myAliases; /// public IEnumerable> Aliases { get { return myAliases; } } [Storable] private List mySubScopes; /// /// Gets all subscopes of the current instance. /// The subscopes are returned as read-only. /// public IList SubScopes { get { return mySubScopes.AsReadOnly(); } } /// /// Initializes a new instance of having "Anonymous" as default name. /// public Scope() { myName = "Anonymous"; myVariables = new Dictionary(); myAliases = new Dictionary(); mySubScopes = new List(); } /// /// Initializes a new instance of with the given . /// /// The name of the scope. public Scope(string name) : this() { if (name != null) myName = name; } /// public void SetParent(IScope scope) { parent = scope; } /// /// Creates a new instance of to represent the current instance visually. /// /// The created view as . public override IView CreateView() { return new ScopeView(this); } /// public IVariable GetVariable(string name) { IVariable variable; if (myVariables.TryGetValue(name, out variable)) return variable; else return null; } /// public void AddVariable(IVariable variable) { myVariables.Add(variable.Name, variable); variable.NameChanging += new EventHandler>(Variable_NameChanging); variable.NameChanged += new EventHandler(Variable_NameChanged); OnVariableAdded(variable); } /// public void RemoveVariable(string name) { IVariable variable; if (myVariables.TryGetValue(name, out variable)) { variable.NameChanging -= new EventHandler>(Variable_NameChanging); variable.NameChanged -= new EventHandler(Variable_NameChanged); myVariables.Remove(name); OnVariableRemoved(variable); } } private void Variable_NameChanging(object sender, CancelEventArgs e) { e.Cancel = myVariables.ContainsKey(e.Value); } private void Variable_NameChanged(object sender, EventArgs e) { IVariable variable = (IVariable)sender; string oldName = null; foreach (KeyValuePair element in myVariables) { if (element.Value == variable) oldName = element.Key; } myVariables.Remove(oldName); myVariables.Add(variable.Name, variable); } /// public T GetVariableValue(string name, bool recursiveLookup) where T : class, IItem { return GetVariableValue(name, recursiveLookup, true); } /// public T GetVariableValue(string name, bool recursiveLookup, bool throwOnError) where T : class, IItem { return (T)GetVariableValue(name, recursiveLookup, throwOnError); } /// public IItem GetVariableValue(string name, bool recursiveLookup) { return GetVariableValue(name, recursiveLookup, true); } /// public IItem GetVariableValue(string name, bool recursiveLookup, bool throwOnError) { IVariable variable; name = TranslateName(name); if (myVariables.TryGetValue(name, out variable)) { return variable.Value; } else { if (recursiveLookup && (parent != null)) return parent.GetVariableValue(name, recursiveLookup, throwOnError); else { if (throwOnError) throw new ArgumentException("Variable " + name + " not found"); else return null; } } } /// public string TranslateName(string name) { while (myAliases.ContainsKey(name)) name = myAliases[name]; if (parent != null) name = parent.TranslateName(name); return name; } /// public void AddAlias(string alias, string name) { RemoveAlias(alias); if (alias != name) { myAliases.Add(alias, name); OnAliasAdded(alias); } } /// public void RemoveAlias(string alias) { if (myAliases.ContainsKey(alias)) { myAliases.Remove(alias); OnAliasRemoved(alias); } } /// public void AddSubScope(IScope scope) { scope.SetParent(this); mySubScopes.Add(scope); OnSubScopeAdded(scope, mySubScopes.Count - 1); } /// public void RemoveSubScope(IScope scope) { int index = mySubScopes.IndexOf(scope); if (mySubScopes.Remove(scope)) { scope.SetParent(null); OnSubScopeRemoved(scope, index); } } /// public void ReorderSubScopes(int[] sequence) { IScope[] scopes = mySubScopes.ToArray(); mySubScopes.Clear(); for (int i = 0; i < scopes.Length; i++) mySubScopes.Add(scopes[sequence[i]]); OnSubScopesReordered(); } /// public IScope GetScope(Guid guid) { if (Guid == guid) return this; else { for (int i = 0; i < mySubScopes.Count; i++) { IScope s = mySubScopes[i].GetScope(guid); if (s != null) return s; } } return null; } /// public IScope GetScope(string name) { if (Name == name) return this; else { for (int i = 0; i < mySubScopes.Count; i++) { IScope s = mySubScopes[i].GetScope(name); if (s != null) return s; } } return null; } /// public void Clear() { string[] variableNames = new string[Variables.Count]; int i = 0; foreach (IVariable variable in Variables) { variableNames[i] = variable.Name; i++; } for (int j = 0; j < variableNames.Length; j++) RemoveVariable(variableNames[j]); KeyValuePair[] aliases = new KeyValuePair[myAliases.Count]; myAliases.CopyTo(aliases, 0); for (int j = 0; j < aliases.Length; j++) RemoveAlias(aliases[j].Key); while (SubScopes.Count > 0) RemoveSubScope(SubScopes[0]); } /// public override object Clone(IDictionary clonedObjects) { Scope clone = (Scope)base.Clone(clonedObjects); clone.myName = Name; foreach (IVariable variable in myVariables.Values) clone.AddVariable((IVariable)Auxiliary.Clone(variable, clonedObjects)); foreach (KeyValuePair alias in myAliases) clone.AddAlias(alias.Key, alias.Value); for (int i = 0; i < SubScopes.Count; i++) clone.AddSubScope((IScope)Auxiliary.Clone(SubScopes[i], clonedObjects)); return clone; } /// public event EventHandler> VariableAdded; /// /// Fires a new VariableAdded event. /// /// The variable that has been added. protected virtual void OnVariableAdded(IVariable variable) { if (VariableAdded != null) VariableAdded(this, new EventArgs(variable)); } /// public event EventHandler> VariableRemoved; /// /// Fires a new VariableRemoved. /// /// The variable that has been deleted. protected virtual void OnVariableRemoved(IVariable variable) { if (VariableRemoved != null) VariableRemoved(this, new EventArgs(variable)); } /// public event EventHandler> AliasAdded; /// /// Fires a new AliasAdded event. /// /// The alias that has been added. protected virtual void OnAliasAdded(string alias) { if (AliasAdded != null) AliasAdded(this, new EventArgs(alias)); } /// public event EventHandler> AliasRemoved; /// /// Fires a new AliasRemoved event. /// /// The alias that has been deleted. protected virtual void OnAliasRemoved(string alias) { if (AliasRemoved != null) AliasRemoved(this, new EventArgs(alias)); } /// public event EventHandler> SubScopeAdded; /// /// Fires a new SubScopeAdded event. /// /// The sub scope that has been added. /// The index where the scope has been added. protected virtual void OnSubScopeAdded(IScope scope, int index) { if (SubScopeAdded != null) SubScopeAdded(this, new EventArgs(scope, index)); } /// public event EventHandler> SubScopeRemoved; /// /// Fires a new SubScopeRemoved event. /// /// The sub scope that has been deleted. /// The position of the sub scope. protected virtual void OnSubScopeRemoved(IScope scope, int index) { if (SubScopeRemoved != null) SubScopeRemoved(this, new EventArgs(scope, index)); } /// public event EventHandler SubScopesReordered; /// /// Fires a new SubScopesReordered event /// protected virtual void OnSubScopesReordered() { if (SubScopesReordered != null) SubScopesReordered(this, new EventArgs()); } } }