#region License Information /* HeuristicLab * Copyright (C) 2002-2010 Heuristic and Evolutionary Algorithms Laboratory (HEAL) * * This file is part of HeuristicLab. * * HeuristicLab is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * HeuristicLab is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with HeuristicLab. If not, see . */ #endregion using System; using System.Collections.Generic; using System.Linq; using HeuristicLab.Collections; using HeuristicLab.Common; using HeuristicLab.Core; using HeuristicLab.Parameters; using HeuristicLab.Persistence.Default.CompositeSerializers.Storable; namespace HeuristicLab.Operators { /// /// A base class for operators which apply arbitrary many other operators of a specific type. /// [Item("MultiOperator", "A base class for operators which apply arbitrary many other operators of a specific type.")] [StorableClass] public abstract class MultiOperator : SingleSuccessorOperator where T : class, IOperator { private List> operatorParameters; [Storable] private ItemList operators; public ItemList Operators { get { return operators; } } public MultiOperator() : base() { operators = new ItemList(); Initialize(); } [StorableConstructor] protected MultiOperator(bool deserializing) : base(deserializing) { } [StorableHook(HookType.AfterDeserialization)] private void Initialize() { if (operators != null) RegisterOperatorsEvents(); operatorParameters = new List>(); for (int i = 0; i < Operators.Count; i++) { IValueParameter opParam = (IValueParameter)Parameters[i.ToString()]; operatorParameters.Add(opParam); opParam.ValueChanged += new EventHandler(opParam_ValueChanged); } } public override IDeepCloneable Clone(Cloner cloner) { MultiOperator clone = (MultiOperator)base.Clone(cloner); clone.operators = (ItemList)cloner.Clone(operators); clone.Initialize(); return clone; } private void UpdateOperatorParameters() { foreach (IValueParameter opParam in operatorParameters) { opParam.ValueChanged -= new EventHandler(opParam_ValueChanged); Parameters.Remove(opParam.Name); } operatorParameters.Clear(); for (int i = 0; i < Operators.Count; i++) { IValueParameter opParam = new ValueParameter(i.ToString(), string.Empty, Operators[i]); opParam.ValueChanged += new EventHandler(opParam_ValueChanged); Parameters.Add(opParam); operatorParameters.Add(opParam); } } #region Events private void RegisterOperatorsEvents() { operators.ItemsAdded += new CollectionItemsChangedEventHandler>(Operators_ItemsAdded); operators.ItemsRemoved += new CollectionItemsChangedEventHandler>(Operators_ItemsRemoved); operators.ItemsReplaced += new CollectionItemsChangedEventHandler>(Operators_ItemsReplaced); operators.ItemsMoved += new CollectionItemsChangedEventHandler>(Operators_ItemsMoved); operators.CollectionReset += new CollectionItemsChangedEventHandler>(Operators_CollectionReset); } private void DeregisterOperatorsEvents() { operators.ItemsAdded -= new CollectionItemsChangedEventHandler>(Operators_ItemsAdded); operators.ItemsRemoved -= new CollectionItemsChangedEventHandler>(Operators_ItemsRemoved); operators.ItemsReplaced -= new CollectionItemsChangedEventHandler>(Operators_ItemsReplaced); operators.ItemsMoved -= new CollectionItemsChangedEventHandler>(Operators_ItemsMoved); operators.CollectionReset -= new CollectionItemsChangedEventHandler>(Operators_CollectionReset); } protected virtual void Operators_ItemsAdded(object sender, CollectionItemsChangedEventArgs> e) { UpdateOperatorParameters(); } protected virtual void Operators_ItemsRemoved(object sender, CollectionItemsChangedEventArgs> e) { UpdateOperatorParameters(); } protected virtual void Operators_ItemsReplaced(object sender, CollectionItemsChangedEventArgs> e) { foreach (IndexedItem item in e.Items) operatorParameters[item.Index].Value = item.Value; } protected virtual void Operators_ItemsMoved(object sender, CollectionItemsChangedEventArgs> e) { foreach (IndexedItem item in e.Items) operatorParameters[item.Index].Value = item.Value; } protected virtual void Operators_CollectionReset(object sender, CollectionItemsChangedEventArgs> e) { UpdateOperatorParameters(); } private void opParam_ValueChanged(object sender, EventArgs e) { IValueParameter opParam = (IValueParameter)sender; operators[operatorParameters.IndexOf(opParam)] = opParam.Value; } #endregion } }