wasSharp – Diff between revs 39 and 44

Subversion Repositories:
Rev:
Only display areas with differencesIgnore whitespace
Rev 39 Rev 44
1 /////////////////////////////////////////////////////////////////////////// 1 ///////////////////////////////////////////////////////////////////////////
2 // Copyright (C) Wizardry and Steamworks 2016 - License: GNU GPLv3 // 2 // Copyright (C) Wizardry and Steamworks 2016 - License: GNU GPLv3 //
3 // Please see: http://www.gnu.org/licenses/gpl.html for legal details, // 3 // Please see: http://www.gnu.org/licenses/gpl.html for legal details, //
4 // rights of fair usage, the disclaimer and warranty conditions. // 4 // rights of fair usage, the disclaimer and warranty conditions. //
5 /////////////////////////////////////////////////////////////////////////// 5 ///////////////////////////////////////////////////////////////////////////
6   6  
7 using System.Collections; 7 using System.Collections;
8 using System.Collections.Generic; 8 using System.Collections.Generic;
9 using System.Collections.Specialized; 9 using System.Collections.Specialized;
10 using System.Threading; 10 using System.Threading;
11   11  
12 namespace wasSharp.Collections.Specialized 12 namespace wasSharp.Collections.Specialized
13 { 13 {
14 /////////////////////////////////////////////////////////////////////////// 14 ///////////////////////////////////////////////////////////////////////////
15 // Copyright (C) 2016 Wizardry and Steamworks - License: GNU GPLv3 // 15 // Copyright (C) 2016 Wizardry and Steamworks - License: GNU GPLv3 //
16 /////////////////////////////////////////////////////////////////////////// 16 ///////////////////////////////////////////////////////////////////////////
17 /// <summary> 17 /// <summary>
18 /// An implementation of an observable Dictionary. 18 /// An implementation of an observable Dictionary.
19 /// </summary> 19 /// </summary>
20 /// <typeparam name="K">the key type</typeparam> 20 /// <typeparam name="K">the key type</typeparam>
21 /// <typeparam name="V">the value type</typeparam> 21 /// <typeparam name="V">the value type</typeparam>
22 public class ObservableDictionary<K, V> : IDictionary<K, V>, INotifyCollectionChanged 22 public class ObservableDictionary<K, V> : IDictionary<K, V>, INotifyCollectionChanged
23 { 23 {
24 private readonly ReaderWriterLockSlim SyncRoot = new ReaderWriterLockSlim(LockRecursionPolicy.SupportsRecursion); 24 private readonly ReaderWriterLockSlim _lock = new ReaderWriterLockSlim(LockRecursionPolicy.SupportsRecursion);
25 private readonly Dictionary<K, V> store = new Dictionary<K, V>(); 25 private readonly Dictionary<K, V> store = new Dictionary<K, V>();
26   26  
27 public bool IsVirgin { get; private set; } = true; 27 public bool IsVirgin { get; private set; } = true;
28   28  
29 public V this[K key] 29 public V this[K key]
30 { 30 {
31 get 31 get
32 { 32 {
33 SyncRoot.EnterReadLock(); 33 _lock.EnterReadLock();
-   34 try
-   35 {
34 var v = store[key]; 36 return store[key];
-   37 }
-   38 finally
-   39 {
35 SyncRoot.ExitReadLock(); 40 if (_lock.IsReadLockHeld) _lock.ExitReadLock();
36 return v; 41 }
37 } 42 }
38   43  
39 set 44 set
40 { 45 {
41 SyncRoot.EnterWriteLock(); 46 _lock.EnterWriteLock();
-   47 try
-   48 {
42 store[key] = value; 49 store[key] = value;
-   50 }
-   51 finally
-   52 {
43 SyncRoot.ExitWriteLock(); 53 if (_lock.IsWriteLockHeld) _lock.ExitWriteLock();
-   54 }
44 } 55 }
45 } 56 }
46   57  
47 public int Count => store.Count; 58 public int Count => store.Count;
48   59  
49 public bool IsReadOnly => false; 60 public bool IsReadOnly => false;
50   61  
51 public ICollection<K> Keys 62 public ICollection<K> Keys
52 { 63 {
53 get 64 get
54 { 65 {
55 SyncRoot.EnterReadLock(); 66 _lock.EnterReadLock();
-   67 try
-   68 {
56 var v = store.Keys; 69 return store.Keys;
-   70 }
-   71 finally
-   72 {
57 SyncRoot.ExitReadLock(); 73 if (_lock.IsReadLockHeld) _lock.ExitReadLock();
58 return v; 74 }
59 } 75 }
60 } 76 }
61   77  
62 public ICollection<V> Values 78 public ICollection<V> Values
63 { 79 {
64 get 80 get
65 { 81 {
66 SyncRoot.EnterReadLock(); 82 _lock.EnterReadLock();
-   83 try
-   84 {
67 var v = store.Values; 85 return store.Values;
-   86 }
-   87 finally
-   88 {
68 SyncRoot.ExitReadLock(); 89 if (_lock.IsReadLockHeld) _lock.ExitReadLock();
69 return v; 90 }
70 } 91 }
71 } 92 }
72   93  
73 public void Add(KeyValuePair<K, V> item) 94 public void Add(KeyValuePair<K, V> item)
74 { 95 {
75 SyncRoot.EnterWriteLock(); 96 _lock.EnterWriteLock();
-   97 try
-   98 {
76 ((IDictionary<K, V>)store).Add(item); 99 ((IDictionary<K, V>) store).Add(item);
-   100 }
-   101 finally
-   102 {
77 SyncRoot.ExitWriteLock(); 103 if (_lock.IsWriteLockHeld) _lock.ExitWriteLock();
-   104 }
78 IsVirgin = false; 105 IsVirgin = false;
79 OnCollectionChanged(new NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction.Add, item)); 106 OnCollectionChanged(new NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction.Add, item));
80 } 107 }
81   108  
82 public void Add(K key, V value) 109 public void Add(K key, V value)
83 { 110 {
84 SyncRoot.EnterWriteLock(); 111 _lock.EnterWriteLock();
-   112 try
-   113 {
85 store.Add(key, value); 114 store.Add(key, value);
-   115 }
-   116 finally
-   117 {
86 SyncRoot.ExitWriteLock(); 118 if (_lock.IsWriteLockHeld) _lock.ExitWriteLock();
-   119 }
87 IsVirgin = false; 120 IsVirgin = false;
88 OnCollectionChanged(new NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction.Add, 121 OnCollectionChanged(new NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction.Add,
89 new KeyValuePair<K, V>(key, value))); 122 new KeyValuePair<K, V>(key, value)));
90 } 123 }
91   124  
92 public void Clear() 125 public void Clear()
93 { 126 {
94 SyncRoot.EnterWriteLock(); 127 _lock.EnterWriteLock();
-   128 try
-   129 {
95 store.Clear(); 130 store.Clear();
-   131 }
-   132 finally
-   133 {
96 SyncRoot.ExitWriteLock(); 134 if (_lock.IsWriteLockHeld) _lock.ExitWriteLock();
-   135 }
97 if (!IsVirgin) 136 if (!IsVirgin)
98 OnCollectionChanged(new NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction.Reset)); 137 OnCollectionChanged(new NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction.Reset));
99 IsVirgin = false; 138 IsVirgin = false;
100 } 139 }
101   140  
102 public bool Contains(KeyValuePair<K, V> item) 141 public bool Contains(KeyValuePair<K, V> item)
103 { 142 {
104 SyncRoot.EnterReadLock(); 143 _lock.EnterReadLock();
-   144 try
-   145 {
105 var c = ((IDictionary<K, V>)store).Contains(item); 146 return ((IDictionary<K, V>) store).Contains(item);
-   147 }
-   148 finally
-   149 {
106 SyncRoot.ExitReadLock(); 150 if (_lock.IsReadLockHeld) _lock.ExitReadLock();
107 return c; 151 }
108 } 152 }
109   153  
110 public bool ContainsKey(K key) 154 public bool ContainsKey(K key)
111 { 155 {
112 SyncRoot.EnterReadLock(); 156 _lock.EnterReadLock();
-   157 try
-   158 {
113 var c = store.ContainsKey(key); 159 return store.ContainsKey(key);
-   160 }
-   161 finally
-   162 {
114 SyncRoot.ExitReadLock(); 163 if (_lock.IsReadLockHeld) _lock.ExitReadLock();
115 return c; 164 }
116 } 165 }
117   166  
118 public void CopyTo(KeyValuePair<K, V>[] array, int arrayIndex) 167 public void CopyTo(KeyValuePair<K, V>[] array, int arrayIndex)
119 { 168 {
120 SyncRoot.EnterReadLock(); 169 _lock.EnterReadLock();
-   170 try
-   171 {
121 ((IDictionary<K, V>)store).CopyTo(array, arrayIndex); 172 ((IDictionary<K, V>) store).CopyTo(array, arrayIndex);
-   173 }
-   174 finally
-   175 {
122 SyncRoot.ExitReadLock(); 176 if (_lock.IsReadLockHeld) _lock.ExitReadLock();
-   177 }
123 } 178 }
124   179  
125 public IEnumerator<KeyValuePair<K, V>> GetEnumerator() 180 public IEnumerator<KeyValuePair<K, V>> GetEnumerator()
126 { 181 {
127 SyncRoot.EnterReadLock(); 182 _lock.EnterReadLock();
-   183 try
-   184 {
128 var enumerator = ((IDictionary<K, V>)store).GetEnumerator(); 185 using (var enumerator = ((IDictionary<K, V>)store).GetEnumerator())
-   186 {
129 SyncRoot.ExitReadLock(); 187 while (enumerator.MoveNext())
130 return enumerator; 188 yield return enumerator.Current;
-   189 }
-   190 }
-   191 finally
-   192 {
-   193 if (_lock.IsReadLockHeld) _lock.ExitReadLock();
-   194 }
131 } 195 }
132   196  
133 public bool Remove(KeyValuePair<K, V> item) 197 public bool Remove(KeyValuePair<K, V> item)
134 { 198 {
135 SyncRoot.EnterWriteLock(); 199 _lock.EnterWriteLock();
-   200 bool removed;
-   201 try
-   202 {
136 var removed = ((IDictionary<K, V>)store).Remove(item); 203 removed = ((IDictionary<K, V>) store).Remove(item);
-   204 }
-   205 finally
-   206 {
137 SyncRoot.ExitWriteLock(); 207 if (_lock.IsWriteLockHeld) _lock.ExitWriteLock();
-   208 }
138 IsVirgin = false; 209 IsVirgin = false;
139 if (removed) 210 if (removed)
140 OnCollectionChanged(new NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction.Remove, item)); 211 OnCollectionChanged(new NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction.Remove, item));
141 return removed; 212 return removed;
142 } 213 }
143   214  
144 public bool Remove(K key) 215 public bool Remove(K key)
145 { 216 {
146 KeyValuePair<K, V> item; 217 KeyValuePair<K, V> item;
147 SyncRoot.EnterWriteLock(); 218 _lock.EnterWriteLock();
-   219 bool removed;
-   220 try
-   221 {
148 if (store.ContainsKey(key)) 222 if (store.ContainsKey(key))
149 item = new KeyValuePair<K, V>(key, store[key]); 223 item = new KeyValuePair<K, V>(key, store[key]);
150   224  
-   225 removed = store.Remove(key);
-   226 }
-   227 finally
151 var removed = store.Remove(key); 228 {
-   229 if (_lock.IsWriteLockHeld) _lock.ExitWriteLock();
152 SyncRoot.ExitWriteLock(); 230 }
153 IsVirgin = false; 231 IsVirgin = false;
154 if (removed) 232 if (removed)
155 OnCollectionChanged(new NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction.Remove, item)); 233 OnCollectionChanged(new NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction.Remove, item));
156 return removed; 234 return removed;
157 } 235 }
158   236  
159 public bool TryGetValue(K key, out V value) 237 public bool TryGetValue(K key, out V value)
160 { 238 {
161 SyncRoot.EnterReadLock(); 239 _lock.EnterReadLock();
-   240 try
-   241 {
162 var c = store.TryGetValue(key, out value); 242 return store.TryGetValue(key, out value);
-   243 }
-   244 finally
-   245 {
163 SyncRoot.ExitReadLock(); 246 if (_lock.IsReadLockHeld) _lock.ExitReadLock();
164 return c; 247 }
165 } 248 }
166   249  
167 IEnumerator IEnumerable.GetEnumerator() 250 IEnumerator IEnumerable.GetEnumerator()
168 { 251 {
169 SyncRoot.EnterReadLock(); 252 _lock.EnterReadLock();
-   253 try
-   254 {
170 var enumerator = ((IDictionary<K, V>)store).GetEnumerator(); 255 using (var enumerator = ((IDictionary<K, V>)store).GetEnumerator())
-   256 {
171 SyncRoot.ExitReadLock(); 257 while (enumerator.MoveNext())
172 return enumerator; 258 yield return enumerator.Current;
-   259 }
-   260 }
-   261 finally
-   262 {
-   263 if (_lock.IsReadLockHeld) _lock.ExitReadLock();
-   264 }
173 } 265 }
174   266  
175 public event NotifyCollectionChangedEventHandler CollectionChanged; 267 public event NotifyCollectionChangedEventHandler CollectionChanged;
176   268  
177 private void OnCollectionChanged(NotifyCollectionChangedEventArgs args) 269 private void OnCollectionChanged(NotifyCollectionChangedEventArgs args)
178 { 270 {
179 CollectionChanged?.Invoke(this, args); 271 CollectionChanged?.Invoke(this, args);
180 } 272 }
181 } 273 }
182 } 274 }
183   275