wasSharp – Blame information for rev 39

Subversion Repositories:
Rev:
Rev Author Line No. Line
22 office 1 ///////////////////////////////////////////////////////////////////////////
2 // Copyright (C) Wizardry and Steamworks 2016 - License: GNU GPLv3 //
3 // Please see: http://www.gnu.org/licenses/gpl.html for legal details, //
4 // rights of fair usage, the disclaimer and warranty conditions. //
5 ///////////////////////////////////////////////////////////////////////////
6  
7 using System.Collections;
8 using System.Collections.Generic;
9 using System.Collections.Specialized;
39 office 10 using System.Threading;
22 office 11  
12 namespace wasSharp.Collections.Specialized
13 {
14 ///////////////////////////////////////////////////////////////////////////
15 // Copyright (C) 2016 Wizardry and Steamworks - License: GNU GPLv3 //
16 ///////////////////////////////////////////////////////////////////////////
17 /// <summary>
18 /// An implementation of an observable Dictionary.
19 /// </summary>
20 /// <typeparam name="K">the key type</typeparam>
21 /// <typeparam name="V">the value type</typeparam>
22 public class ObservableDictionary<K, V> : IDictionary<K, V>, INotifyCollectionChanged
23 {
39 office 24 private readonly ReaderWriterLockSlim SyncRoot = new ReaderWriterLockSlim(LockRecursionPolicy.SupportsRecursion);
22 office 25 private readonly Dictionary<K, V> store = new Dictionary<K, V>();
26  
27 public bool IsVirgin { get; private set; } = true;
28  
29 public V this[K key]
30 {
39 office 31 get
32 {
33 SyncRoot.EnterReadLock();
34 var v = store[key];
35 SyncRoot.ExitReadLock();
36 return v;
37 }
22 office 38  
39 office 39 set
40 {
41 SyncRoot.EnterWriteLock();
42 store[key] = value;
43 SyncRoot.ExitWriteLock();
44 }
22 office 45 }
46  
47 public int Count => store.Count;
48  
49 public bool IsReadOnly => false;
50  
39 office 51 public ICollection<K> Keys
52 {
53 get
54 {
55 SyncRoot.EnterReadLock();
56 var v = store.Keys;
57 SyncRoot.ExitReadLock();
58 return v;
59 }
60 }
22 office 61  
39 office 62 public ICollection<V> Values
63 {
64 get
65 {
66 SyncRoot.EnterReadLock();
67 var v = store.Values;
68 SyncRoot.ExitReadLock();
69 return v;
70 }
71 }
22 office 72  
73 public void Add(KeyValuePair<K, V> item)
74 {
39 office 75 SyncRoot.EnterWriteLock();
27 office 76 ((IDictionary<K, V>)store).Add(item);
39 office 77 SyncRoot.ExitWriteLock();
22 office 78 IsVirgin = false;
79 OnCollectionChanged(new NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction.Add, item));
80 }
81  
82 public void Add(K key, V value)
83 {
39 office 84 SyncRoot.EnterWriteLock();
22 office 85 store.Add(key, value);
39 office 86 SyncRoot.ExitWriteLock();
22 office 87 IsVirgin = false;
88 OnCollectionChanged(new NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction.Add,
89 new KeyValuePair<K, V>(key, value)));
90 }
91  
92 public void Clear()
93 {
39 office 94 SyncRoot.EnterWriteLock();
22 office 95 store.Clear();
39 office 96 SyncRoot.ExitWriteLock();
22 office 97 if (!IsVirgin)
98 OnCollectionChanged(new NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction.Reset));
99 IsVirgin = false;
100 }
101  
102 public bool Contains(KeyValuePair<K, V> item)
103 {
39 office 104 SyncRoot.EnterReadLock();
105 var c = ((IDictionary<K, V>)store).Contains(item);
106 SyncRoot.ExitReadLock();
107 return c;
22 office 108 }
109  
110 public bool ContainsKey(K key)
111 {
39 office 112 SyncRoot.EnterReadLock();
113 var c = store.ContainsKey(key);
114 SyncRoot.ExitReadLock();
115 return c;
22 office 116 }
117  
118 public void CopyTo(KeyValuePair<K, V>[] array, int arrayIndex)
119 {
39 office 120 SyncRoot.EnterReadLock();
27 office 121 ((IDictionary<K, V>)store).CopyTo(array, arrayIndex);
39 office 122 SyncRoot.ExitReadLock();
22 office 123 }
124  
125 public IEnumerator<KeyValuePair<K, V>> GetEnumerator()
126 {
39 office 127 SyncRoot.EnterReadLock();
128 var enumerator = ((IDictionary<K, V>)store).GetEnumerator();
129 SyncRoot.ExitReadLock();
130 return enumerator;
22 office 131 }
132  
133 public bool Remove(KeyValuePair<K, V> item)
134 {
39 office 135 SyncRoot.EnterWriteLock();
27 office 136 var removed = ((IDictionary<K, V>)store).Remove(item);
39 office 137 SyncRoot.ExitWriteLock();
22 office 138 IsVirgin = false;
139 if (removed)
140 OnCollectionChanged(new NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction.Remove, item));
141 return removed;
142 }
143  
144 public bool Remove(K key)
145 {
146 KeyValuePair<K, V> item;
39 office 147 SyncRoot.EnterWriteLock();
22 office 148 if (store.ContainsKey(key))
149 item = new KeyValuePair<K, V>(key, store[key]);
150  
151 var removed = store.Remove(key);
39 office 152 SyncRoot.ExitWriteLock();
22 office 153 IsVirgin = false;
154 if (removed)
155 OnCollectionChanged(new NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction.Remove, item));
156 return removed;
157 }
158  
159 public bool TryGetValue(K key, out V value)
160 {
39 office 161 SyncRoot.EnterReadLock();
162 var c = store.TryGetValue(key, out value);
163 SyncRoot.ExitReadLock();
164 return c;
22 office 165 }
166  
167 IEnumerator IEnumerable.GetEnumerator()
168 {
39 office 169 SyncRoot.EnterReadLock();
170 var enumerator = ((IDictionary<K, V>)store).GetEnumerator();
171 SyncRoot.ExitReadLock();
172 return enumerator;
22 office 173 }
174  
175 public event NotifyCollectionChangedEventHandler CollectionChanged;
176  
177 private void OnCollectionChanged(NotifyCollectionChangedEventArgs args)
178 {
179 CollectionChanged?.Invoke(this, args);
180 }
181 }
27 office 182 }