wasSharp – Blame information for rev 39

Subversion Repositories:
Rev:
Rev Author Line No. Line
10 office 1 ///////////////////////////////////////////////////////////////////////////
2 // Copyright (C) Wizardry and Steamworks 2013 - 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;
39 office 8 using System.Threading;
10 office 9 using System.Collections;
10 using System.Collections.Generic;
11 using System.Collections.Specialized;
12 using System.Linq;
13  
14 namespace wasSharp.Collections.Specialized
15 {
16 ///////////////////////////////////////////////////////////////////////////
17 // Copyright (C) 2014 Wizardry and Steamworks - License: GNU GPLv3 //
18 ///////////////////////////////////////////////////////////////////////////
19 /// <summary>
20 /// An implementation of an observable HashSet.
21 /// </summary>
22 /// <typeparam name="T">the object type</typeparam>
23 office 23 public class ObservableHashSet<T> : ICollection<T>, INotifyCollectionChanged, IEnumerable<T>
10 office 24 {
39 office 25 private readonly ReaderWriterLockSlim SyncRoot = new ReaderWriterLockSlim(LockRecursionPolicy.SupportsRecursion);
10 office 26 private readonly HashSet<T> store = new HashSet<T>();
27  
28 public ObservableHashSet(HashSet<T> set)
29 {
39 office 30 SyncRoot.EnterWriteLock();
10 office 31 UnionWith(set);
39 office 32 SyncRoot.ExitWriteLock();
10 office 33 }
34  
35 public ObservableHashSet()
36 {
37 }
38  
39 public ObservableHashSet(T item)
40 {
39 office 41 SyncRoot.EnterWriteLock();
10 office 42 Add(item);
39 office 43 SyncRoot.ExitWriteLock();
10 office 44 }
45  
46 public ObservableHashSet(ObservableHashSet<T> other)
47 {
39 office 48 SyncRoot.EnterWriteLock();
10 office 49 UnionWith(other);
39 office 50 SyncRoot.ExitWriteLock();
10 office 51 }
52  
53 public ObservableHashSet(IEnumerable<T> list)
54 {
39 office 55 SyncRoot.EnterWriteLock();
10 office 56 UnionWith(list);
39 office 57 SyncRoot.ExitWriteLock();
10 office 58 }
59  
60 public bool IsVirgin { get; private set; } = true;
61  
62 public IEnumerator<T> GetEnumerator()
63 {
39 office 64 SyncRoot.EnterReadLock();
65 var enumerator = store.GetEnumerator();
66 SyncRoot.ExitReadLock();
67 return enumerator;
10 office 68 }
69  
70 IEnumerator IEnumerable.GetEnumerator()
71 {
39 office 72 SyncRoot.EnterReadLock();
73 var enumerator = GetEnumerator();
74 SyncRoot.ExitReadLock();
75 return enumerator;
10 office 76 }
77  
78 public void Add(T item)
79 {
39 office 80 SyncRoot.EnterWriteLock();
10 office 81 store.Add(item);
39 office 82 SyncRoot.ExitWriteLock();
10 office 83 IsVirgin = false;
84 OnCollectionChanged(new NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction.Add, item));
85 }
86  
87 public void Clear()
88 {
39 office 89 SyncRoot.EnterWriteLock();
10 office 90 store.Clear();
39 office 91 SyncRoot.ExitWriteLock();
10 office 92 if (!IsVirgin)
93 OnCollectionChanged(new NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction.Reset));
94 IsVirgin = false;
95 }
96  
97 public bool Contains(T item)
98 {
39 office 99 SyncRoot.EnterReadLock();
100 var contains = store.Contains(item);
101 SyncRoot.ExitReadLock();
102 return contains;
10 office 103 }
104  
105 public void CopyTo(T[] array, int arrayIndex)
106 {
39 office 107 SyncRoot.EnterReadLock();
10 office 108 store.CopyTo(array, arrayIndex);
39 office 109 SyncRoot.ExitReadLock();
10 office 110 }
111  
112 public bool Remove(T item)
113 {
39 office 114 SyncRoot.EnterWriteLock();
10 office 115 var removed = store.Remove(item);
39 office 116 SyncRoot.ExitWriteLock();
10 office 117 IsVirgin = false;
118 if (removed)
119 OnCollectionChanged(new NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction.Remove, item));
120 return removed;
121 }
122  
123 public int Count => store.Count;
124  
125 public bool IsReadOnly => false;
126  
127 public event NotifyCollectionChangedEventHandler CollectionChanged;
128  
129 public void UnionWith(IEnumerable<T> list)
130 {
131 var added = new List<T>(list.Except(store));
39 office 132 SyncRoot.EnterWriteLock();
10 office 133 store.UnionWith(added);
39 office 134 SyncRoot.ExitWriteLock();
10 office 135 if (!IsVirgin && added.Any())
136 OnCollectionChanged(new NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction.Add, added));
137 IsVirgin = false;
138 }
139  
140 private void OnCollectionChanged(NotifyCollectionChangedEventArgs args)
141 {
142 CollectionChanged?.Invoke(this, args);
143 }
144  
145 public void ExceptWith(IEnumerable<T> list)
146 {
147 var removed = new List<T>(list.Intersect(store));
39 office 148 SyncRoot.EnterWriteLock();
10 office 149 store.ExceptWith(removed);
39 office 150 SyncRoot.ExitWriteLock();
10 office 151 if (!IsVirgin && removed.Any())
152 OnCollectionChanged(new NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction.Remove,
153 removed));
154 IsVirgin = false;
155 }
156  
157 public void RemoveWhere(Func<T, bool> func)
158 {
159 var removed = new List<T>(store.Where(func));
39 office 160 SyncRoot.EnterWriteLock();
10 office 161 store.ExceptWith(removed);
39 office 162 SyncRoot.ExitWriteLock();
10 office 163 if (!IsVirgin && removed.Any())
164 OnCollectionChanged(new NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction.Remove,
165 removed));
166 IsVirgin = false;
167 }
23 office 168  
169 public IEnumerable<T> AsEnumerable()
170 {
39 office 171 SyncRoot.EnterWriteLock();
172 var enumerable = store.AsEnumerable();
173 SyncRoot.ExitWriteLock();
174 return enumerable;
23 office 175 }
10 office 176 }
27 office 177 }