Free cookie consent management tool by TermsFeed Policy Generator

source: trunk/sources/HeuristicLab.Collections/3.3/ObservableArray.cs @ 3013

Last change on this file since 3013 was 2994, checked in by epitzer, 15 years ago

Make StorableClass attribute compulsory for StorableSerializer to work, add named property StorableClassType to choose between Empty and MarkedOnly, later other options will be added. (#548)

File size: 11.0 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;
24using System.Collections.Generic;
25using System.ComponentModel;
26using System.Linq;
27using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
28
29namespace HeuristicLab.Collections {
30  [Serializable]
31  [StorableClass(StorableClassType.MarkedOnly)]
32  public class ObservableArray<T> : IObservableArray<T> {
33    [Storable]
34    private T[] array;
35
36    #region Properties
37    public int Length {
38      get { return array.Length; }
39    }
40    int ICollection<T>.Count {
41      get { return array.Length; }
42    }
43    bool ICollection<T>.IsReadOnly {
44      get { return array.IsReadOnly; }
45    }
46
47    public T this[int index] {
48      get {
49        return array[index];
50      }
51      set {
52        T item = array[index];
53        if (!((item == null) && (value == null)) && ((item == null) || (!item.Equals(value)))) {
54          array[index] = value;
55          OnItemsReplaced(new IndexedItem<T>[] { new IndexedItem<T>(index, value) }, new IndexedItem<T>[] { new IndexedItem<T>(index, item) });
56          OnPropertyChanged("Item[]");
57        }
58      }
59    }
60    #endregion
61
62    #region Constructors
63    public ObservableArray() {
64      array = new T[0];
65    }
66    public ObservableArray(int length) {
67      array = new T[length];
68    }
69    public ObservableArray(T[] array) {
70      this.array = (T[])array.Clone();
71    }
72    public ObservableArray(IEnumerable<T> collection) {
73      array = collection.ToArray();
74    }
75    #endregion
76
77    #region Access
78    public bool Contains(T item) {
79      return IndexOf(item) != -1;
80    }
81    public int IndexOf(T item) {
82      return Array.IndexOf<T>(array, item);
83    }
84    public int IndexOf(T item, int startIndex) {
85      return Array.IndexOf<T>(array, item, startIndex);
86    }
87    public int IndexOf(T item, int startIndex, int count) {
88      return Array.IndexOf<T>(array, item, startIndex, count);
89    }
90
91    public int LastIndexOf(T item) {
92      return Array.LastIndexOf<T>(array, item);
93    }
94    public int LastIndexOf(T item, int startIndex) {
95      return Array.LastIndexOf<T>(array, item, startIndex);
96    }
97    public int LastIndexOf(T item, int startIndex, int count) {
98      return Array.LastIndexOf<T>(array, item, startIndex, count);
99    }
100
101    public int BinarySearch(T item) {
102      return Array.BinarySearch<T>(array, item);
103    }
104    public int BinarySearch(T item, IComparer<T> comparer) {
105      return Array.BinarySearch<T>(array, item, comparer);
106    }
107    public int BinarySearch(int index, int count, T item) {
108      return Array.BinarySearch<T>(array, index, count, item);
109    }
110    public int BinarySearch(int index, int count, T item, IComparer<T> comparer) {
111      return Array.BinarySearch<T>(array, index, count, item, comparer);
112    }
113
114    public bool Exists(Predicate<T> match) {
115      return Array.Exists<T>(array, match);
116    }
117
118    public T Find(Predicate<T> match) {
119      return Array.Find<T>(array, match);
120    }
121    public T[] FindAll(Predicate<T> match) {
122      return Array.FindAll<T>(array, match);
123    }
124    public T FindLast(Predicate<T> match) {
125      return Array.FindLast<T>(array, match);
126    }
127
128    public int FindIndex(Predicate<T> match) {
129      return Array.FindIndex<T>(array, match);
130    }
131    public int FindIndex(int startIndex, Predicate<T> match) {
132      return Array.FindIndex<T>(array, startIndex, match);
133    }
134    public int FindIndex(int startIndex, int count, Predicate<T> match) {
135      return Array.FindIndex<T>(array, startIndex, count, match);
136    }
137
138    public int FindLastIndex(Predicate<T> match) {
139      return Array.FindLastIndex<T>(array, match);
140    }
141    public int FindLastIndex(int startIndex, Predicate<T> match) {
142      return Array.FindLastIndex<T>(array, startIndex, match);
143    }
144    public int FindLastIndex(int startIndex, int count, Predicate<T> match) {
145      return Array.FindLastIndex<T>(array, startIndex, count, match);
146    }
147    #endregion
148
149    #region Manipulation
150    void ICollection<T>.Add(T item) {
151      throw new NotSupportedException();
152    }
153    void IList<T>.Insert(int index, T item) {
154      throw new NotSupportedException();
155    }
156    bool ICollection<T>.Remove(T item) {
157      throw new NotSupportedException();
158    }
159    void IList<T>.RemoveAt(int index) {
160      throw new NotSupportedException();
161    }
162
163    public void Clear(int index, int length) {
164      if (length > 0) {
165        IndexedItem<T>[] oldItems = GetIndexedItems(index, length);
166        Array.Clear(array, index, length);
167        OnPropertyChanged("Item[]");
168        OnItemsReplaced(GetIndexedItems(index, length), oldItems);
169      }
170    }
171    void ICollection<T>.Clear() {
172      Clear(0, array.Length);
173    }
174
175    public void Resize(int newSize) {
176      if (newSize != array.Length) {
177        IndexedItem<T>[] oldItems = GetIndexedItems();
178        Array.Resize<T>(ref array, newSize);
179        OnPropertyChanged("Length");
180        OnPropertyChanged("Item[]");
181        OnCollectionReset(GetIndexedItems(), oldItems);
182      }
183    }
184
185    public void Reverse() {
186      if (array.Length > 1) {
187        IndexedItem<T>[] oldItems = GetIndexedItems();
188        Array.Reverse(array);
189        OnPropertyChanged("Item[]");
190        OnItemsMoved(GetIndexedItems(), oldItems);
191      }
192    }
193    public void Reverse(int index, int length) {
194      if (length > 1) {
195        IndexedItem<T>[] oldItems = GetIndexedItems(index, length);
196        Array.Reverse(array, index, length);
197        OnPropertyChanged("Item[]");
198        OnItemsMoved(GetIndexedItems(index, length), oldItems);
199      }
200    }
201
202    public void Sort() {
203      if (array.Length > 1) {
204        IndexedItem<T>[] oldItems = GetIndexedItems();
205        Array.Sort<T>(array);
206        OnPropertyChanged("Item[]");
207        OnItemsMoved(GetIndexedItems(), oldItems);
208      }
209    }
210    public void Sort(Comparison<T> comparison) {
211      if (array.Length > 1) {
212        IndexedItem<T>[] oldItems = GetIndexedItems();
213        Array.Sort<T>(array, comparison);
214        OnPropertyChanged("Item[]");
215        OnItemsMoved(GetIndexedItems(), oldItems);
216      }
217    }
218    public void Sort(IComparer<T> comparer) {
219      if (array.Length > 1) {
220        IndexedItem<T>[] oldItems = GetIndexedItems();
221        Array.Sort<T>(array, comparer);
222        OnPropertyChanged("Item[]");
223        OnItemsMoved(GetIndexedItems(), oldItems);
224      }
225    }
226    public void Sort(int index, int length) {
227      if (length > 1) {
228        IndexedItem<T>[] oldItems = GetIndexedItems(index, length);
229        Array.Sort<T>(array, index, length);
230        OnPropertyChanged("Item[]");
231        OnItemsMoved(GetIndexedItems(index, length), oldItems);
232      }
233    }
234    public void Sort(int index, int length, IComparer<T> comparer) {
235      if (length > 1) {
236        IndexedItem<T>[] oldItems = GetIndexedItems(index, length);
237        Array.Sort<T>(array, index, length, comparer);
238        OnPropertyChanged("Item[]");
239        OnItemsMoved(GetIndexedItems(index, length), oldItems);
240      }
241    }
242    #endregion
243
244    #region Conversion
245    public ReadOnlyObservableArray<T> AsReadOnly() {
246      return new ReadOnlyObservableArray<T>(this);
247    }
248    public void CopyTo(T[] array) {
249      Array.Copy(this.array, array, this.array.Length);
250    }
251    public void CopyTo(T[] array, int arrayIndex) {
252      Array.Copy(this.array, 0, array, arrayIndex, this.array.Length);
253    }
254    public void CopyTo(int index, T[] array, int arrayIndex, int count) {
255      Array.Copy(this.array, index, array, arrayIndex, count);
256    }
257    public TOutput[] ConvertAll<TOutput>(Converter<T, TOutput> converter) {
258      return Array.ConvertAll<T, TOutput>(array, converter);
259    }
260    #endregion
261
262    #region Processing
263    public void ForEach(Action<T> action) {
264      Array.ForEach<T>(array, action);
265    }
266    public bool TrueForAll(Predicate<T> match) {
267      return Array.TrueForAll<T>(array, match);
268    }
269    #endregion
270
271    #region Enumeration
272    public IEnumerator<T> GetEnumerator() {
273      foreach (object o in ((IEnumerable)this))
274        yield return (T)o;
275    }
276    IEnumerator IEnumerable.GetEnumerator() {
277      return array.GetEnumerator();
278    }
279    #endregion
280
281    #region Events
282    [field: NonSerialized]
283    public event CollectionItemsChangedEventHandler<IndexedItem<T>> ItemsReplaced;
284    protected virtual void OnItemsReplaced(IEnumerable<IndexedItem<T>> items, IEnumerable<IndexedItem<T>> oldItems) {
285      if (ItemsReplaced != null)
286        ItemsReplaced(this, new CollectionItemsChangedEventArgs<IndexedItem<T>>(items, oldItems));
287    }
288
289    [field: NonSerialized]
290    public event CollectionItemsChangedEventHandler<IndexedItem<T>> ItemsMoved;
291    protected virtual void OnItemsMoved(IEnumerable<IndexedItem<T>> items, IEnumerable<IndexedItem<T>> oldItems) {
292      if (ItemsMoved != null)
293        ItemsMoved(this, new CollectionItemsChangedEventArgs<IndexedItem<T>>(items, oldItems));
294    }
295
296    [field: NonSerialized]
297    public event CollectionItemsChangedEventHandler<IndexedItem<T>> CollectionReset;
298    protected virtual void OnCollectionReset(IEnumerable<IndexedItem<T>> items, IEnumerable<IndexedItem<T>> oldItems) {
299      if (CollectionReset != null)
300        CollectionReset(this, new CollectionItemsChangedEventArgs<IndexedItem<T>>(items, oldItems));
301    }
302
303    [field: NonSerialized]
304    public event PropertyChangedEventHandler PropertyChanged;
305    protected virtual void OnPropertyChanged(string propertyName) {
306      if (PropertyChanged != null)
307        PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
308    }
309    #endregion
310
311    #region Private helpers
312    private IndexedItem<T>[] GetIndexedItems() {
313      IndexedItem<T>[] items = new IndexedItem<T>[array.Length];
314      for (int i = 0; i < array.Length; i++)
315        items[i] = new IndexedItem<T>(i, array[i]);
316      return items;
317    }
318    private IndexedItem<T>[] GetIndexedItems(int index, int count) {
319      IndexedItem<T>[] items = new IndexedItem<T>[count];
320      for (int i = 0; i < count; i++)
321        items[i] = new IndexedItem<T>(index + i, array[index + i]);
322      return items;
323    }
324    #endregion
325  }
326}
Note: See TracBrowser for help on using the repository browser.