Free cookie consent management tool by TermsFeed Policy Generator

source: branches/WebJobManager/HeuristicLab.Data/3.3/ValueTypeMatrix.cs @ 13656

Last change on this file since 13656 was 13656, checked in by ascheibe, 8 years ago

#2582 created branch for Hive Web Job Manager

File size: 9.8 KB
Line 
1#region License Information
2/* HeuristicLab
3 * Copyright (C) 2002-2015 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("ValueTypeMatrix", "An abstract base class for representing matrices of value types.")]
34  [StorableClass]
35  public abstract class ValueTypeMatrix<T> : Item, IEnumerable<T> where T : struct {
36    private const int maximumToStringLength = 100;
37
38    public static new Image StaticItemImage
39    {
40      get { return new Bitmap(25, 25); }
41    }
42
43    [Storable]
44    protected T[,] matrix;
45
46    [Storable]
47    protected List<string> columnNames;
48    public virtual IEnumerable<string> ColumnNames
49    {
50      get { return this.columnNames; }
51      set
52      {
53        if (ReadOnly) throw new NotSupportedException("ColumnNames cannot be set. ValueTypeMatrix is read-only.");
54        if (value == null || value.Count() == 0)
55          columnNames = new List<string>();
56        else if (value.Count() != Columns)
57          throw new ArgumentException("A column name must be specified for each column.");
58        else
59          columnNames = new List<string>(value);
60        OnColumnNamesChanged();
61      }
62    }
63    [Storable]
64    protected List<string> rowNames;
65    public virtual IEnumerable<string> RowNames
66    {
67      get { return this.rowNames; }
68      set
69      {
70        if (ReadOnly) throw new NotSupportedException("RowNames cannot be set. ValueTypeMatrix is read-only.");
71        if (value == null || value.Count() == 0)
72          rowNames = new List<string>();
73        else if (value.Count() != Rows)
74          throw new ArgumentException("A row name must be specified for each row.");
75        else
76          rowNames = new List<string>(value);
77        OnRowNamesChanged();
78      }
79    }
80    [Storable]
81    protected bool sortableView;
82    public virtual bool SortableView
83    {
84      get { return sortableView; }
85      set
86      {
87        if (ReadOnly) throw new NotSupportedException("SortableView cannot be set. ValueTypeMatrix is read-only.");
88        if (value != sortableView) {
89          sortableView = value;
90          OnSortableViewChanged();
91        }
92      }
93    }
94
95    public virtual int Rows
96    {
97      get { return matrix.GetLength(0); }
98      protected set
99      {
100        if (ReadOnly) throw new NotSupportedException("Rows cannot be set. ValueTypeMatrix is read-only.");
101        if (value != Rows) {
102          T[,] newArray = new T[value, Columns];
103          Array.Copy(matrix, newArray, Math.Min(value * Columns, matrix.Length));
104          matrix = newArray;
105          while (rowNames.Count > value)
106            rowNames.RemoveAt(rowNames.Count - 1);
107          while (rowNames.Count < value)
108            rowNames.Add("Row " + rowNames.Count);
109          OnRowsChanged();
110          OnRowNamesChanged();
111          OnReset();
112        }
113      }
114    }
115    public virtual int Columns
116    {
117      get { return matrix.GetLength(1); }
118      protected set
119      {
120        if (ReadOnly) throw new NotSupportedException("Columns cannot be set. ValueTypeMatrix is read-only.");
121        if (value != Columns) {
122          T[,] newArray = new T[Rows, value];
123          for (int i = 0; i < Rows; i++)
124            Array.Copy(matrix, i * Columns, newArray, i * value, Math.Min(value, Columns));
125          matrix = newArray;
126          while (columnNames.Count > value)
127            columnNames.RemoveAt(columnNames.Count - 1);
128          while (columnNames.Count < value)
129            columnNames.Add("Column " + columnNames.Count);
130          OnColumnsChanged();
131          OnColumnNamesChanged();
132          OnReset();
133        }
134      }
135    }
136    public virtual T this[int rowIndex, int columnIndex]
137    {
138      get { return matrix[rowIndex, columnIndex]; }
139      set
140      {
141        if (ReadOnly) throw new NotSupportedException("Item cannot be set. ValueTypeMatrix is read-only.");
142        if (!value.Equals(matrix[rowIndex, columnIndex])) {
143          matrix[rowIndex, columnIndex] = value;
144          OnItemChanged(rowIndex, columnIndex);
145        }
146      }
147    }
148
149    [Storable]
150    protected bool readOnly;
151    public virtual bool ReadOnly
152    {
153      get { return readOnly; }
154    }
155
156    [StorableConstructor]
157    protected ValueTypeMatrix(bool deserializing) : base(deserializing) { }
158    protected ValueTypeMatrix(ValueTypeMatrix<T> original, Cloner cloner)
159      : base(original, cloner) {
160      this.matrix = (T[,])original.matrix.Clone();
161      this.columnNames = new List<string>(original.columnNames);
162      this.rowNames = new List<string>(original.rowNames);
163      this.sortableView = original.sortableView;
164      this.readOnly = original.readOnly;
165    }
166    protected ValueTypeMatrix() {
167      matrix = new T[0, 0];
168      columnNames = new List<string>();
169      rowNames = new List<string>();
170      sortableView = false;
171      readOnly = false;
172    }
173    protected ValueTypeMatrix(int rows, int columns) {
174      matrix = new T[rows, columns];
175      columnNames = new List<string>();
176      rowNames = new List<string>();
177      sortableView = false;
178      readOnly = false;
179    }
180    protected ValueTypeMatrix(int rows, int columns, IEnumerable<string> columnNames)
181      : this(rows, columns) {
182      ColumnNames = columnNames;
183    }
184    protected ValueTypeMatrix(int rows, int columns, IEnumerable<string> columnNames, IEnumerable<string> rowNames)
185      : this(rows, columns, columnNames) {
186      RowNames = rowNames;
187    }
188    protected ValueTypeMatrix(T[,] elements) {
189      if (elements == null) throw new ArgumentNullException();
190      matrix = (T[,])elements.Clone();
191      columnNames = new List<string>();
192      rowNames = new List<string>();
193      sortableView = false;
194      readOnly = false;
195    }
196    protected ValueTypeMatrix(T[,] elements, IEnumerable<string> columnNames)
197      : this(elements) {
198      ColumnNames = columnNames;
199    }
200    protected ValueTypeMatrix(T[,] elements, IEnumerable<string> columnNames, IEnumerable<string> rowNames)
201      : this(elements, columnNames) {
202      RowNames = rowNames;
203    }
204
205    public virtual ValueTypeMatrix<T> AsReadOnly() {
206      ValueTypeMatrix<T> readOnlyValueTypeMatrix = (ValueTypeMatrix<T>)this.Clone();
207      readOnlyValueTypeMatrix.readOnly = true;
208      return readOnlyValueTypeMatrix;
209    }
210
211    public override string ToString() {
212      if (matrix.Length == 0) return "[]";
213
214      StringBuilder sb = new StringBuilder();
215      sb.Append("[");
216      for (int i = 0; i < Rows; i++) {
217        sb.Append("[").Append(matrix[i, 0].ToString());
218        for (int j = 1; j < Columns; j++)
219          sb.Append(";").Append(matrix[i, j].ToString());
220        sb.Append("]");
221
222        if (sb.Length > maximumToStringLength) {
223          sb.Append("[...]");
224          break;
225        }
226      }
227      sb.Append("]");
228
229      return sb.ToString();
230    }
231
232    public virtual IEnumerator<T> GetEnumerator() {
233      return matrix.Cast<T>().GetEnumerator();
234    }
235
236    IEnumerator IEnumerable.GetEnumerator() {
237      return GetEnumerator();
238    }
239
240    #region events
241    public event EventHandler ColumnsChanged;
242    protected virtual void OnColumnsChanged() {
243      EventHandler handler = ColumnsChanged;
244      if (handler != null)
245        handler(this, EventArgs.Empty);
246    }
247    public event EventHandler RowsChanged;
248    protected virtual void OnRowsChanged() {
249      EventHandler handler = RowsChanged;
250      if (handler != null)
251        handler(this, EventArgs.Empty);
252    }
253    public event EventHandler ColumnNamesChanged;
254    protected virtual void OnColumnNamesChanged() {
255      EventHandler handler = ColumnNamesChanged;
256      if (handler != null)
257        handler(this, EventArgs.Empty);
258    }
259    public event EventHandler RowNamesChanged;
260    protected virtual void OnRowNamesChanged() {
261      EventHandler handler = RowNamesChanged;
262      if (handler != null)
263        handler(this, EventArgs.Empty);
264    }
265    public event EventHandler SortableViewChanged;
266    protected virtual void OnSortableViewChanged() {
267      EventHandler handler = SortableViewChanged;
268      if (handler != null)
269        handler(this, EventArgs.Empty);
270    }
271    public event EventHandler<EventArgs<int, int>> ItemChanged;
272    protected virtual void OnItemChanged(int rowIndex, int columnIndex) {
273      if (ItemChanged != null)
274        ItemChanged(this, new EventArgs<int, int>(rowIndex, columnIndex));
275
276      //approximation to avoid firing of unnecessary ToStringChangedEvents
277      //columnIndex is not used, because always full rows are returned in the ToString method
278      if (rowIndex * Columns < maximumToStringLength)
279        OnToStringChanged();
280    }
281    public event EventHandler Reset;
282    protected virtual void OnReset() {
283      if (Reset != null)
284        Reset(this, EventArgs.Empty);
285      OnToStringChanged();
286    }
287    #endregion
288  }
289}
Note: See TracBrowser for help on using the repository browser.