source: branches/ImprovingStringConvertibleMatrix/HeuristicLab.Data/3.3/ValueTypeArray.cs @ 9308

Last change on this file since 9308 was 9308, checked in by sforsten, 6 years ago

#2018:

  • added column names to the ValueTypeArray and StringArray
  • added batch update methods to IStringConvertibleArray similar to methods in IStringConvertibleMatrix
File size: 7.5 KB
Line 
1#region License Information
2/* HeuristicLab
3 * Copyright (C) 2002-2012 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;
24using System.Collections.Generic;
25using System.Drawing;
26using System.Linq;
27using System.Text;
28using HeuristicLab.Common;
29using HeuristicLab.Core;
30using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
31
32namespace HeuristicLab.Data {
33  [Item("ValueTypeArray", "An abstract base class for representing arrays of value types.")]
34  [StorableClass]
35  public abstract class ValueTypeArray<T> : Item, IEnumerable<T>, IStringConvertibleArray where T : struct {
36    public static new Image StaticItemImage {
37      get { return HeuristicLab.Common.Resources.VSImageLibrary.Class; }
38    }
39
40    [Storable]
41    protected T[] array;
42
43    [Storable]
44    protected List<string> columnNames;
45    public virtual IEnumerable<string> ColumnNames {
46      get { return this.columnNames; }
47      set {
48        if (ReadOnly) throw new NotSupportedException("ColumnNames cannot be set. ValueTypeArray is read-only.");
49        if (value == null || value.Count() == 0)
50          columnNames = new List<string>();
51        else if (value.Count() != Length)
52          throw new ArgumentException("A column name must be specified for each column.");
53        else
54          columnNames = new List<string>(value);
55        OnColumnNamesChanged();
56      }
57    }
58
59    public virtual int Length {
60      get { return array.Length; }
61      #region Mono Compatibility
62      // this setter should be protected, but the Mono compiler couldn't handle it
63      set {
64        if (ReadOnly) throw new NotSupportedException("Length cannot be set. ValueTypeArray is read-only.");
65        if (value != Length) {
66          Array.Resize<T>(ref array, value);
67          while (columnNames.Count > value)
68            columnNames.RemoveAt(columnNames.Count - 1);
69          while (columnNames.Count < value)
70            columnNames.Add("Column " + columnNames.Count);
71          OnColumnNamesChanged();
72          OnReset();
73        }
74      }
75      #endregion
76    }
77    public virtual T this[int index] {
78      get { return array[index]; }
79      set {
80        if (ReadOnly) throw new NotSupportedException("Item cannot be set. ValueTypeArray is read-only.");
81        if (!value.Equals(array[index])) {
82          array[index] = value;
83          OnItemsChanged(new List<int>(1) { index });
84        }
85      }
86    }
87
88    public virtual void SetValues(IEnumerable<ArrayValue<T>> arrayValues) {
89      if (ReadOnly) throw new NotSupportedException("Item cannot be set. ValueTypeMatrix is read-only.");
90      List<int> positions = new List<int>();
91      foreach (var arrayValue in arrayValues) {
92        if (!arrayValue.Value.Equals(array[arrayValue.Index])) {
93          array[arrayValue.Index] = arrayValue.Value;
94          positions.Add(arrayValue.Index);
95        }
96      }
97      OnItemsChanged(positions);
98    }
99
100    [Storable]
101    protected bool readOnly;
102    public virtual bool ReadOnly {
103      get { return readOnly; }
104    }
105
106    [StorableHook(HookType.AfterDeserialization)]
107    private void AfterDeserialization() {
108      if (columnNames == null) {
109        columnNames = new List<string>(array.Length);
110        while (columnNames.Count < array.Length)
111          columnNames.Add("Column " + columnNames.Count);
112      }
113    }
114
115    [StorableConstructor]
116    protected ValueTypeArray(bool deserializing) : base(deserializing) { }
117    protected ValueTypeArray(ValueTypeArray<T> original, Cloner cloner)
118      : base(original, cloner) {
119      this.array = (T[])original.array.Clone();
120      this.columnNames = new List<string>(original.columnNames);
121      this.readOnly = original.readOnly;
122    }
123    protected ValueTypeArray() {
124      array = new T[0];
125      columnNames = new List<string>();
126      readOnly = false;
127    }
128    protected ValueTypeArray(int length) {
129      array = new T[length];
130      columnNames = new List<string>(length);
131      readOnly = false;
132    }
133    protected ValueTypeArray(T[] elements) {
134      if (elements == null) throw new ArgumentNullException();
135      array = (T[])elements.Clone();
136      columnNames = new List<string>(elements.Length);
137      readOnly = false;
138    }
139
140    public virtual ValueTypeArray<T> AsReadOnly() {
141      ValueTypeArray<T> readOnlyValueTypeArray = (ValueTypeArray<T>)this.Clone();
142      readOnlyValueTypeArray.readOnly = true;
143      return readOnlyValueTypeArray;
144    }
145
146    public override string ToString() {
147      StringBuilder sb = new StringBuilder();
148      sb.Append("[");
149      if (array.Length > 0) {
150        sb.Append(array[0].ToString());
151        for (int i = 1; i < array.Length; i++)
152          sb.Append(";").Append(array[i].ToString());
153      }
154      sb.Append("]");
155      return sb.ToString();
156    }
157
158    public virtual IEnumerator<T> GetEnumerator() {
159      return array.Cast<T>().GetEnumerator();
160    }
161
162    IEnumerator IEnumerable.GetEnumerator() {
163      return GetEnumerator();
164    }
165
166    public event EventHandler ColumnNamesChanged;
167    protected virtual void OnColumnNamesChanged() {
168      EventHandler handler = ColumnNamesChanged;
169      if (handler != null)
170        handler(this, EventArgs.Empty);
171    }
172    public event EventHandler<ArrayValuesChangedEventArgs> ItemsChanged;
173    protected virtual void OnItemsChanged(IEnumerable<int> indices) {
174      if (ItemsChanged != null)
175        ItemsChanged(this, new ArrayValuesChangedEventArgs(indices));
176      OnToStringChanged();
177    }
178    public event EventHandler Reset;
179    protected virtual void OnReset() {
180      if (Reset != null)
181        Reset(this, EventArgs.Empty);
182      OnToStringChanged();
183    }
184
185    protected abstract bool Validate(string value, out string errorMessage);
186    protected abstract string GetValue(int index);
187    protected abstract bool SetValue(string value, int index);
188    protected abstract bool SetValues(IEnumerable<ArrayValue<string>> arrayValues);
189
190    #region IStringConvertibleArray Members
191    int IStringConvertibleArray.Length {
192      get { return Length; }
193      set { Length = value; }
194    }
195    bool IStringConvertibleArray.Validate(string value, out string errorMessage) {
196      return Validate(value, out errorMessage);
197    }
198    string IStringConvertibleArray.GetValue(int index) {
199      return GetValue(index);
200    }
201    bool IStringConvertibleArray.SetValue(string value, int index) {
202      return SetValue(value, index);
203    }
204    bool IStringConvertibleArray.SetValue(ArrayValue<string> arrayValue) {
205      return SetValue(arrayValue.Value, arrayValue.Index);
206    }
207    bool IStringConvertibleArray.SetValues(IEnumerable<ArrayValue<string>> arrayValues) {
208      return SetValues(arrayValues);
209    }
210    #endregion
211  }
212}
Note: See TracBrowser for help on using the repository browser.