Paradox Game Engine  v1.0.0 beta06
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Events Macros Pages
TrackingDictionary.cs
Go to the documentation of this file.
1 // Copyright (c) 2014 Silicon Studio Corp. (http://siliconstudio.co.jp)
2 // This file is distributed under GPL v3. See LICENSE.md for details.
3 using System;
4 using System.Collections;
5 using System.Collections.Generic;
6 using System.Collections.Specialized;
7 using System.Linq;
8 using SiliconStudio.Core.Serialization.Serializers;
9 
10 namespace SiliconStudio.Core.Collections
11 {
12  /// <summary>
13  /// Represents a dictionary of key/value pairs that generates events when items get added or removed.
14  /// </summary>
15  /// <remarks>
16  /// Underlying storage is done with a <see cref="Dictionary{TKey,TValue}"/>.
17  /// </remarks>
18  /// <typeparam name="TKey">The type of the key.</typeparam>
19  /// <typeparam name="TValue">The type of the value.</typeparam>
20  [DataSerializer(typeof(DictionaryAllSerializer<,,>), Mode = DataSerializerGenericMode.TypeAndGenericArguments)]
21  public class TrackingDictionary<TKey, TValue> : IDictionary<TKey, TValue>, IDictionary, ITrackingCollectionChanged
22  {
23  private Dictionary<TKey, TValue> innerDictionary;
24  public event EventHandler<TrackingCollectionChangedEventArgs> CollectionChanged;
25 
26  /// <summary>
27  /// Initializes a new instance of the <see cref="TrackingDictionary{TKey, TValue}"/> class.
28  /// </summary>
30  {
31  innerDictionary = new Dictionary<TKey, TValue>();
32  }
33 
34  /// <inheritdoc/>
35  public void Add(TKey key, TValue value)
36  {
37  innerDictionary.Add(key, value);
38  var collectionChanged = CollectionChanged;
39  if (collectionChanged != null)
40  collectionChanged(this, new TrackingCollectionChangedEventArgs(NotifyCollectionChangedAction.Add, key, value, null, true));
41  }
42 
43  /// <inheritdoc/>
44  public bool ContainsKey(TKey key)
45  {
46  return innerDictionary.ContainsKey(key);
47  }
48 
49  /// <inheritdoc/>
50  public ICollection<TKey> Keys
51  {
52  get { return innerDictionary.Keys; }
53  }
54 
55  /// <inheritdoc/>
56  public bool Remove(TKey key)
57  {
58  var collectionChanged = CollectionChanged;
59  if (collectionChanged != null && innerDictionary.ContainsKey(key))
60  collectionChanged(this, new TrackingCollectionChangedEventArgs(NotifyCollectionChangedAction.Remove, key, innerDictionary[key], null, true));
61 
62  return innerDictionary.Remove(key);
63  }
64 
65  /// <inheritdoc/>
66  public bool TryGetValue(TKey key, out TValue value)
67  {
68  return innerDictionary.TryGetValue(key, out value);
69  }
70 
71  /// <inheritdoc/>
72  public ICollection<TValue> Values
73  {
74  get { return innerDictionary.Values; }
75  }
76 
77  /// <inheritdoc/>
78  public TValue this[TKey key]
79  {
80  get
81  {
82  return innerDictionary[key];
83  }
84  set
85  {
86  var collectionChanged = CollectionChanged;
87  if (collectionChanged != null)
88  {
89  TValue oldValue;
90  bool alreadyExisting = innerDictionary.TryGetValue(key, out oldValue);
91  if (alreadyExisting)
92  collectionChanged(this, new TrackingCollectionChangedEventArgs(NotifyCollectionChangedAction.Remove, key, oldValue, null, false));
93  innerDictionary[key] = value;
94  collectionChanged(this, new TrackingCollectionChangedEventArgs(NotifyCollectionChangedAction.Add, key, innerDictionary[key], oldValue, !alreadyExisting));
95  }
96  else
97  {
98  innerDictionary[key] = value;
99  }
100  }
101  }
102 
103  /// <inheritdoc/>
104  public void Add(KeyValuePair<TKey, TValue> item)
105  {
106  Add(item.Key, item.Value);
107  }
108 
109  /// <inheritdoc/>
110  public void Clear()
111  {
112  var collectionChanged = CollectionChanged;
113  if (collectionChanged != null)
114  {
115  foreach (var key in innerDictionary.Keys.ToArray())
116  {
117  Remove(key);
118  }
119  }
120  else
121  {
122  innerDictionary.Clear();
123  }
124  }
125 
126  /// <inheritdoc/>
127  public bool Contains(KeyValuePair<TKey, TValue> item)
128  {
129  return innerDictionary.Contains(item);
130  }
131 
132  /// <inheritdoc/>
133  public void CopyTo(KeyValuePair<TKey, TValue>[] array, int arrayIndex)
134  {
135  ((IDictionary<TKey, TValue>)innerDictionary).CopyTo(array, arrayIndex);
136  }
137 
138  /// <inheritdoc/>
139  public int Count
140  {
141  get { return innerDictionary.Count; }
142  }
143 
144  /// <inheritdoc/>
145  public bool IsReadOnly
146  {
147  get { return ((IDictionary<TKey, TValue>)innerDictionary).IsReadOnly; }
148  }
149 
150  /// <inheritdoc/>
151  public bool Remove(KeyValuePair<TKey, TValue> item)
152  {
153  var collectionChanged = CollectionChanged;
154  if (collectionChanged != null && innerDictionary.Contains(item))
155  return innerDictionary.Remove(item.Key);
156 
157  return ((IDictionary<TKey, TValue>)innerDictionary).Remove(item);
158  }
159 
160  /// <inheritdoc/>
161  public IEnumerator<KeyValuePair<TKey, TValue>> GetEnumerator()
162  {
163  return innerDictionary.GetEnumerator();
164  }
165 
166  /// <inheritdoc/>
167  System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator()
168  {
169  return innerDictionary.GetEnumerator();
170  }
171 
172  /// <inheritdoc/>
173  void IDictionary.Add(object key, object value)
174  {
175  ((IDictionary)innerDictionary).Add(key, value);
176  }
177 
178  /// <inheritdoc/>
179  bool IDictionary.Contains(object key)
180  {
181  return ((IDictionary)innerDictionary).Contains(key);
182  }
183 
184  /// <inheritdoc/>
185  IDictionaryEnumerator IDictionary.GetEnumerator()
186  {
187  return ((IDictionary)innerDictionary).GetEnumerator();
188  }
189 
190  /// <inheritdoc/>
191  bool IDictionary.IsFixedSize
192  {
193  get { return ((IDictionary)innerDictionary).IsFixedSize; }
194  }
195 
196  /// <inheritdoc/>
197  ICollection IDictionary.Keys
198  {
199  get { return ((IDictionary)innerDictionary).Keys; }
200  }
201 
202  /// <inheritdoc/>
203  void IDictionary.Remove(object key)
204  {
205  ((IDictionary)innerDictionary).Remove(key);
206  }
207 
208  /// <inheritdoc/>
209  ICollection IDictionary.Values
210  {
211  get { return ((IDictionary)innerDictionary).Values; }
212  }
213 
214  /// <inheritdoc/>
215  object IDictionary.this[object key]
216  {
217  get { return ((IDictionary)innerDictionary)[key]; }
218  set { ((IDictionary)innerDictionary)[key] = value; }
219  }
220 
221  /// <inheritdoc/>
222  void ICollection.CopyTo(Array array, int index)
223  {
224  ((IDictionary)innerDictionary).CopyTo(array, index);
225  }
226 
227  /// <inheritdoc/>
228  bool ICollection.IsSynchronized
229  {
230  get { return ((IDictionary)innerDictionary).IsSynchronized; }
231  }
232 
233  /// <inheritdoc/>
234  object ICollection.SyncRoot
235  {
236  get { return ((IDictionary)innerDictionary).SyncRoot; }
237  }
238  }
239 }
TrackingDictionary()
Initializes a new instance of the TrackingDictionary{TKey, TValue} class.
void CopyTo(KeyValuePair< TKey, TValue >[] array, int arrayIndex)
Keys
Enumeration for keys.
Definition: Keys.cs:8
DataSerializerGenericMode
Defines what generic parameters to pass to the serializer.
IEnumerator< KeyValuePair< TKey, TValue > > GetEnumerator()
SiliconStudio.Paradox.Input.Keys Keys
EventHandler< TrackingCollectionChangedEventArgs > CollectionChanged