Free cookie consent management tool by TermsFeed Policy Generator

source: trunk/sources/HeuristicLab.Core/OperatorBase.cs @ 1450

Last change on this file since 1450 was 776, checked in by vdorfer, 15 years ago

Created API documentation for HeuristicLab.Core namespace (#331)

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