wasSharp – Blame information for rev

Subversion Repositories:
Rev:
Rev Author Line No. Line
4 zed 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 office 7 using System;
8 using System.Collections;
4 zed 9 using System.Collections.Generic;
7 office 10 using System.Collections.ObjectModel;
11 using System.Collections.Specialized;
12 using System.IO;
13 using System.Linq;
4 zed 14 using System.Xml;
15 using System.Xml.Schema;
16 using System.Xml.Serialization;
17  
18 namespace wasSharp
19 {
7 office 20 public static class Collections
4 zed 21 {
7 office 22 ///////////////////////////////////////////////////////////////////////////
23 // Copyright (C) 2016 Wizardry and Steamworks - License: GNU GPLv3 //
24 ///////////////////////////////////////////////////////////////////////////
4 zed 25 /// <summary>
7 office 26 /// A circular queue implementation based on linked lists.
27 /// </summary>
28 /// <typeparam name="T">the type of value to store</typeparam>
29 public class CircularQueue<T>
30 {
31 private readonly LinkedList<T> Store = new LinkedList<T>();
32 private LinkedListNode<T> CurrentNode = null;
33  
34 object SyncRoot = new object();
35  
36 public int Count
37 {
38 get
39 {
40 lock (SyncRoot)
41 {
42 return Store.Count;
43 }
44 }
45 }
46  
47 private T GetNext
48 {
49 get
50 {
51 lock (SyncRoot)
52 {
53  
54 if (CurrentNode == null)
55 return default(T);
56  
57 T value = CurrentNode.Value;
58  
59 switch (CurrentNode.Next != null)
60 {
61 case true:
62 CurrentNode = CurrentNode.Next;
63 break;
64 default:
65 CurrentNode = Store.First;
66 break;
67 }
68  
69 return value;
70 }
71 }
72 }
73  
74 public IEnumerable<T> Items
75 {
76 get
77 {
78 lock (SyncRoot)
79 {
80  
81 if (CurrentNode == null)
82 yield break;
83  
84 var node = CurrentNode;
85 do
86 {
87 yield return node.Value;
88 node = node.Next;
89 } while (node != null);
90 }
91 }
92 }
93  
94 public CircularQueue()
95 {
96  
97 }
98  
99 public CircularQueue(IEnumerable<T> items)
100 {
101 Enqueue(items);
102 }
103  
104 public CircularQueue(CircularQueue<T> queue)
105 {
106 lock (SyncRoot)
107 {
108 lock (queue.SyncRoot)
109 {
110  
111 foreach (var item in queue.Items)
112 {
113 Store.AddLast(item);
114 }
115  
116 if (CurrentNode == null)
117 CurrentNode = Store.First;
118 }
119 }
120 }
121  
122 public void Enqueue(IEnumerable<T> items)
123 {
124 lock (SyncRoot)
125 {
126 foreach (var i in items)
127 Store.AddLast(i);
128  
129 if (CurrentNode == null)
130 CurrentNode = Store.First;
131 }
132 }
133  
134 public void Enqueue(T item)
135 {
136 lock (SyncRoot)
137 {
138  
139 Store.AddLast(item);
140  
141 if (CurrentNode == null)
142 CurrentNode = Store.First;
143 }
144 }
145  
146 public T Dequeue()
147 {
148 lock (SyncRoot)
149 {
150 return GetNext;
151 }
152 }
153  
154 public IEnumerable<T> Dequeue(int count = 1)
155 {
156 if (count <= 0)
157 yield break;
158  
159 lock (SyncRoot)
160 {
161 if(CurrentNode == null)
162 yield break;
163  
164 do
165 {
166 yield return GetNext;
167 } while (--count != 0);
168 }
169 }
170  
171 public void Clear()
172 {
173 lock (SyncRoot)
174 {
175 Store.Clear();
176  
177 CurrentNode = null;
178 }
179 }
180  
181 public bool Contains(T item)
182 {
183 lock (SyncRoot)
184 {
185 return Store.Contains(item);
186 }
187 }
188  
189 public void CopyTo(T[] array, int arrayIndex)
190 {
191 lock (SyncRoot)
192 {
193 Store.CopyTo(array, arrayIndex);
194 }
195 }
196  
197 public bool Remove(T item)
198 {
199 lock (SyncRoot)
200 {
201 var node = Store.Find(item);
202 if (node == null)
203 return false;
204 if (CurrentNode.Equals(node))
205 {
206 switch (node.Next != null)
207 {
208 case true:
209 CurrentNode = node.Next;
210 break;
211 default:
212 CurrentNode = Store.First;
213 break;
214 }
215 }
216 Store.Remove(node);
217 return true;
218 }
219 }
220  
221 public void RemoveAll(IEnumerable<T> items)
222 {
223 var itemSet = new HashSet<T>(items);
224 lock (SyncRoot)
225 {
226 var node = CurrentNode;
227 do
228 {
229 var next = node.Next;
230 if (itemSet.Contains(node.Value))
231 {
232 switch (next != null)
233 {
234 case true:
235 CurrentNode = next;
236 break;
237 default:
238 CurrentNode = Store.First;
239 break;
240 }
241 Store.Remove(node);
242 }
243 node = next;
244 } while (node != null);
245 }
246 }
247 }
248  
249 ///////////////////////////////////////////////////////////////////////////
250 // Copyright (C) 2016 Wizardry and Steamworks - License: GNU GPLv3 //
251 ///////////////////////////////////////////////////////////////////////////
252 /// <summary>
253 /// A collection that maps ranges to values with O(1) complexity
254 /// lookups and O(n) insertions.
255 /// </summary>
256 /// <typeparam name="T">the type of value to store</typeparam>
257 public class RangeCollection<T> : IEnumerable
258 {
259 private Dictionary<int, T> map = null;
260  
261 public RangeCollection(int min, int max)
262 {
263 map = new Dictionary<int, T>(max - min);
264 }
265  
266 /// <summary>
267 /// Map a value to a range.
268 /// </summary>
269 /// <param name="Value">the value for the range</param>
270 /// <param name="min">the minimal range</param>
271 /// <param name="max">the maximal range</param>
272 public void Add(T Value, int min, int max)
273 {
274 foreach (var i in Enumerable.Range(min, max - min + 1))
275 {
276 map.Add(i, Value);
277 }
278 }
279  
280 public IEnumerator GetEnumerator()
281 {
282 return ((IEnumerable)map).GetEnumerator();
283 }
284  
285 public T this[int x]
286 {
287 get
288 {
289 T value;
290 return map.TryGetValue(x, out value) ? value : default(T);
291 }
292 }
293 }
294  
295 ///////////////////////////////////////////////////////////////////////////
296 // Copyright (C) 2016 Wizardry and Steamworks - License: GNU GPLv3 //
297 ///////////////////////////////////////////////////////////////////////////
298 /// <summary>
299 /// Returns true of an enumerable contains more than one element.
300 /// </summary>
301 /// <typeparam name="T">the type of the enumeration</typeparam>
302 /// <param name="e">the enumeration</param>
303 /// <returns>true if enumeration contains more than one element</returns>
304 /// <remarks>O(2) worst case</remarks>
305 public static bool Some<T>(this IEnumerable<T> e)
306 {
307 int i = 0;
308 using (var iter = e.GetEnumerator())
309 {
310 while (iter.MoveNext())
311 {
312 if (++i > 1)
313 return true;
314 }
315 return false;
316 }
317 }
318  
319 /// <summary>
320 /// Compares two dictionaries for equality.
321 /// </summary>
322 /// <typeparam name="TKey">key type</typeparam>
323 /// <typeparam name="TValue">value type</typeparam>
324 /// <param name="dictionary">dictionary to compare</param>
325 /// <param name="otherDictionary">dictionary to compare to</param>
326 /// <returns>true if the dictionaries contain the same elements</returns>
327 public static bool ContentEquals<TKey, TValue>(this IDictionary<TKey, TValue> dictionary,
328 IDictionary<TKey, TValue> otherDictionary)
329 {
330 return
331 (dictionary ?? new Dictionary<TKey, TValue>()).Count.Equals(
332 (otherDictionary ?? new Dictionary<TKey, TValue>()).Count) &&
333 (otherDictionary ?? new Dictionary<TKey, TValue>())
334 .OrderBy(kvp => kvp.Key)
335 .SequenceEqual((dictionary ?? new Dictionary<TKey, TValue>())
336 .OrderBy(kvp => kvp.Key));
337 }
338  
339 ///////////////////////////////////////////////////////////////////////////
340 // Copyright (C) 2014 Wizardry and Steamworks - License: GNU GPLv3 //
341 ///////////////////////////////////////////////////////////////////////////
342 /// <summary>
343 /// An implementation of an observable HashSet.
344 /// </summary>
345 /// <typeparam name="T">the object type</typeparam>
346 public class ObservableHashSet<T> : ICollection<T>, INotifyCollectionChanged
347 {
348 private readonly HashSet<T> store = new HashSet<T>();
349  
350 public ObservableHashSet(HashSet<T> set)
351 {
352 UnionWith(set);
353 }
354  
355 public ObservableHashSet()
356 {
357 }
358  
359 public ObservableHashSet(T item)
360 {
361 Add(item);
362 }
363  
364 public ObservableHashSet(ObservableHashSet<T> other)
365 {
366 UnionWith(other);
367 }
368  
369 public ObservableHashSet(IEnumerable<T> list)
370 {
371 UnionWith(list);
372 }
373  
374 public bool IsVirgin { get; private set; } = true;
375  
376 public IEnumerator<T> GetEnumerator()
377 {
378 return store.GetEnumerator();
379 }
380  
381 IEnumerator IEnumerable.GetEnumerator()
382 {
383 return GetEnumerator();
384 }
385  
386 public void Add(T item)
387 {
388 store.Add(item);
389 IsVirgin = false;
390 OnCollectionChanged(new NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction.Add, item));
391 }
392  
393 public void Clear()
394 {
395 store.Clear();
396 if (!IsVirgin)
397 OnCollectionChanged(new NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction.Reset));
398 IsVirgin = false;
399 }
400  
401 public bool Contains(T item)
402 {
403 return store.Contains(item);
404 }
405  
406 public void CopyTo(T[] array, int arrayIndex)
407 {
408 store.CopyTo(array, arrayIndex);
409 }
410  
411 public bool Remove(T item)
412 {
413 var removed = store.Remove(item);
414 IsVirgin = false;
415 if (removed)
416 OnCollectionChanged(new NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction.Remove, item));
417 return removed;
418 }
419  
420 public int Count => store.Count;
421  
422 public bool IsReadOnly => false;
423  
424 public event NotifyCollectionChangedEventHandler CollectionChanged;
425  
426 public void UnionWith(IEnumerable<T> list)
427 {
428 var added = new List<T>(list.Except(store));
429 store.UnionWith(added);
430 if (!IsVirgin && added.Any())
431 OnCollectionChanged(new NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction.Add, added));
432 IsVirgin = false;
433 }
434  
435 private void OnCollectionChanged(NotifyCollectionChangedEventArgs args)
436 {
437 CollectionChanged?.Invoke(this, args);
438 }
439  
440 public void ExceptWith(IEnumerable<T> list)
441 {
442 var removed = new List<T>(list.Intersect(store));
443 store.ExceptWith(removed);
444 if (!IsVirgin && removed.Any())
445 OnCollectionChanged(new NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction.Remove,
446 removed));
447 IsVirgin = false;
448 }
449  
450 public void RemoveWhere(Func<T, bool> func)
451 {
452 var removed = new List<T>(store.Where(func));
453 store.ExceptWith(removed);
454 if (!IsVirgin && removed.Any())
455 OnCollectionChanged(new NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction.Remove,
456 removed));
457 IsVirgin = false;
458 }
459 }
460  
461 /// <summary>
462 /// An observable collection allowing the add of a range of items.
463 /// </summary>
464 /// <typeparam name="T">the collection type</typeparam>
465 public class ExtendedObservableCollection<T> : ObservableCollection<T>
466 {
467 private bool _suppressNotification;
468  
469 protected override void OnCollectionChanged(NotifyCollectionChangedEventArgs e)
470 {
471 if (!_suppressNotification)
472 base.OnCollectionChanged(e);
473 }
474  
475 public void AddRange(IEnumerable<T> list)
476 {
477 if (list == null)
478 throw new ArgumentNullException(nameof(list));
479  
480 _suppressNotification = true;
481  
482 foreach (var item in list)
483 {
484 Add(item);
485 }
486 _suppressNotification = false;
487 OnCollectionChanged(new NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction.Reset));
488 }
489 }
490  
491 /// <summary>
4 zed 492 /// A serializable dictionary class.
493 /// </summary>
494 /// <typeparam name="TKey">the key</typeparam>
495 /// <typeparam name="TValue">the value</typeparam>
496 [XmlRoot("Dictionary")]
497 public class SerializableDictionary<TKey, TValue>
498 : Dictionary<TKey, TValue>, IXmlSerializable
499 {
500 #region IXmlSerializable Members
501  
7 office 502 public SerializableDictionary(IEnumerable<KeyValuePair<TKey, TValue>> kvp)
503 {
504 foreach (var i in kvp)
505 {
506 Add(i.Key, i.Value);
507 }
508 }
509  
510 public SerializableDictionary()
511 {
512 }
513  
514 /// <summary>
515 /// Deep-clones the serializable dictionary.
516 /// </summary>
517 /// <returns>a deep clone of the original dictionary</returns>
518 public SerializableDictionary<TKey, TValue> Clone()
519 {
520 SerializableDictionary<TKey, TValue> clone;
521 try
522 {
523 using (var writer = new MemoryStream())
524 {
525 var serializer =
526 new XmlSerializer(
527 typeof (SerializableDictionary<TKey, TValue>));
528 serializer.Serialize(writer, this);
529 writer.Seek(0, SeekOrigin.Begin);
530 clone = (SerializableDictionary<TKey, TValue>)
531 new XmlSerializer(
532 typeof (SerializableDictionary<TKey, TValue>))
533 .Deserialize(writer);
534 }
535 }
536 /* cloning failed so return an empty dictionary */
537 catch (Exception)
538 {
539 clone = new SerializableDictionary<TKey, TValue>();
540 }
541 return clone;
542 }
543  
4 zed 544 public XmlSchema GetSchema()
545 {
546 return null;
547 }
548  
549 public void ReadXml(XmlReader reader)
550 {
7 office 551 var keySerializer = new XmlSerializer(typeof (TKey));
552 var valueSerializer = new XmlSerializer(typeof (TValue));
4 zed 553  
7 office 554 var wasEmpty = reader.IsEmptyElement;
4 zed 555 reader.Read();
556  
557 if (wasEmpty)
558 return;
559  
7 office 560 while (!reader.NodeType.Equals(XmlNodeType.EndElement))
4 zed 561 {
562 reader.ReadStartElement("Item");
563  
564 reader.ReadStartElement("Key");
7 office 565 var key = (TKey) keySerializer.Deserialize(reader);
4 zed 566 reader.ReadEndElement();
567  
568 reader.ReadStartElement("Value");
7 office 569 var value = (TValue) valueSerializer.Deserialize(reader);
4 zed 570 reader.ReadEndElement();
571  
572 Add(key, value);
573  
574 reader.ReadEndElement();
575 reader.MoveToContent();
576 }
577 reader.ReadEndElement();
578 }
579  
580 public void WriteXml(XmlWriter writer)
581 {
7 office 582 var keySerializer = new XmlSerializer(typeof (TKey));
583 var valueSerializer = new XmlSerializer(typeof (TValue));
4 zed 584  
7 office 585 foreach (var key in Keys)
4 zed 586 {
587 writer.WriteStartElement("Item");
588  
589 writer.WriteStartElement("Key");
590 keySerializer.Serialize(writer, key);
591 writer.WriteEndElement();
592  
593 writer.WriteStartElement("Value");
7 office 594 var value = this[key];
4 zed 595 valueSerializer.Serialize(writer, value);
596 writer.WriteEndElement();
597  
598 writer.WriteEndElement();
599 }
600 }
601  
602 #endregion
603 }
7 office 604  
605 /// <summary>
606 /// A serializable sorted dictionary class.
607 /// </summary>
608 /// <typeparam name="TKey">the key</typeparam>
609 /// <typeparam name="TValue">the value</typeparam>
610 [XmlRoot("SortedDictionary")]
611 public class SerializableSortedDictionary<TKey, TValue>
612 : SortedDictionary<TKey, TValue>, IXmlSerializable
613 {
614 #region IXmlSerializable Members
615  
616 public SerializableSortedDictionary(IEnumerable<KeyValuePair<TKey, TValue>> kvp)
617 {
618 foreach (var i in kvp)
619 {
620 Add(i.Key, i.Value);
621 }
622 }
623  
624 public SerializableSortedDictionary()
625 {
626 }
627  
628 /// <summary>
629 /// Deep-clones the serializable dictionary.
630 /// </summary>
631 /// <returns>a deep clone of the original dictionary</returns>
632 public SerializableSortedDictionary<TKey, TValue> Clone()
633 {
634 SerializableSortedDictionary<TKey, TValue> clone;
635 try
636 {
637 using (var writer = new MemoryStream())
638 {
639 var serializer =
640 new XmlSerializer(
641 typeof(SerializableDictionary<TKey, TValue>));
642 serializer.Serialize(writer, this);
643 writer.Seek(0, SeekOrigin.Begin);
644 clone = (SerializableSortedDictionary<TKey, TValue>)
645 new XmlSerializer(
646 typeof(SerializableSortedDictionary<TKey, TValue>))
647 .Deserialize(writer);
648 }
649 }
650 /* cloning failed so return an empty dictionary */
651 catch (Exception)
652 {
653 clone = new SerializableSortedDictionary<TKey, TValue>();
654 }
655 return clone;
656 }
657  
658 public XmlSchema GetSchema()
659 {
660 return null;
661 }
662  
663 public void ReadXml(XmlReader reader)
664 {
665 var keySerializer = new XmlSerializer(typeof(TKey));
666 var valueSerializer = new XmlSerializer(typeof(TValue));
667  
668 var wasEmpty = reader.IsEmptyElement;
669 reader.Read();
670  
671 if (wasEmpty)
672 return;
673  
674 while (!reader.NodeType.Equals(XmlNodeType.EndElement))
675 {
676 reader.ReadStartElement("Item");
677  
678 reader.ReadStartElement("Key");
679 var key = (TKey)keySerializer.Deserialize(reader);
680 reader.ReadEndElement();
681  
682 reader.ReadStartElement("Value");
683 var value = (TValue)valueSerializer.Deserialize(reader);
684 reader.ReadEndElement();
685  
686 Add(key, value);
687  
688 reader.ReadEndElement();
689 reader.MoveToContent();
690 }
691 reader.ReadEndElement();
692 }
693  
694 public void WriteXml(XmlWriter writer)
695 {
696 var keySerializer = new XmlSerializer(typeof(TKey));
697 var valueSerializer = new XmlSerializer(typeof(TValue));
698  
699 foreach (var key in Keys)
700 {
701 writer.WriteStartElement("Item");
702  
703 writer.WriteStartElement("Key");
704 keySerializer.Serialize(writer, key);
705 writer.WriteEndElement();
706  
707 writer.WriteStartElement("Value");
708 var value = this[key];
709 valueSerializer.Serialize(writer, value);
710 writer.WriteEndElement();
711  
712 writer.WriteEndElement();
713 }
714 }
715  
716 #endregion
717 }
4 zed 718 }
719 }