Free cookie consent management tool by TermsFeed Policy Generator

source: branches/Persistence Test/HeuristicLab.Data/3.3/ConstrainedItemList.cs @ 4071

Last change on this file since 4071 was 2474, checked in by swagner, 15 years ago

Implemented generic EventArgs (#796)

File size: 12.5 KB
Line 
1#region License Information
2/* HeuristicLab
3 * Copyright (C) 2002-2008 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.Text;
26using System.Xml;
27using HeuristicLab.Core;
28using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
29using HeuristicLab.Common;
30
31namespace HeuristicLab.Data {
32  /// <summary>
33  /// A class representing a list of elements
34  /// (which are implementing the interface <see cref="IItem"/>) having some constraints.
35  /// </summary>
36  public class ConstrainedItemList : ConstrainedItemBase, IEnumerable, IEnumerable<IItem> {
37
38    [Storable]
39    private List<IItem> list;
40
41    [Storable]
42    private bool suspendConstraintCheck;
43
44    /// <summary>
45    /// Checks whether the test for the constraints is suspended.
46    /// </summary>
47    public bool ConstraintCheckSuspended {
48      get { return suspendConstraintCheck; }
49    }
50
51    /// <summary>
52    /// Initializes a new instance of <see cref="ConstrainedItemList"/> with the constraint check enabled.
53    /// </summary>
54    public ConstrainedItemList()
55      : base() {
56      list = new List<IItem>();
57      suspendConstraintCheck = false;
58    }
59
60    /// <summary>
61    /// Creates a new instance of <see cref="ConstrainedItemListView"/>.
62    /// </summary>
63    /// <returns>The created instance as <see cref="ConstrainedItemListView"/>.</returns>
64    public override IView CreateView() {
65      return new ConstrainedItemListView(this);
66    }
67    /// <summary>
68    /// Clones the current instance.
69    /// </summary>
70    /// <remarks>The elements of the current instance are cloned with the
71    /// <see cref="HeuristicLab.Core.Auxiliary.Clone"/> method of the class <see cref="Auxiliary"/>.</remarks>
72    /// <param name="clonedObjects">A dictionary of all already cloned objects.</param>
73    /// <returns>The cloned instance as <see cref="ConstrainedItemList"/>.</returns>
74    public override object Clone(IDictionary<Guid, object> clonedObjects) {
75      ConstrainedItemList clone = new ConstrainedItemList();
76      clonedObjects.Add(Guid, clone);
77      foreach (IConstraint constraint in Constraints)
78        clone.AddConstraint((IConstraint)Auxiliary.Clone(constraint, clonedObjects));
79      clone.suspendConstraintCheck = suspendConstraintCheck;
80      foreach (IItem item in list) {
81        clone.list.Add((IItem)Auxiliary.Clone(item, clonedObjects));
82      }
83      return clone;
84    }
85
86    /// <summary>
87    /// The string representation of the current list instance.
88    /// </summary>
89    /// <returns>The current list as string, each element separated by a semicolon.
90    /// "Empty List" if the list has no elements.</returns>
91    public override string ToString() {
92      if (list.Count > 0) {
93        StringBuilder builder = new StringBuilder();
94        builder.Append(list[0].ToString());
95        for (int i = 1; i < list.Count; i++) {
96          builder.Append(";");
97          builder.Append(list[i].ToString());
98        }
99        return builder.ToString();
100      } else {
101        return "Empty List";
102      }
103    }
104
105    /// <inheritdoc cref="List&lt;T&gt;.IndexOf(T)"/>
106    public int IndexOf(IItem item) {
107      return list.IndexOf(item);
108    }
109
110    /// <summary>
111    /// Sets <c>suspendConstraintCheck</c> to <c>true</c>.
112    /// </summary>
113    public void BeginCombinedOperation() {
114      suspendConstraintCheck = true;
115    }
116
117    /// <summary>
118    /// Checks whether the current instance fulfills all constraints.
119    /// </summary>
120    /// <param name="violatedConstraints">Output parameter,
121    /// contains all constraints that could not be fulfilled.</param>
122    /// <returns><c>true</c> if all constraints could be fulfilled, <c>false</c> otherwise.</returns>
123    public bool EndCombinedOperation(out ICollection<IConstraint> violatedConstraints) {
124      if (IsValid(out violatedConstraints))
125        suspendConstraintCheck = false;
126      else
127        suspendConstraintCheck = true;
128
129      return !suspendConstraintCheck;
130    }
131
132    /// <summary>
133    /// Adds a new <paramref name="item"/> at a specified <paramref name="index"/> to the current instance if all constraints are fulfilled.
134    /// </summary>
135    /// <remarks>Calls <see cref="OnItemAdded"/> if the insertion was successful.</remarks>
136    /// <param name="index">The position where to insert the new element.</param>
137    /// <param name="item">The new element to insert.</param>
138    /// <param name="violatedConstraints">Output parameter, all constraints that could not be fulfilled.</param>
139    /// <returns><c>true</c> if the insertion was successful, <c>false</c> otherwise.</returns>
140    public bool TryInsert(int index, IItem item, out ICollection<IConstraint> violatedConstraints) {
141      list.Insert(index, item);
142      violatedConstraints = new List<IConstraint>();
143      if (suspendConstraintCheck || IsValid(out violatedConstraints)) {
144        OnItemAdded(item, index);
145        return true;
146      } else {
147        list.RemoveAt(index);
148        return false;
149      }
150    }
151
152    /// <summary>
153    /// Removes an element at the specified <paramref name="index"/>
154    /// from the current instance if all constraints are fulfilled.
155    /// </summary>
156    /// <remarks>Calls <see cref="OnItemRemoved"/> if the deletion was successful.</remarks>
157    /// <param name="index">The position where to remove the element.</param>
158    /// <param name="violatedConstraints">Output parameter, all constraints that could not be fulfilled.</param>
159    /// <returns><c>true</c> if the element could be removed successfully, <c>false</c> otherwise.</returns>
160    public bool TryRemoveAt(int index, out ICollection<IConstraint> violatedConstraints) {
161      IItem item = list[index];
162      list.RemoveAt(index);
163      violatedConstraints = new List<IConstraint>();
164      if (suspendConstraintCheck || IsValid(out violatedConstraints)) {
165        OnItemRemoved(item, index);
166        return true;
167      } else {
168        list.Insert(index, item);
169        return false;
170      }
171    }
172
173    /// <summary>
174    /// Gets the element of the current instance at the specified <paramref name="index"/>.
175    /// </summary>
176    /// <param name="index">The position of the searched element.</param>
177    /// <returns>The searched element as <see cref="IItem"/>.</returns>
178    public IItem this[int index] {
179      get { return list[index]; }
180    }
181
182    /// <summary>
183    /// Changes the element at a specified position if all constraints are fulfilled.
184    /// </summary>
185    /// <param name="index">The position where to change the element.</param>
186    /// <param name="item">The element that replaces the current one.</param>
187    /// <param name="violatedConstraints">Output parameter, all constraints that could not be fulfilled.</param>
188    /// <returns><c>true</c> if the substitution was successful, <c>false</c> otherwise.</returns>
189    public bool TrySetAt(int index, IItem item, out ICollection<IConstraint> violatedConstraints) {
190      IItem backup = this[index];
191      list[index] = item;
192      violatedConstraints = new List<IConstraint>();
193      if (suspendConstraintCheck || IsValid(out violatedConstraints)) {
194        return true;
195      } else {
196        list[index] = backup;
197        return false;
198      }
199    }
200
201    /// <summary>
202    /// Adds a new <paramref name="item"/> to the current list if all constraints are fulfilled.
203    /// </summary>
204    /// <remarks>Calls <see cref="OnItemAdded"/> if the add was successful.</remarks>
205    /// <param name="item">The element to add.</param>
206    /// <param name="violatedConstraints">Output parameter, all constraints that could not be fulfilled.</param>
207    /// <returns><c>true</c> if the element could be successfully added, <c>false</c> otherwise.</returns>
208    public bool TryAdd(IItem item, out ICollection<IConstraint> violatedConstraints) {
209      list.Add(item);
210      violatedConstraints = new List<IConstraint>();
211      if (suspendConstraintCheck || IsValid(out violatedConstraints)) {
212        OnItemAdded(item, list.Count - 1);
213        return true;
214      } else {
215        list.RemoveAt(list.Count - 1);
216        return false;
217      }
218    }
219    /// <summary>
220    /// Empties the current list.
221    /// </summary>
222    /// <remarks>Calls <see cref="OnCleared"/>.</remarks>
223    public void Clear() {
224      list.Clear();
225      OnCleared();
226    }
227    /// <inheritdoc cref="List&lt;T&gt;.Contains"/>
228    public bool Contains(IItem item) {
229      return list.Contains(item);
230    }
231    /// <inheritdoc cref="List&lt;T&gt;.CopyTo(T[],int)"/>
232    public void CopyTo(IItem[] array, int arrayIndex) {
233      list.CopyTo(array, arrayIndex);
234    }
235    /// <inheritdoc cref="List&lt;T&gt;.Count"/>
236    public int Count {
237      get { return list.Count; }
238    }
239    /// <summary>
240    /// Checks whether the current instance is read-only.
241    /// </summary>
242    /// <remarks>Always returns <c>false</c>.</remarks>
243    public bool IsReadOnly {
244      get { return false; }
245    }
246    /// <summary>
247    /// Removes a specified <paramref name="item"/> from the
248    /// current instance if all constraints are fulfilled.
249    /// </summary>
250    /// <param name="item">The element to remove.</param>
251    /// <param name="violatedConstraints">Output parameter, all constraints that could not be fulfilled.</param>
252    /// <returns><c>true</c> if the deletion was successful, <c>false</c> otherwise.</returns>
253    public bool TryRemove(IItem item, out ICollection<IConstraint> violatedConstraints) {
254      int index = list.IndexOf(item);
255      if (index >= 0) {
256        return TryRemoveAt(index, out violatedConstraints);
257      } else {
258        violatedConstraints = new List<IConstraint>();
259        return false;
260      }
261    }
262
263    /// <inheritdoc cref="List&lt;T&gt;.GetEnumerator"/>
264    public IEnumerator<IItem> GetEnumerator() {
265      return list.GetEnumerator();
266    }
267
268    /// <inheritdoc cref="List&lt;T&gt;.GetEnumerator"/>
269    IEnumerator IEnumerable.GetEnumerator() {
270      return list.GetEnumerator();
271    }
272
273    /// <summary>
274    /// Occurs when a new item is added.
275    /// </summary>
276    public event EventHandler<EventArgs<IItem, int>> ItemAdded;
277    /// <summary>
278    /// Fires a new <c>ItemAdded</c> event.
279    /// </summary>         
280    /// <remarks>Calls <see cref="HeuristicLab.Core.ItemBase.OnChanged"/>.</remarks>
281    /// <param name="item">The element that was added.</param>
282    /// <param name="index">The position where the element was added.</param>
283    protected virtual void OnItemAdded(IItem item, int index) {
284      if (ItemAdded != null)
285        ItemAdded(this, new EventArgs<IItem, int>(item, index));
286      OnChanged();
287    }
288    /// <summary>
289    /// Occurs when an element is removed from the current instance.
290    /// </summary>
291    public event EventHandler<EventArgs<IItem, int>> ItemRemoved;
292    /// <summary>
293    /// Fires a new <c>ItemRemoved</c> event.
294    /// </summary>
295    /// <remarks>Calls <see cref="HeuristicLab.Core.ItemBase.OnChanged"/>.</remarks>
296    /// <param name="item">The element that has been removed.</param>
297    /// <param name="index">The position from where it has been removed.</param>
298    protected virtual void OnItemRemoved(IItem item, int index) {
299      if (ItemRemoved != null)
300        ItemRemoved(this, new EventArgs<IItem, int>(item, index));
301      OnChanged();
302    }
303    /// <summary>
304    /// Occurs when the current list is emptied.
305    /// </summary>
306    public event EventHandler Cleared;
307    /// <summary>
308    /// Fires a new <c>Cleared</c> event.
309    /// </summary>
310    /// <remarks>Calls <see cref="HeuristicLab.Core.ItemBase.OnChanged"/>.</remarks>
311    protected virtual void OnCleared() {
312      if (Cleared != null)
313        Cleared(this, new EventArgs());
314      OnChanged();
315    }
316  }
317}
Note: See TracBrowser for help on using the repository browser.