Free cookie consent management tool by TermsFeed Policy Generator

source: branches/CloningRefactorBranch/HeuristicLab.Core/OperatorBase.cs @ 885

Last change on this file since 885 was 885, checked in by gkronber, 15 years ago

Refactored cloning in HL.Core, HL.Data and HL.Constraints

#285 (Cloning could be improved by creating objects at the bottom of the cloning chain with 'new' instead of the top with Activator.CreateInstance())

File size: 28.9 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;
26
27namespace HeuristicLab.Core {
28  /// <summary>
29  /// The base class for all operators.
30  /// </summary>
31  public abstract class OperatorBase : ConstrainedItemBase, IOperator {
32    private string myName;
33    /// <summary>
34    /// Gets or sets the name of the operator.
35    /// </summary>
36    /// <remarks>Calls <see cref="OnNameChanged"/> in the setter.</remarks>
37    public string Name {
38      get { return myName; }
39      set {
40        if (myName != value) {
41          myName = value;
42          OnNameChanged();
43        }
44      }
45    }
46    /// <summary>
47    /// Gets the description of the current operator.
48    /// </summary>
49    /// <remarks>Returns "No operator description available" if the method is not overriden.</remarks>
50    public virtual string Description {
51      get { return "No operator description available."; }
52    }
53    /// <summary>
54    /// Flag whether the current instance has been canceled.
55    /// </summary>
56    protected bool myCanceled;
57    /// <inheritdoc/>
58    public bool Canceled {
59      get { return myCanceled; }
60    }
61    private bool myBreakpoint;
62    /// <inheritdoc/>
63    /// <remarks>Calls <see cref="OnBreakpointChanged"/> in the setter.</remarks>
64    public bool Breakpoint {
65      get { return myBreakpoint; }
66      set {
67        if (value != myBreakpoint) {
68          myBreakpoint = value;
69          OnBreakpointChanged();
70        }
71      }
72    }
73
74    private List<IOperator> mySubOperators;
75    /// <summary>
76    /// Gets a list of all suboperators.
77    /// <note type="caution"> Returns the suboperators read-only!</note>
78    /// </summary>
79    public virtual IList<IOperator> SubOperators {
80      get { return mySubOperators.AsReadOnly(); }
81    }
82    private Dictionary<string, IVariableInfo> myVariableInfos;
83    /// <inheritdoc/>
84    public virtual ICollection<IVariableInfo> VariableInfos {
85      get { return myVariableInfos.Values; }
86    }
87    private Dictionary<string, IVariable> myVariables;
88    /// <inheritdoc/>
89    public virtual ICollection<IVariable> Variables {
90      get { return myVariables.Values; }
91    }
92
93    /// <summary>
94    /// Initializes a new instance of <see cref="OperatorBase"/> setting the breakpoint flag and
95    /// the canceled flag to <c>false</c> and the name of the operator to the type name.
96    /// </summary>
97    protected OperatorBase() {
98      myName = this.GetType().Name;
99      myCanceled = false;
100      myBreakpoint = false;
101      mySubOperators = new List<IOperator>();
102      myVariableInfos = new Dictionary<string, IVariableInfo>();
103      myVariables = new Dictionary<string, IVariable>();
104    }
105
106    /// <summary>
107    /// Copy constructor.
108    /// </summary>
109    /// <param name="original">The original instance to be cloned</param>
110    /// <param name="clonedObjects">Already cloned objects (for referential integrity).</param>
111    protected OperatorBase(OperatorBase original, IDictionary<Guid, object> clonedObjects)
112      : base(original, clonedObjects) {
113      this.myName = original.Name;
114      this.mySubOperators = new List<IOperator>();
115      for (int i = 0; i < original.SubOperators.Count; i++)
116        AddSubOperator((IOperator)Auxiliary.Clone(original.SubOperators[i], clonedObjects));
117      this.myVariableInfos = new Dictionary<string, IVariableInfo>();
118      foreach (IVariableInfo variableInfo in original.myVariableInfos.Values)
119        AddVariableInfo((IVariableInfo)Auxiliary.Clone(variableInfo, clonedObjects));
120      this.myVariables = new Dictionary<string, IVariable>();
121      foreach (IVariable variable in original.myVariables.Values)
122        AddVariable((IVariable)Auxiliary.Clone(variable, clonedObjects));
123    }
124
125    /// <summary>
126    /// Creates a new instance of <see cref="OperatorBaseView"/> to represent the current operator
127    /// visually.
128    /// </summary>
129    /// <returns>The created view as <see cref="OperatorBaseView"/>.</returns>
130    public override IView CreateView() {
131      return new OperatorBaseView(this);
132    }
133
134    #region SubOperator Methods
135    /// <inheritdoc cref="HeuristicLab.Core.IOperator.AddSubOperator(HeuristicLab.Core.IOperator)"/>
136    /// <param name="subOperator">The sub operator to add.</param>
137    /// <remarks>Calls <see cref="OnSubOperatorAdded"/>.</remarks>
138    public virtual void AddSubOperator(IOperator subOperator) {
139      mySubOperators.Add(subOperator);
140      OnSubOperatorAdded(subOperator, mySubOperators.Count - 1);
141    }
142    /// <inheritdoc cref="IOperator.TryAddSubOperator(HeuristicLab.Core.IOperator)"/>
143    /// <param name="subOperator">The sub operator to add.</param>
144    /// <remarks>Calls <see cref="OnSubOperatorAdded"/>.</remarks>
145    public virtual bool TryAddSubOperator(IOperator subOperator) {
146      mySubOperators.Add(subOperator);
147      if (IsValid()) {
148        OnSubOperatorAdded(subOperator, mySubOperators.Count - 1);
149        return true;
150      } else {
151        mySubOperators.RemoveAt(mySubOperators.Count - 1);
152        return false;
153      }
154    }
155    /// <inheritdoc cref="HeuristicLab.Core.IOperator.TryAddSubOperator(HeuristicLab.Core.IOperator,
156    /// out System.Collections.Generic.ICollection&lt;HeuristicLab.Core.IConstraint&gt;)"/>
157    /// <param name="subOperator">The sub operator to add.</param>
158    /// <remarks>Calls <see cref="OnSubOperatorAdded"/>.</remarks>
159    public virtual bool TryAddSubOperator(IOperator subOperator, out ICollection<IConstraint> violatedConstraints) {
160      mySubOperators.Add(subOperator);
161      if (IsValid(out violatedConstraints)) {
162        OnSubOperatorAdded(subOperator, mySubOperators.Count - 1);
163        return true;
164      } else {
165        mySubOperators.RemoveAt(mySubOperators.Count - 1);
166        return false;
167      }
168    }
169    /// <inheritdoc cref="HeuristicLab.Core.IOperator.AddSubOperator(HeuristicLab.Core.IOperator, int)"/>
170    /// <param name="subOperator">The sub operator to add.</param>
171    /// <remarks>Calls <see cref="OnSubOperatorAdded"/>.</remarks>
172    public virtual void AddSubOperator(IOperator subOperator, int index) {
173      mySubOperators.Insert(index, subOperator);
174      OnSubOperatorAdded(subOperator, index);
175    }
176    /// <inheritdoc cref="IOperator.TryAddSubOperator(HeuristicLab.Core.IOperator, int)"/>
177    /// <param name="subOperator">The sub operator to add.</param>
178    /// <remarks>Calls <see cref="OnSubOperatorAdded"/>.</remarks>
179    public virtual bool TryAddSubOperator(IOperator subOperator, int index) {
180      mySubOperators.Insert(index, subOperator);
181      if (IsValid()) {
182        OnSubOperatorAdded(subOperator, index);
183        return true;
184      } else {
185        mySubOperators.RemoveAt(index);
186        return false;
187      }
188    }
189    /// <inheritdoc cref="IOperator.TryAddSubOperator(HeuristicLab.Core.IOperator, int, out
190    /// System.Collections.Generic.ICollection&lt;HeuristicLab.Core.IConstraint&gt;)"/>
191    /// <param name="subOperator">The sub operator to add.</param>
192    /// <remarks>Calls <see cref="OnSubOperatorAdded"/>.</remarks>
193    public virtual bool TryAddSubOperator(IOperator subOperator, int index, out ICollection<IConstraint> violatedConstraints) {
194      mySubOperators.Insert(index, subOperator);
195      if (IsValid(out violatedConstraints)) {
196        OnSubOperatorAdded(subOperator, index);
197        return true;
198      } else {
199        mySubOperators.RemoveAt(index);
200        return false;
201      }
202    }
203    /// <inheritdoc/>
204    /// <remarks>Calls <see cref="OnSubOperatorRemoved"/>.</remarks>
205    public virtual void RemoveSubOperator(int index) {
206      IOperator op = mySubOperators[index];
207      mySubOperators.RemoveAt(index);
208      OnSubOperatorRemoved(op, index);
209    }
210    /// <inheritdoc/>
211    /// <remarks>Calls <see cref="OnSubOperatorRemoved"/>.</remarks>
212    public virtual bool TryRemoveSubOperator(int index) {
213      IOperator op = mySubOperators[index];
214      mySubOperators.RemoveAt(index);
215      if (IsValid()) {
216        OnSubOperatorRemoved(op, index);
217        return true;
218      } else {
219        mySubOperators.Insert(index, op);
220        return false;
221      }
222    }
223    /// <inheritdoc/>
224    /// <remarks>Calls <see cref="OnSubOperatorRemoved"/>.</remarks>
225    public virtual bool TryRemoveSubOperator(int index, out ICollection<IConstraint> violatedConstraints) {
226      IOperator op = mySubOperators[index];
227      mySubOperators.RemoveAt(index);
228      if (IsValid(out violatedConstraints)) {
229        OnSubOperatorRemoved(op, index);
230        return true;
231      } else {
232        mySubOperators.Insert(index, op);
233        return false;
234      }
235    }
236    #endregion
237
238    #region VariableInfo Methods
239    /// <inheritdoc/>
240    public virtual IVariableInfo GetVariableInfo(string formalName) {
241      IVariableInfo info;
242      if (myVariableInfos.TryGetValue(formalName, out info))
243        return info;
244      else
245        return null;
246    }
247    /// <inheritdoc/>
248    /// <remarks>Calls <see cref="OnVariableInfoAdded"/>.</remarks>
249    public virtual void AddVariableInfo(IVariableInfo variableInfo) {
250      myVariableInfos.Add(variableInfo.FormalName, variableInfo);
251      OnVariableInfoAdded(variableInfo);
252    }
253    /// <inheritdoc/>
254    /// <remarks>Calls <see cref="OnVariableInfoAdded"/>.</remarks>
255    public virtual bool TryAddVariableInfo(IVariableInfo variableInfo) {
256      myVariableInfos.Add(variableInfo.FormalName, variableInfo);
257      if (IsValid()) {
258        OnVariableInfoAdded(variableInfo);
259        return true;
260      } else {
261        myVariableInfos.Remove(variableInfo.FormalName);
262        return false;
263      }
264    }
265    /// <inheritdoc/>
266    /// <remarks>Calls <see cref="OnVariableInfoAdded"/>.</remarks>
267    public virtual bool TryAddVariableInfo(IVariableInfo variableInfo, out ICollection<IConstraint> violatedConstraints) {
268      myVariableInfos.Add(variableInfo.FormalName, variableInfo);
269      if (IsValid(out violatedConstraints)) {
270        OnVariableInfoAdded(variableInfo);
271        return true;
272      } else {
273        myVariableInfos.Remove(variableInfo.FormalName);
274        return false;
275      }
276    }
277    /// <inheritdoc/>
278    /// <remarks>Calls <see cref="OnVariableInfoRemoved"/>.</remarks>
279    public virtual void RemoveVariableInfo(string formalName) {
280      IVariableInfo variableInfo;
281      if (myVariableInfos.TryGetValue(formalName, out variableInfo)) {
282        myVariableInfos.Remove(formalName);
283        OnVariableInfoRemoved(variableInfo);
284      }
285    }
286    /// <inheritdoc/>
287    /// <remarks>Calls <see cref="OnVariableInfoRemoved"/>.</remarks>
288    public virtual bool TryRemoveVariableInfo(string formalName) {
289      IVariableInfo variableInfo;
290      if (myVariableInfos.TryGetValue(formalName, out variableInfo)) {
291        myVariableInfos.Remove(formalName);
292        if (IsValid()) {
293          OnVariableInfoRemoved(variableInfo);
294          return true;
295        } else {
296          myVariableInfos.Add(formalName, variableInfo);
297          return false;
298        }
299      }
300      return true;
301    }
302    /// <inheritdoc/>
303    /// <remarks>Calls <see cref="OnVariableInfoRemoved"/>.</remarks>
304    public virtual bool TryRemoveVariableInfo(string formalName, out ICollection<IConstraint> violatedConstraints) {
305      IVariableInfo variableInfo;
306      if (myVariableInfos.TryGetValue(formalName, out variableInfo)) {
307        myVariableInfos.Remove(formalName);
308        if (IsValid(out violatedConstraints)) {
309          OnVariableInfoRemoved(variableInfo);
310          return true;
311        } else {
312          myVariableInfos.Add(formalName, variableInfo);
313          return false;
314        }
315      }
316      violatedConstraints = new List<IConstraint>();
317      return true;
318    }
319    #endregion
320
321    #region Variable Methods
322    /// <inheritdoc/>
323    public virtual IVariable GetVariable(string name) {
324      IVariable variable;
325      if (myVariables.TryGetValue(name, out variable))
326        return variable;
327      else
328        return null;
329    }
330    /// <inheritdoc/>
331    /// <remarks>Calls <see cref="OnVariableAdded"/> and adds <c>NameChanging</c> and <c>NameChanged</c>
332    /// event handlers.</remarks>
333    public virtual void AddVariable(IVariable variable) {
334      myVariables.Add(variable.Name, variable);
335      variable.NameChanging += new EventHandler<NameChangingEventArgs>(Variable_NameChanging);
336      variable.NameChanged += new EventHandler(Variable_NameChanged);
337      OnVariableAdded(variable);
338    }
339    /// <inheritdoc/>
340    /// <remarks>Calls <see cref="OnVariableAdded"/> and adds <c>NameChanging</c> and <c>NameChanged</c>
341    /// event handlers.</remarks>
342    public virtual bool TryAddVariable(IVariable variable) {
343      myVariables.Add(variable.Name, variable);
344      if (IsValid()) {
345        variable.NameChanging += new EventHandler<NameChangingEventArgs>(Variable_NameChanging);
346        variable.NameChanged += new EventHandler(Variable_NameChanged);
347        OnVariableAdded(variable);
348        return true;
349      } else {
350        myVariableInfos.Remove(variable.Name);
351        return false;
352      }
353    }
354    /// <inheritdoc/>
355    /// <remarks>Calls <see cref="OnVariableAdded"/> and adds <c>NameChanging</c> and <c>NameChanged</c>
356    /// event handlers.</remarks>
357    public virtual bool TryAddVariable(IVariable variable, out ICollection<IConstraint> violatedConstraints) {
358      myVariables.Add(variable.Name, variable);
359      if (IsValid(out violatedConstraints)) {
360        variable.NameChanging += new EventHandler<NameChangingEventArgs>(Variable_NameChanging);
361        variable.NameChanged += new EventHandler(Variable_NameChanged);
362        OnVariableAdded(variable);
363        return true;
364      } else {
365        myVariableInfos.Remove(variable.Name);
366        return false;
367      }
368    }
369    /// <inheritdoc/>
370    /// <remarks>Calls <see cref="OnVariableRemoved"/> and removes <c>NameChanging</c> and <c>NameChanged</c>
371    /// event handlers.</remarks>
372    public virtual void RemoveVariable(string name) {
373      IVariable variable;
374      if (myVariables.TryGetValue(name, out variable)) {
375        variable.NameChanging -= new EventHandler<NameChangingEventArgs>(Variable_NameChanging);
376        variable.NameChanged -= new EventHandler(Variable_NameChanged);
377        myVariables.Remove(name);
378        OnVariableRemoved(variable);
379      }
380    }
381    /// <inheritdoc/>
382    /// <remarks>Calls <see cref="OnVariableRemoved"/> and removes <c>NameChanging</c> and <c>NameChanged</c>
383    /// event handlers.</remarks>
384    public virtual bool TryRemoveVariable(string name) {
385      IVariable variable;
386      if (myVariables.TryGetValue(name, out variable)) {
387        myVariables.Remove(name);
388        if (IsValid()) {
389          variable.NameChanging -= new EventHandler<NameChangingEventArgs>(Variable_NameChanging);
390          variable.NameChanged -= new EventHandler(Variable_NameChanged);
391          OnVariableRemoved(variable);
392          return true;
393        } else {
394          myVariables.Add(name, variable);
395          return false;
396        }
397      }
398      return true;
399    }
400    /// <inheritdoc/>
401    /// <remarks>Calls <see cref="OnVariableRemoved"/> and removes <c>NameChanging</c> and <c>NameChanged</c>
402    /// event handlers.</remarks>
403    public virtual bool TryRemoveVariable(string name, out ICollection<IConstraint> violatedConstraints) {
404      IVariable variable;
405      if (myVariables.TryGetValue(name, out variable)) {
406        myVariables.Remove(name);
407        if (IsValid(out violatedConstraints)) {
408          variable.NameChanging -= new EventHandler<NameChangingEventArgs>(Variable_NameChanging);
409          variable.NameChanged -= new EventHandler(Variable_NameChanged);
410          OnVariableRemoved(variable);
411          return true;
412        } else {
413          myVariables.Add(name, variable);
414          return false;
415        }
416      }
417      violatedConstraints = new List<IConstraint>();
418      return true;
419    }
420    private void Variable_NameChanging(object sender, NameChangingEventArgs e) {
421      e.Cancel = myVariables.ContainsKey(e.Name);
422    }
423    private void Variable_NameChanged(object sender, EventArgs e) {
424      IVariable variable = (IVariable)sender;
425      string oldName = null;
426      foreach (KeyValuePair<string, IVariable> element in myVariables) {
427        if (element.Value == variable)
428          oldName = element.Key;
429      }
430      myVariables.Remove(oldName);
431      myVariables.Add(variable.Name, variable);
432    }
433    /// <inheritdoc cref="IOperator.GetVariableValue&lt;T&gt;(string, HeuristicLab.Core.IScope, bool)"/>
434    ///  <remarks>Calls <see cref="GetVariableValue&lt;T&gt;(string, HeuristicLab.Core.IScope, bool, bool)"/>
435    /// with <c>throwOnError</c> set to <c>false</c>.</remarks>
436    public T GetVariableValue<T>(string formalName, IScope scope, bool recursiveLookup) where T : class, IItem {
437      return GetVariableValue<T>(formalName, scope, recursiveLookup, true);
438    }
439    /// <inheritdoc cref="IOperator.GetVariableValue&lt;T&gt;(string, HeuristicLab.Core.IScope, bool, bool)"/>
440    /// <remarks>Calls
441    /// <see cref="GetVariableValue(string, HeuristicLab.Core.IScope, bool, bool)"/>.</remarks>
442    public T GetVariableValue<T>(string formalName, IScope scope, bool recursiveLookup, bool throwOnError) where T : class, IItem {
443      return (T)GetVariableValue(formalName, scope, recursiveLookup, throwOnError);
444    }
445    /// <inheritdoc cref="IOperator.GetVariableValue(string, HeuristicLab.Core.IScope, bool)"/>
446    /// <remarks>Calls <see cref="GetVariableValue(string, HeuristicLab.Core.IScope, bool, bool)"/>
447    /// with <c>throwOnError</c> set to <c>false</c>.</remarks>
448    public IItem GetVariableValue(string formalName, IScope scope, bool recursiveLookup) {
449      return GetVariableValue(formalName, scope, recursiveLookup, true);
450    }
451    /// <inheritdoc cref="IOperator.GetVariableValue(string, HeuristicLab.Core.IScope, bool, bool)"/>
452    public virtual IItem GetVariableValue(string formalName, IScope scope, bool recursiveLookup, bool throwOnError) {
453      IVariableInfo info = GetVariableInfo(formalName);
454      if (info.Local) {
455        IVariable variable;
456        if (myVariables.TryGetValue(info.ActualName, out variable))
457          return variable.Value;
458        else {
459          if (throwOnError)
460            throw new ArgumentException("Variable " + info.ActualName + " not found");
461          else
462            return null;
463        }
464      } else {
465        return scope.GetVariableValue(formalName, recursiveLookup, throwOnError);
466      }
467    }
468    #endregion
469    /// <inheritdoc/>
470    public virtual IOperation Execute(IScope scope) {
471      myCanceled = false;
472
473      foreach (IVariableInfo variableInfo in VariableInfos)
474        scope.AddAlias(variableInfo.FormalName, variableInfo.ActualName);
475
476      IOperation next = Apply(scope);
477
478      foreach (IVariableInfo variableInfo in VariableInfos)
479        scope.RemoveAlias(variableInfo.FormalName);
480
481      OnExecuted();
482      return next;
483    }
484    /// <inheritdoc/>
485    /// <remarks>Sets property <see cref="Canceled"/> to <c>true</c>.</remarks>
486    public virtual void Abort() {
487      myCanceled = true;
488    }
489    /// <summary>
490    /// Performs the current operator on the specified <paramref name="scope"/>.
491    /// </summary>
492    /// <param name="scope">The scope where to execute the operator</param>
493    /// <returns><c>null</c>.</returns>
494    public virtual IOperation Apply(IScope scope) {
495      return null;
496    }
497    /// <inheritdoc/>
498    public event EventHandler NameChanged;
499    /// <summary>
500    /// Fires a new <c>NameChanged</c> event.
501    /// </summary>
502    protected virtual void OnNameChanged() {
503      if (NameChanged != null) {
504        NameChanged(this, new EventArgs());
505      }
506    }
507    /// <inheritdoc/>
508    public event EventHandler BreakpointChanged;
509    /// <summary>
510    /// Fires a new <c>BreakpointChanged</c> event.
511    /// </summary>
512    protected virtual void OnBreakpointChanged() {
513      if (BreakpointChanged != null) {
514        BreakpointChanged(this, new EventArgs());
515      }
516    }
517    /// <inheritdoc/>
518    public event EventHandler<OperatorIndexEventArgs> SubOperatorAdded;
519    /// <summary>
520    /// Fires a new <c>SubOperatorAdded</c> event.
521    /// </summary>
522    /// <param name="subOperator">The sub operator that has been added.</param>
523    /// <param name="index">The position where the operator has been added.</param>
524    protected virtual void OnSubOperatorAdded(IOperator subOperator, int index) {
525      if (SubOperatorAdded != null)
526        SubOperatorAdded(this, new OperatorIndexEventArgs(subOperator, index));
527    }
528    /// <inheritdoc/>
529    public event EventHandler<OperatorIndexEventArgs> SubOperatorRemoved;
530    /// <summary>
531    /// Fires a new <c>SubOperatorRemoved</c> event.
532    /// </summary>
533    /// <param name="subOperator">The sub operator that has been removed.</param>
534    /// <param name="index">The position where the operator has been removed.</param>
535    protected virtual void OnSubOperatorRemoved(IOperator subOperator, int index) {
536      if (SubOperatorRemoved != null)
537        SubOperatorRemoved(this, new OperatorIndexEventArgs(subOperator, index));
538    }
539    /// <inheritdoc/>
540    public event EventHandler<VariableInfoEventArgs> VariableInfoAdded;
541    /// <summary>
542    /// Fires a new <c>VariableInfoAdded</c> event.
543    /// </summary>
544    /// <param name="variableInfo">The variable info that has been added.</param>
545    protected virtual void OnVariableInfoAdded(IVariableInfo variableInfo) {
546      if (VariableInfoAdded != null)
547        VariableInfoAdded(this, new VariableInfoEventArgs(variableInfo));
548    }
549    /// <inheritdoc/>
550    public event EventHandler<VariableInfoEventArgs> VariableInfoRemoved;
551    /// <summary>
552    /// Fires a new <c>VariableInfoRemoved</c> event.
553    /// </summary>
554    /// <param name="variableInfo">The variable info that has been removed.</param>
555    protected virtual void OnVariableInfoRemoved(IVariableInfo variableInfo) {
556      if (VariableInfoRemoved != null)
557        VariableInfoRemoved(this, new VariableInfoEventArgs(variableInfo));
558    }
559    /// <inheritdoc/>
560    public event EventHandler<VariableEventArgs> VariableAdded;
561    /// <summary>
562    /// Fires a new <c>VariableAdded</c> event.
563    /// </summary>
564    /// <param name="variable">The variable that has been added.</param>
565    protected virtual void OnVariableAdded(IVariable variable) {
566      if (VariableAdded != null)
567        VariableAdded(this, new VariableEventArgs(variable));
568    }
569    /// <inheritdoc/>
570    public event EventHandler<VariableEventArgs> VariableRemoved;
571    /// <summary>
572    /// Fires a new <c>VariableRemoved</c> event.
573    /// </summary>
574    /// <param name="variable">The variable that has been removed</param>
575    protected virtual void OnVariableRemoved(IVariable variable) {
576      if (VariableRemoved != null)
577        VariableRemoved(this, new VariableEventArgs(variable));
578    }
579    /// <inheritdoc/>
580    public event EventHandler Executed;
581    /// <summary>
582    /// Fires a new <c>Executed</c> event.
583    /// </summary>
584    protected virtual void OnExecuted() {
585      if (Executed != null) {
586        Executed(this, new EventArgs());
587      }
588    }
589
590    #region Persistence Methods
591    /// <summary>
592    /// Saves the current instance as <see cref="XmlNode"/> in the specified <paramref name="document"/>.
593    /// </summary>
594    /// <remarks>
595    /// Calls <see cref="ConstrainedItemBase.GetXmlNode"/> of base class <see cref="ConstrainedItemBase"/>.
596    /// <br/>A quick overview how the single elements of the current instance are saved:
597    /// <list type="bullet">
598    /// <item>
599    /// <term>Name: </term>
600    /// <description>Saved as an <see cref="XmlAttribute"/> with the name <c>Name</c>.</description>
601    /// </item>
602    /// <item>
603    /// <term>Breakpoint: </term>
604    /// <description>Is only saved if it set to <c>true</c>.
605    /// Saved as an <see cref="XmlAttribute"/> with the name <c>Breakpoint</c>.</description>
606    /// </item>
607    /// <item>
608    /// <term>Sub operators: </term>
609    /// <description>Saved as child node with tag name <c>SubOperators</c>. All sub operators are themselves
610    /// saved as child nodes.</description>
611    /// </item>
612    /// <item>
613    /// <term>Variable infos: </term>
614    /// <description>Saved as child node with tag name <c>VariableInfos</c>. All variable infos are themselves
615    /// saved as child nodes.</description>
616    /// </item>
617    /// <item>
618    /// <term>Variables: </term>
619    /// <description>Saved as child node with tag name <c>Variables</c>. All variables are themselves
620    /// saved as child nodes.</description>
621    /// </item>
622    /// </list>
623    /// </remarks>
624    /// <param name="name">The (tag)name of the <see cref="XmlNode"/>.</param>
625    /// <param name="document">The <see cref="XmlDocument"/> where to save the data.</param>
626    /// <param name="persistedObjects">The dictionary of all already persisted objects. (Needed to avoid cycles.)</param>
627    /// <returns>The saved <see cref="XmlNode"/>.</returns>
628    public override XmlNode GetXmlNode(string name, XmlDocument document, IDictionary<Guid, IStorable> persistedObjects) {
629      XmlNode node = base.GetXmlNode(name, document, persistedObjects);
630      XmlAttribute nameAttribute = document.CreateAttribute("Name");
631      nameAttribute.Value = Name;
632      node.Attributes.Append(nameAttribute);
633      if (Breakpoint) {
634        XmlAttribute breakpointAttribute = document.CreateAttribute("Breakpoint");
635        breakpointAttribute.Value = Breakpoint.ToString();
636        node.Attributes.Append(breakpointAttribute);
637      }
638      XmlNode subOperatorsNode = document.CreateNode(XmlNodeType.Element, "SubOperators", null);
639      for (int i = 0; i < SubOperators.Count; i++)
640        subOperatorsNode.AppendChild(PersistenceManager.Persist(SubOperators[i], document, persistedObjects));
641      node.AppendChild(subOperatorsNode);
642      XmlNode infosNode = document.CreateNode(XmlNodeType.Element, "VariableInfos", null);
643      foreach (IVariableInfo info in myVariableInfos.Values)
644        infosNode.AppendChild(PersistenceManager.Persist(info, document, persistedObjects));
645      node.AppendChild(infosNode);
646      XmlNode variablesNode = document.CreateNode(XmlNodeType.Element, "Variables", null);
647      foreach (IVariable variable in myVariables.Values)
648        variablesNode.AppendChild(PersistenceManager.Persist(variable, document, persistedObjects));
649      node.AppendChild(variablesNode);
650      return node;
651    }
652    /// <summary>
653    /// Loads the persisted operation from the specified <paramref name="node"/>.
654    /// </summary>
655    /// <remarks>Calls <see cref="ConstrainedItemBase.Populate"/> of base class
656    /// <see cref="ConstrainedItemBase"/>.
657    /// For informations how the different elements must be saved please see <see cref="GetXmlNode"/>.</remarks>
658    /// <param name="node">The <see cref="XmlNode"/> where the operation is saved.</param>
659    /// <param name="restoredObjects">A dictionary of all already restored objects. (Needed to avoid cycles.)</param>
660    public override void Populate(XmlNode node, IDictionary<Guid, IStorable> restoredObjects) {
661      base.Populate(node, restoredObjects);
662      myName = node.Attributes["Name"].Value;
663      if (node.Attributes["Breakpoint"] != null)
664        myBreakpoint = bool.Parse(node.Attributes["Breakpoint"].Value);
665      XmlNode subOperatorsNode = node.SelectSingleNode("SubOperators");
666      for (int i = 0; i < subOperatorsNode.ChildNodes.Count; i++)
667        AddSubOperator((IOperator)PersistenceManager.Restore(subOperatorsNode.ChildNodes[i], restoredObjects));
668      XmlNode infosNode = node.SelectSingleNode("VariableInfos");
669      myVariableInfos.Clear();
670      foreach (XmlNode infoNode in infosNode.ChildNodes)
671        AddVariableInfo((IVariableInfo)PersistenceManager.Restore(infoNode, restoredObjects));
672      XmlNode variablesNode = node.SelectSingleNode("Variables");
673      myVariables.Clear();
674      foreach (XmlNode variableNode in variablesNode.ChildNodes)
675        AddVariable((IVariable)PersistenceManager.Restore(variableNode, restoredObjects));
676    }
677    #endregion
678  }
679}
Note: See TracBrowser for help on using the repository browser.