Free cookie consent management tool by TermsFeed Policy Generator

source: branches/CEDMA-Exporter-715/sources/HeuristicLab.Core/3.2/OperatorBase.cs @ 2227

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

Reverted r1847 after discussion with swagner. Instead each operator should decide independently what happens after abort and adapt the returned next operation accordingly. #633 (Engines do not handle abortion of operators correctly)

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.