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

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

Register event listeners during deserialization. (#603)

File size: 24.4 KB
Line 
1#region License Information
2/* HeuristicLab
3 * Copyright (C) 2002-2008 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
4 *
5 * This file is part of HeuristicLab.
6 *
7 * HeuristicLab is free software: you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation, either version 3 of the License, or
10 * (at your option) any later version.
11 *
12 * HeuristicLab is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15 * GNU General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License
18 * along with HeuristicLab. If not, see <http://www.gnu.org/licenses/>.
19 */
20#endregion
21
22using System;
23using System.Collections.Generic;
24using System.Text;
25using System.Xml;
26using HeuristicLab.Persistence.Default.Decomposers.Storable;
27
28namespace HeuristicLab.Core {
29  /// <summary>
30  /// The base class for all operators.
31  /// </summary>
32  public abstract class OperatorBase : ConstrainedItemBase, IOperator {
33
34    [Storable]
35    private string myName;
36    /// <summary>
37    /// Gets or sets the name of the operator.
38    /// </summary>
39    /// <remarks>Calls <see cref="OnNameChanged"/> in the setter.</remarks>
40    public string Name {
41      get { return myName; }
42      set {
43        if (myName != value) {
44          myName = value;
45          OnNameChanged();
46        }
47      }
48    }
49    /// <summary>
50    /// Gets the description of the current operator.
51    /// </summary>
52    /// <remarks>Returns "No operator description available" if the method is not overriden.</remarks>
53    public virtual string Description {
54      get { return "No operator description available."; }
55    }
56    /// <summary>
57    /// Flag whether the current instance has been canceled.
58    /// </summary>
59    protected bool myCanceled;
60    /// <inheritdoc/>
61    public bool Canceled {
62      get { return myCanceled; }
63    }
64
65    [Storable]
66    private bool myBreakpoint;
67    /// <inheritdoc/>
68    /// <remarks>Calls <see cref="OnBreakpointChanged"/> in the setter.</remarks>
69    public bool Breakpoint {
70      get { return myBreakpoint; }
71      set {
72        if (value != myBreakpoint) {
73          myBreakpoint = value;
74          OnBreakpointChanged();
75        }
76      }
77    }
78
79    [Storable]
80    private List<IOperator> mySubOperators;
81    /// <summary>
82    /// Gets a list of all suboperators.
83    /// <note type="caution"> Returns the suboperators read-only!</note>
84    /// </summary>
85    public virtual IList<IOperator> SubOperators {
86      get { return mySubOperators.AsReadOnly(); }
87    }
88
89    [Storable]
90    private Dictionary<string, IVariableInfo> myVariableInfos;
91    /// <inheritdoc/>
92    public virtual ICollection<IVariableInfo> VariableInfos {
93      get { return myVariableInfos.Values; }
94    }
95   
96    private Dictionary<string, IVariable> myVariables;
97    /// <inheritdoc/>   
98    public virtual ICollection<IVariable> Variables {
99      get { return myVariables.Values; }
100    }
101
102    [Storable(Name="Variables")]
103    private List<IVariable> VariablePersistence {
104      get { return new List<IVariable>(myVariables.Values); }
105      set {
106        foreach (IVariable var in value) {
107          AddVariable(var);
108        }
109      }
110    }
111
112    /// <summary>
113    /// Initializes a new instance of <see cref="OperatorBase"/> setting the breakpoint flag and
114    /// the canceled flag to <c>false</c> and the name of the operator to the type name.
115    /// </summary>
116    protected OperatorBase() {
117      myName = this.GetType().Name;
118      myCanceled = false;
119      myBreakpoint = false;
120      mySubOperators = new List<IOperator>();
121      myVariableInfos = new Dictionary<string, IVariableInfo>();
122      myVariables = new Dictionary<string, IVariable>();
123    }
124
125    /// <summary>
126    /// Clones the current instance (deep clone).
127    /// </summary>
128    /// <remarks>Clones also sub operators, variables and variable infos.</remarks>
129    /// <param name="clonedObjects">Dictionary of all already cloned objects. (Needed to avoid cycles.)</param>
130    /// <returns>The cloned object as <see cref="OperatorBase"/>.</returns>
131    public override object Clone(IDictionary<Guid, object> clonedObjects) {
132      OperatorBase clone = (OperatorBase)base.Clone(clonedObjects);
133      clone.myName = Name;
134      clone.mySubOperators.Clear();
135      for (int i = 0; i < SubOperators.Count; i++)
136        clone.AddSubOperator((IOperator)Auxiliary.Clone(SubOperators[i], clonedObjects));
137      clone.myVariableInfos.Clear();
138      foreach (IVariableInfo variableInfo in myVariableInfos.Values)
139        clone.AddVariableInfo((IVariableInfo)Auxiliary.Clone(variableInfo, clonedObjects));
140      clone.myVariables.Clear();
141      foreach (IVariable variable in myVariables.Values)
142        clone.AddVariable((IVariable)Auxiliary.Clone(variable, clonedObjects));
143      return clone;
144    }
145
146    /// <summary>
147    /// Creates a new instance of <see cref="OperatorBaseView"/> to represent the current operator
148    /// visually.
149    /// </summary>
150    /// <returns>The created view as <see cref="OperatorBaseView"/>.</returns>
151    public override IView CreateView() {
152      return new OperatorBaseView(this);
153    }
154
155    #region SubOperator Methods
156    /// <inheritdoc cref="HeuristicLab.Core.IOperator.AddSubOperator(HeuristicLab.Core.IOperator)"/>
157    /// <param name="subOperator">The sub operator to add.</param>
158    /// <remarks>Calls <see cref="OnSubOperatorAdded"/>.</remarks>
159    public virtual void AddSubOperator(IOperator subOperator) {
160      mySubOperators.Add(subOperator);
161      OnSubOperatorAdded(subOperator, mySubOperators.Count - 1);
162    }
163    /// <inheritdoc cref="IOperator.TryAddSubOperator(HeuristicLab.Core.IOperator)"/>
164    /// <param name="subOperator">The sub operator to add.</param>
165    /// <remarks>Calls <see cref="OnSubOperatorAdded"/>.</remarks>
166    public virtual bool TryAddSubOperator(IOperator subOperator) {
167      mySubOperators.Add(subOperator);
168      if (IsValid()) {
169        OnSubOperatorAdded(subOperator, mySubOperators.Count - 1);
170        return true;
171      } else {
172        mySubOperators.RemoveAt(mySubOperators.Count - 1);
173        return false;
174      }
175    }
176    /// <inheritdoc cref="HeuristicLab.Core.IOperator.TryAddSubOperator(HeuristicLab.Core.IOperator,
177    /// out System.Collections.Generic.ICollection&lt;HeuristicLab.Core.IConstraint&gt;)"/>
178    /// <param name="subOperator">The sub operator to add.</param>
179    /// <remarks>Calls <see cref="OnSubOperatorAdded"/>.</remarks>
180    public virtual bool TryAddSubOperator(IOperator subOperator, out ICollection<IConstraint> violatedConstraints) {
181      mySubOperators.Add(subOperator);
182      if (IsValid(out violatedConstraints)) {
183        OnSubOperatorAdded(subOperator, mySubOperators.Count - 1);
184        return true;
185      } else {
186        mySubOperators.RemoveAt(mySubOperators.Count - 1);
187        return false;
188      }
189    }
190    /// <inheritdoc cref="HeuristicLab.Core.IOperator.AddSubOperator(HeuristicLab.Core.IOperator, int)"/>
191    /// <param name="subOperator">The sub operator to add.</param>
192    /// <remarks>Calls <see cref="OnSubOperatorAdded"/>.</remarks>
193    public virtual void AddSubOperator(IOperator subOperator, int index) {
194      mySubOperators.Insert(index, subOperator);
195      OnSubOperatorAdded(subOperator, index);
196    }
197    /// <inheritdoc cref="IOperator.TryAddSubOperator(HeuristicLab.Core.IOperator, int)"/>
198    /// <param name="subOperator">The sub operator to add.</param>
199    /// <remarks>Calls <see cref="OnSubOperatorAdded"/>.</remarks>
200    public virtual bool TryAddSubOperator(IOperator subOperator, int index) {
201      mySubOperators.Insert(index, subOperator);
202      if (IsValid()) {
203        OnSubOperatorAdded(subOperator, index);
204        return true;
205      } else {
206        mySubOperators.RemoveAt(index);
207        return false;
208      }
209    }
210    /// <inheritdoc cref="IOperator.TryAddSubOperator(HeuristicLab.Core.IOperator, int, out
211    /// System.Collections.Generic.ICollection&lt;HeuristicLab.Core.IConstraint&gt;)"/>
212    /// <param name="subOperator">The sub operator to add.</param>
213    /// <remarks>Calls <see cref="OnSubOperatorAdded"/>.</remarks>
214    public virtual bool TryAddSubOperator(IOperator subOperator, int index, out ICollection<IConstraint> violatedConstraints) {
215      mySubOperators.Insert(index, subOperator);
216      if (IsValid(out violatedConstraints)) {
217        OnSubOperatorAdded(subOperator, index);
218        return true;
219      } else {
220        mySubOperators.RemoveAt(index);
221        return false;
222      }
223    }
224    /// <inheritdoc/>
225    /// <remarks>Calls <see cref="OnSubOperatorRemoved"/>.</remarks>
226    public virtual void RemoveSubOperator(int index) {
227      IOperator op = mySubOperators[index];
228      mySubOperators.RemoveAt(index);
229      OnSubOperatorRemoved(op, index);
230    }
231    /// <inheritdoc/>
232    /// <remarks>Calls <see cref="OnSubOperatorRemoved"/>.</remarks>
233    public virtual bool TryRemoveSubOperator(int index) {
234      IOperator op = mySubOperators[index];
235      mySubOperators.RemoveAt(index);
236      if (IsValid()) {
237        OnSubOperatorRemoved(op, index);
238        return true;
239      } else {
240        mySubOperators.Insert(index, op);
241        return false;
242      }
243    }
244    /// <inheritdoc/>
245    /// <remarks>Calls <see cref="OnSubOperatorRemoved"/>.</remarks>
246    public virtual bool TryRemoveSubOperator(int index, out ICollection<IConstraint> violatedConstraints) {
247      IOperator op = mySubOperators[index];
248      mySubOperators.RemoveAt(index);
249      if (IsValid(out violatedConstraints)) {
250        OnSubOperatorRemoved(op, index);
251        return true;
252      } else {
253        mySubOperators.Insert(index, op);
254        return false;
255      }
256    }
257    #endregion
258
259    #region VariableInfo Methods
260    /// <inheritdoc/>
261    public virtual IVariableInfo GetVariableInfo(string formalName) {
262      IVariableInfo info;
263      if (myVariableInfos.TryGetValue(formalName, out info))
264        return info;
265      else
266        return null;
267    }
268    /// <inheritdoc/>
269    /// <remarks>Calls <see cref="OnVariableInfoAdded"/>.</remarks>
270    public virtual void AddVariableInfo(IVariableInfo variableInfo) {
271      myVariableInfos.Add(variableInfo.FormalName, variableInfo);
272      OnVariableInfoAdded(variableInfo);
273    }
274    /// <inheritdoc/>
275    /// <remarks>Calls <see cref="OnVariableInfoAdded"/>.</remarks>
276    public virtual bool TryAddVariableInfo(IVariableInfo variableInfo) {
277      myVariableInfos.Add(variableInfo.FormalName, variableInfo);
278      if (IsValid()) {
279        OnVariableInfoAdded(variableInfo);
280        return true;
281      } else {
282        myVariableInfos.Remove(variableInfo.FormalName);
283        return false;
284      }
285    }
286    /// <inheritdoc/>
287    /// <remarks>Calls <see cref="OnVariableInfoAdded"/>.</remarks>
288    public virtual bool TryAddVariableInfo(IVariableInfo variableInfo, out ICollection<IConstraint> violatedConstraints) {
289      myVariableInfos.Add(variableInfo.FormalName, variableInfo);
290      if (IsValid(out violatedConstraints)) {
291        OnVariableInfoAdded(variableInfo);
292        return true;
293      } else {
294        myVariableInfos.Remove(variableInfo.FormalName);
295        return false;
296      }
297    }
298    /// <inheritdoc/>
299    /// <remarks>Calls <see cref="OnVariableInfoRemoved"/>.</remarks>
300    public virtual void RemoveVariableInfo(string formalName) {
301      IVariableInfo variableInfo;
302      if (myVariableInfos.TryGetValue(formalName, out variableInfo)) {
303        myVariableInfos.Remove(formalName);
304        OnVariableInfoRemoved(variableInfo);
305      }
306    }
307    /// <inheritdoc/>
308    /// <remarks>Calls <see cref="OnVariableInfoRemoved"/>.</remarks>
309    public virtual bool TryRemoveVariableInfo(string formalName) {
310      IVariableInfo variableInfo;
311      if (myVariableInfos.TryGetValue(formalName, out variableInfo)) {
312        myVariableInfos.Remove(formalName);
313        if (IsValid()) {
314          OnVariableInfoRemoved(variableInfo);
315          return true;
316        } else {
317          myVariableInfos.Add(formalName, variableInfo);
318          return false;
319        }
320      }
321      return true;
322    }
323    /// <inheritdoc/>
324    /// <remarks>Calls <see cref="OnVariableInfoRemoved"/>.</remarks>
325    public virtual bool TryRemoveVariableInfo(string formalName, out ICollection<IConstraint> violatedConstraints) {
326      IVariableInfo variableInfo;
327      if (myVariableInfos.TryGetValue(formalName, out variableInfo)) {
328        myVariableInfos.Remove(formalName);
329        if (IsValid(out violatedConstraints)) {
330          OnVariableInfoRemoved(variableInfo);
331          return true;
332        } else {
333          myVariableInfos.Add(formalName, variableInfo);
334          return false;
335        }
336      }
337      violatedConstraints = new List<IConstraint>();
338      return true;
339    }
340    #endregion
341
342    #region Variable Methods
343    /// <inheritdoc/>
344    public virtual IVariable GetVariable(string name) {
345      IVariable variable;
346      if (myVariables.TryGetValue(name, out variable))
347        return variable;
348      else
349        return null;
350    }
351    /// <inheritdoc/>
352    /// <remarks>Calls <see cref="OnVariableAdded"/> and adds <c>NameChanging</c> and <c>NameChanged</c>
353    /// event handlers.</remarks>
354    public virtual void AddVariable(IVariable variable) {
355      myVariables.Add(variable.Name, variable);
356      variable.NameChanging += new EventHandler<NameChangingEventArgs>(Variable_NameChanging);
357      variable.NameChanged += new EventHandler(Variable_NameChanged);
358      OnVariableAdded(variable);
359    }
360    /// <inheritdoc/>
361    /// <remarks>Calls <see cref="OnVariableAdded"/> and adds <c>NameChanging</c> and <c>NameChanged</c>
362    /// event handlers.</remarks>
363    public virtual bool TryAddVariable(IVariable variable) {
364      myVariables.Add(variable.Name, variable);
365      if (IsValid()) {
366        variable.NameChanging += new EventHandler<NameChangingEventArgs>(Variable_NameChanging);
367        variable.NameChanged += new EventHandler(Variable_NameChanged);
368        OnVariableAdded(variable);
369        return true;
370      } else {
371        myVariableInfos.Remove(variable.Name);
372        return false;
373      }
374    }
375    /// <inheritdoc/>
376    /// <remarks>Calls <see cref="OnVariableAdded"/> and adds <c>NameChanging</c> and <c>NameChanged</c>
377    /// event handlers.</remarks>
378    public virtual bool TryAddVariable(IVariable variable, out ICollection<IConstraint> violatedConstraints) {
379      myVariables.Add(variable.Name, variable);
380      if (IsValid(out violatedConstraints)) {
381        variable.NameChanging += new EventHandler<NameChangingEventArgs>(Variable_NameChanging);
382        variable.NameChanged += new EventHandler(Variable_NameChanged);
383        OnVariableAdded(variable);
384        return true;
385      } else {
386        myVariableInfos.Remove(variable.Name);
387        return false;
388      }
389    }
390    /// <inheritdoc/>
391    /// <remarks>Calls <see cref="OnVariableRemoved"/> and removes <c>NameChanging</c> and <c>NameChanged</c>
392    /// event handlers.</remarks>
393    public virtual void RemoveVariable(string name) {
394      IVariable variable;
395      if (myVariables.TryGetValue(name, out variable)) {
396        variable.NameChanging -= new EventHandler<NameChangingEventArgs>(Variable_NameChanging);
397        variable.NameChanged -= new EventHandler(Variable_NameChanged);
398        myVariables.Remove(name);
399        OnVariableRemoved(variable);
400      }
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) {
406      IVariable variable;
407      if (myVariables.TryGetValue(name, out variable)) {
408        myVariables.Remove(name);
409        if (IsValid()) {
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      return true;
420    }
421    /// <inheritdoc/>
422    /// <remarks>Calls <see cref="OnVariableRemoved"/> and removes <c>NameChanging</c> and <c>NameChanged</c>
423    /// event handlers.</remarks>
424    public virtual bool TryRemoveVariable(string name, out ICollection<IConstraint> violatedConstraints) {
425      IVariable variable;
426      if (myVariables.TryGetValue(name, out variable)) {
427        myVariables.Remove(name);
428        if (IsValid(out violatedConstraints)) {
429          variable.NameChanging -= new EventHandler<NameChangingEventArgs>(Variable_NameChanging);
430          variable.NameChanged -= new EventHandler(Variable_NameChanged);
431          OnVariableRemoved(variable);
432          return true;
433        } else {
434          myVariables.Add(name, variable);
435          return false;
436        }
437      }
438      violatedConstraints = new List<IConstraint>();
439      return true;
440    }
441    private void Variable_NameChanging(object sender, NameChangingEventArgs e) {
442      e.Cancel = myVariables.ContainsKey(e.Name);
443    }
444    private void Variable_NameChanged(object sender, EventArgs e) {
445      IVariable variable = (IVariable)sender;
446      string oldName = null;
447      foreach (KeyValuePair<string, IVariable> element in myVariables) {
448        if (element.Value == variable)
449          oldName = element.Key;
450      }
451      myVariables.Remove(oldName);
452      myVariables.Add(variable.Name, variable);
453    }
454    /// <inheritdoc cref="IOperator.GetVariableValue&lt;T&gt;(string, HeuristicLab.Core.IScope, bool)"/>
455    ///  <remarks>Calls <see cref="GetVariableValue&lt;T&gt;(string, HeuristicLab.Core.IScope, bool, bool)"/>
456    /// with <c>throwOnError</c> set to <c>false</c>.</remarks>
457    public T GetVariableValue<T>(string formalName, IScope scope, bool recursiveLookup) where T : class, IItem {
458      return GetVariableValue<T>(formalName, scope, recursiveLookup, true);
459    }
460    /// <inheritdoc cref="IOperator.GetVariableValue&lt;T&gt;(string, HeuristicLab.Core.IScope, bool, bool)"/>
461    /// <remarks>Calls
462    /// <see cref="GetVariableValue(string, HeuristicLab.Core.IScope, bool, bool)"/>.</remarks>
463    public T GetVariableValue<T>(string formalName, IScope scope, bool recursiveLookup, bool throwOnError) where T : class, IItem {
464      return (T)GetVariableValue(formalName, scope, recursiveLookup, throwOnError);
465    }
466    /// <inheritdoc cref="IOperator.GetVariableValue(string, HeuristicLab.Core.IScope, bool)"/>
467    /// <remarks>Calls <see cref="GetVariableValue(string, HeuristicLab.Core.IScope, bool, bool)"/>
468    /// with <c>throwOnError</c> set to <c>false</c>.</remarks>
469    public IItem GetVariableValue(string formalName, IScope scope, bool recursiveLookup) {
470      return GetVariableValue(formalName, scope, recursiveLookup, true);
471    }
472    /// <inheritdoc cref="IOperator.GetVariableValue(string, HeuristicLab.Core.IScope, bool, bool)"/>
473    public virtual IItem GetVariableValue(string formalName, IScope scope, bool recursiveLookup, bool throwOnError) {
474      IVariableInfo info = GetVariableInfo(formalName);
475      if (info.Local) {
476        IVariable variable;
477        if (myVariables.TryGetValue(info.ActualName, out variable))
478          return variable.Value;
479        else {
480          if (throwOnError)
481            throw new ArgumentException("Variable " + info.ActualName + " not found");
482          else
483            return null;
484        }
485      } else {
486        return scope.GetVariableValue(formalName, recursiveLookup, throwOnError);
487      }
488    }
489    #endregion
490    /// <inheritdoc/>
491    public virtual IOperation Execute(IScope scope) {
492      myCanceled = false;
493
494      foreach (IVariableInfo variableInfo in VariableInfos)
495        scope.AddAlias(variableInfo.FormalName, variableInfo.ActualName);
496
497      IOperation next = Apply(scope);
498
499      foreach (IVariableInfo variableInfo in VariableInfos)
500        scope.RemoveAlias(variableInfo.FormalName);
501
502      OnExecuted();
503      return next;
504    }
505    /// <inheritdoc/>
506    /// <remarks>Sets property <see cref="Canceled"/> to <c>true</c>.</remarks>
507    public virtual void Abort() {
508      myCanceled = true;
509    }
510    /// <summary>
511    /// Performs the current operator on the specified <paramref name="scope"/>.
512    /// </summary>
513    /// <param name="scope">The scope where to execute the operator</param>
514    /// <returns><c>null</c>.</returns>
515    public virtual IOperation Apply(IScope scope) {
516      return null;
517    }
518    /// <inheritdoc/>
519    public event EventHandler NameChanged;
520    /// <summary>
521    /// Fires a new <c>NameChanged</c> event.
522    /// </summary>
523    protected virtual void OnNameChanged() {
524      if (NameChanged != null) {
525        NameChanged(this, new EventArgs());
526      }
527    }
528    /// <inheritdoc/>
529    public event EventHandler BreakpointChanged;
530    /// <summary>
531    /// Fires a new <c>BreakpointChanged</c> event.
532    /// </summary>
533    protected virtual void OnBreakpointChanged() {
534      if (BreakpointChanged != null) {
535        BreakpointChanged(this, new EventArgs());
536      }
537    }
538    /// <inheritdoc/>
539    public event EventHandler<OperatorIndexEventArgs> SubOperatorAdded;
540    /// <summary>
541    /// Fires a new <c>SubOperatorAdded</c> event.
542    /// </summary>
543    /// <param name="subOperator">The sub operator that has been added.</param>
544    /// <param name="index">The position where the operator has been added.</param>
545    protected virtual void OnSubOperatorAdded(IOperator subOperator, int index) {
546      if (SubOperatorAdded != null)
547        SubOperatorAdded(this, new OperatorIndexEventArgs(subOperator, index));
548    }
549    /// <inheritdoc/>
550    public event EventHandler<OperatorIndexEventArgs> SubOperatorRemoved;
551    /// <summary>
552    /// Fires a new <c>SubOperatorRemoved</c> event.
553    /// </summary>
554    /// <param name="subOperator">The sub operator that has been removed.</param>
555    /// <param name="index">The position where the operator has been removed.</param>
556    protected virtual void OnSubOperatorRemoved(IOperator subOperator, int index) {
557      if (SubOperatorRemoved != null)
558        SubOperatorRemoved(this, new OperatorIndexEventArgs(subOperator, index));
559    }
560    /// <inheritdoc/>
561    public event EventHandler<VariableInfoEventArgs> VariableInfoAdded;
562    /// <summary>
563    /// Fires a new <c>VariableInfoAdded</c> event.
564    /// </summary>
565    /// <param name="variableInfo">The variable info that has been added.</param>
566    protected virtual void OnVariableInfoAdded(IVariableInfo variableInfo) {
567      if (VariableInfoAdded != null)
568        VariableInfoAdded(this, new VariableInfoEventArgs(variableInfo));
569    }
570    /// <inheritdoc/>
571    public event EventHandler<VariableInfoEventArgs> VariableInfoRemoved;
572    /// <summary>
573    /// Fires a new <c>VariableInfoRemoved</c> event.
574    /// </summary>
575    /// <param name="variableInfo">The variable info that has been removed.</param>
576    protected virtual void OnVariableInfoRemoved(IVariableInfo variableInfo) {
577      if (VariableInfoRemoved != null)
578        VariableInfoRemoved(this, new VariableInfoEventArgs(variableInfo));
579    }
580    /// <inheritdoc/>
581    public event EventHandler<VariableEventArgs> VariableAdded;
582    /// <summary>
583    /// Fires a new <c>VariableAdded</c> event.
584    /// </summary>
585    /// <param name="variable">The variable that has been added.</param>
586    protected virtual void OnVariableAdded(IVariable variable) {
587      if (VariableAdded != null)
588        VariableAdded(this, new VariableEventArgs(variable));
589    }
590    /// <inheritdoc/>
591    public event EventHandler<VariableEventArgs> VariableRemoved;
592    /// <summary>
593    /// Fires a new <c>VariableRemoved</c> event.
594    /// </summary>
595    /// <param name="variable">The variable that has been removed</param>
596    protected virtual void OnVariableRemoved(IVariable variable) {
597      if (VariableRemoved != null)
598        VariableRemoved(this, new VariableEventArgs(variable));
599    }
600    /// <inheritdoc/>
601    public event EventHandler Executed;
602    /// <summary>
603    /// Fires a new <c>Executed</c> event.
604    /// </summary>
605    protected virtual void OnExecuted() {
606      if (Executed != null) {
607        Executed(this, new EventArgs());
608      }
609    }
610  }
611}
Note: See TracBrowser for help on using the repository browser.