Free cookie consent management tool by TermsFeed Policy Generator

source: trunk/sources/HeuristicLab.Problems.ExternalEvaluation/3.3/SolutionMessageBuilder.cs @ 3881

Last change on this file since 3881 was 3881, checked in by abeham, 14 years ago

#866

  • Added license headers to designer files
  • Refactored message building, to be user customizable and better extendable
    • A SolutionMessageBuilder holds several Converters
    • A Converter specifies several types to convert and a conversion method
  • ExternalEvaluator has the message builder as parameter and exposes it to the UI through the parameters collection
  • The proto file has been updated to include a length field in the array variables
  • Converters exist for all types in HeuristicLab.Data
File size: 5.4 KB
Line 
1#region License Information
2/* HeuristicLab
3 * Copyright (C) 2002-2010 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 System.Text;
26using HeuristicLab.Core;
27using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
28using HeuristicLab.Collections;
29
30namespace HeuristicLab.Problems.ExternalEvaluation {
31  [Item("SolutionMessageBuilder", "Holds and uses a number of converters to translate HeuristicLab objects into appropriate fields of a solution message.")]
32  [StorableClass]
33  public class SolutionMessageBuilder : NamedItem {
34    public override bool CanChangeName { get { return false; } }
35    public override bool CanChangeDescription { get { return false; } }
36    private Dictionary<Type, Action<IItem, string, SolutionMessage.Builder>> dispatcher;
37
38    [Storable]
39    private CheckedItemCollection<IItemToSolutionMessageConverter> converters;
40    public CheckedItemCollection<IItemToSolutionMessageConverter> Converters {
41      get { return converters; }
42    }
43
44    [StorableConstructor]
45    protected SolutionMessageBuilder(bool deserializing) : base(deserializing) { }
46    public SolutionMessageBuilder()
47      : base() {
48      name = ItemName;
49      description = ItemDescription;
50      converters = new CheckedItemCollection<IItemToSolutionMessageConverter>();
51      AttachEventHandlers();
52
53      converters.Add(new BoolConverter());
54      converters.Add(new DateTimeValueConverter());
55      converters.Add(new DoubleConverter());
56      converters.Add(new IntegerConverter());
57      converters.Add(new StringConverter());
58      converters.Add(new TimeSpanValueConverter());
59    }
60
61    public void AddToMessage(IItem item, string name, SolutionMessage.Builder builder) {
62      if (dispatcher == null) FillDispatcher();
63      Type itemType = item.GetType();
64      while (!dispatcher.ContainsKey(itemType)) {
65        if (itemType.BaseType != null) itemType = itemType.BaseType;
66        else break;
67      }
68      if (itemType.BaseType == null && !dispatcher.ContainsKey(itemType)) {
69        IEnumerable<Type> interfaces = item.GetType().GetInterfaces().Where(x => dispatcher.ContainsKey(x));
70        if (interfaces.Count() != 1) throw new ArgumentException(Name + ": No converter for type + " + itemType.FullName + " defined.", "item");
71        else itemType = interfaces.Single();
72      }
73      dispatcher[itemType](item, name, builder);
74    }
75
76    [StorableHook(HookType.AfterDeserialization)]
77    private void AttachEventHandlers() {
78      converters.ItemsAdded += new CollectionItemsChangedEventHandler<IItemToSolutionMessageConverter>(converters_ItemsAdded);
79      converters.ItemsRemoved += new CollectionItemsChangedEventHandler<IItemToSolutionMessageConverter>(converters_ItemsRemoved);
80      converters.CheckedItemsChanged += new CollectionItemsChangedEventHandler<IItemToSolutionMessageConverter>(converters_CheckedItemsChanged);
81    }
82
83    private void converters_ItemsAdded(object sender, CollectionItemsChangedEventArgs<IItemToSolutionMessageConverter> e) {
84      AddToDispatcher(e.Items);
85    }
86
87    private void converters_ItemsRemoved(object sender, CollectionItemsChangedEventArgs<IItemToSolutionMessageConverter> e) {
88      RemoveFromDispatcher(e.Items);
89    }
90
91    private void converters_CheckedItemsChanged(object sender, CollectionItemsChangedEventArgs<IItemToSolutionMessageConverter> e) {
92      FillDispatcher();
93    }
94
95    private void FillDispatcher() {
96      dispatcher = new Dictionary<Type, Action<IItem, string, SolutionMessage.Builder>>();
97      foreach (IItemToSolutionMessageConverter c in converters.CheckedItems) {
98        Type[] types = c.ItemTypes;
99        foreach (Type t in types) {
100          if (dispatcher.ContainsKey(t)) dispatcher.Remove(t);
101          dispatcher.Add(t, new Action<IItem, string, SolutionMessage.Builder>(c.AddItemToBuilder));
102        }
103      }
104    }
105
106    private void AddToDispatcher(IEnumerable<IItemToSolutionMessageConverter> items) {
107      if (dispatcher == null) FillDispatcher();
108      foreach (IItemToSolutionMessageConverter c in items) {
109        Type[] types = c.ItemTypes;
110        foreach (Type t in types) {
111          if (dispatcher.ContainsKey(t)) dispatcher.Remove(t);
112          dispatcher.Add(t, new Action<IItem, string, SolutionMessage.Builder>(c.AddItemToBuilder));
113        }
114      }
115    }
116
117    private void RemoveFromDispatcher(IEnumerable<IItemToSolutionMessageConverter> items) {
118      if (dispatcher == null) FillDispatcher();
119      foreach (IItemToSolutionMessageConverter c in items) {
120        Type[] types = c.ItemTypes;
121        foreach (Type t in types) {
122          if (dispatcher.ContainsKey(t)) dispatcher.Remove(t);
123        }
124      }
125    }
126  }
127}
Note: See TracBrowser for help on using the repository browser.