Free cookie consent management tool by TermsFeed Policy Generator

source: trunk/sources/HeuristicLab.Data/3.3/ConstrainedItemList.cs @ 2016

Last change on this file since 2016 was 1823, checked in by epitzer, 16 years ago

Namespace refactoring: rename formatters & decomposers -> primitive and composite serializers. (#603)

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