source: trunk/sources/HeuristicLab.Operators/3.3/MultiOperator.cs @ 15583

Last change on this file since 15583 was 15583, checked in by swagner, 3 years ago

#2640: Updated year of copyrights in license headers

File size: 6.6 KB
Line 
1#region License Information
2/* HeuristicLab
3 * Copyright (C) 2002-2018 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.Linq;
25using HeuristicLab.Collections;
26using HeuristicLab.Common;
27using HeuristicLab.Core;
28using HeuristicLab.Parameters;
29using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
30
31namespace HeuristicLab.Operators {
32  /// <summary>
33  /// A base class for operators which apply arbitrary many other operators of a specific type.
34  /// </summary>
35  [Item("MultiOperator", "A base class for operators which apply arbitrary many other operators of a specific type.")]
36  [StorableClass]
37  public abstract class MultiOperator<T> : InstrumentedOperator, IMultiOperator<T> where T : class, IOperator {
38    private List<IValueParameter<T>> operatorParameters;
39    protected IEnumerable<IValueParameter<T>> OperatorParameters { get { return operatorParameters; } }
40
41    [Storable]
42    private IItemList<T> operators;
43    public IItemList<T> Operators {
44      get { return operators; }
45      protected set {
46        if (operators != value) {
47          if (value == null) throw new ArgumentException();
48          DeregisterOperatorsEvents();
49          operators = value;
50          RegisterOperatorsEvents();
51          UpdateOperatorParameters();
52        }
53      }
54    }
55   
56    IEnumerable<IOperator> IMultiOperator.Operators { get { return operators.AsEnumerable(); } }
57
58    [StorableConstructor]
59    protected MultiOperator(bool deserializing) : base(deserializing) { }
60    protected MultiOperator(MultiOperator<T> original, Cloner cloner)
61      : base(original, cloner) {
62      this.operators = cloner.Clone<IItemList<T>>(original.operators);
63      Initialize();
64    }
65    public MultiOperator()
66      : base() {
67      this.operators = new ItemList<T>();
68      Initialize();
69    }
70
71    [StorableHook(HookType.AfterDeserialization)]
72    private void AfterDeserialization() {
73      Initialize();
74    }
75
76    public virtual bool AddOperator(IOperator op) {
77      var tOp = op as T;
78      if (tOp == null) return false;
79      operators.Add(tOp);
80      return true;
81    }
82
83    public virtual bool RemoveOperator(IOperator op) {
84      var tOp = op as T;
85      if (tOp == null) return false;
86      return operators.Remove(tOp);
87    }
88
89    private void Initialize() {
90      if (operators != null) RegisterOperatorsEvents();
91      operatorParameters = new List<IValueParameter<T>>();
92      for (int i = 0; i < Operators.Count; i++) {
93        IValueParameter<T> opParam = (IValueParameter<T>)Parameters[i.ToString()];
94        operatorParameters.Add(opParam);
95        opParam.ValueChanged += new EventHandler(opParam_ValueChanged);
96      }
97    }
98
99    private void UpdateOperatorParameters() {
100      foreach (IValueParameter<T> opParam in operatorParameters) {
101        opParam.ValueChanged -= new EventHandler(opParam_ValueChanged);
102        Parameters.Remove(opParam.Name);
103      }
104      operatorParameters.Clear();
105      for (int i = 0; i < Operators.Count; i++) {
106        IValueParameter<T> opParam = new OptionalValueParameter<T>(i.ToString(), string.Empty, Operators[i]);
107        opParam.Hidden = true;
108        opParam.ValueChanged += new EventHandler(opParam_ValueChanged);
109        Parameters.Add(opParam);
110        operatorParameters.Add(opParam);
111      }
112    }
113
114    #region Events
115    private void RegisterOperatorsEvents() {
116      operators.ItemsAdded += new CollectionItemsChangedEventHandler<IndexedItem<T>>(Operators_ItemsAdded);
117      operators.ItemsRemoved += new CollectionItemsChangedEventHandler<IndexedItem<T>>(Operators_ItemsRemoved);
118      operators.ItemsReplaced += new CollectionItemsChangedEventHandler<IndexedItem<T>>(Operators_ItemsReplaced);
119      operators.ItemsMoved += new CollectionItemsChangedEventHandler<IndexedItem<T>>(Operators_ItemsMoved);
120      operators.CollectionReset += new CollectionItemsChangedEventHandler<IndexedItem<T>>(Operators_CollectionReset);
121    }
122    private void DeregisterOperatorsEvents() {
123      operators.ItemsAdded -= new CollectionItemsChangedEventHandler<IndexedItem<T>>(Operators_ItemsAdded);
124      operators.ItemsRemoved -= new CollectionItemsChangedEventHandler<IndexedItem<T>>(Operators_ItemsRemoved);
125      operators.ItemsReplaced -= new CollectionItemsChangedEventHandler<IndexedItem<T>>(Operators_ItemsReplaced);
126      operators.ItemsMoved -= new CollectionItemsChangedEventHandler<IndexedItem<T>>(Operators_ItemsMoved);
127      operators.CollectionReset -= new CollectionItemsChangedEventHandler<IndexedItem<T>>(Operators_CollectionReset);
128    }
129    protected virtual void Operators_ItemsAdded(object sender, CollectionItemsChangedEventArgs<IndexedItem<T>> e) {
130      UpdateOperatorParameters();
131    }
132    protected virtual void Operators_ItemsRemoved(object sender, CollectionItemsChangedEventArgs<IndexedItem<T>> e) {
133      UpdateOperatorParameters();
134    }
135    protected virtual void Operators_ItemsReplaced(object sender, CollectionItemsChangedEventArgs<IndexedItem<T>> e) {
136      foreach (IndexedItem<T> item in e.Items)
137        operatorParameters[item.Index].Value = item.Value;
138    }
139    protected virtual void Operators_ItemsMoved(object sender, CollectionItemsChangedEventArgs<IndexedItem<T>> e) {
140      foreach (IndexedItem<T> item in e.Items)
141        operatorParameters[item.Index].Value = item.Value;
142    }
143    protected virtual void Operators_CollectionReset(object sender, CollectionItemsChangedEventArgs<IndexedItem<T>> e) {
144      UpdateOperatorParameters();
145    }
146    private void opParam_ValueChanged(object sender, EventArgs e) {
147      IValueParameter<T> opParam = (IValueParameter<T>)sender;
148      if (opParam.Value == null)
149        operators.RemoveAt(operatorParameters.IndexOf(opParam));
150      else
151        operators[operatorParameters.IndexOf(opParam)] = opParam.Value;
152    }
153    #endregion
154  }
155}
Note: See TracBrowser for help on using the repository browser.