152
|
1 using System;
|
|
2 using System.Collections.Generic;
|
|
3 using System.Linq;
|
|
4
|
|
5 namespace Implab.Components {
|
|
6 /// <summary>
|
153
|
7 /// Component container, used to store track components in multi-threaded environmment.
|
152
|
8 /// </summary>
|
|
9 /// <remarks>Instanses of this class are thread safe.</remarks>
|
|
10 public class ComponentContainer<T> : Disposable, ICollection<T> {
|
216
|
11 List<T> m_components = new List<T>();
|
|
12 readonly object m_lock = new object();
|
152
|
13
|
153
|
14 /// <summary>
|
|
15 /// Removes currently stored compoenents from the container and disposes them if possible.
|
|
16 /// </summary>
|
|
17 /// <remarks>
|
|
18 /// A new components may be added before this method completes.
|
|
19 /// </remarks>
|
152
|
20 public void Clear() {
|
216
|
21 List<T> removed;
|
152
|
22
|
216
|
23 lock (m_lock) {
|
|
24 removed = m_components;
|
|
25 m_components = new List<T>();
|
152
|
26 }
|
|
27
|
|
28 foreach (var item in removed.OfType<IDisposable>())
|
|
29 item.Dispose();
|
|
30 }
|
|
31
|
153
|
32 /// <summary>
|
|
33 /// Checks whether the specified item in the collection.
|
|
34 /// </summary>
|
|
35 /// <param name="item">The item to check.</param>
|
152
|
36 public bool Contains(T item) {
|
216
|
37 lock (m_lock)
|
152
|
38 return m_components.Contains(item);
|
|
39 }
|
|
40
|
153
|
41 /// <summary>
|
|
42 /// Copies currently stored components to the specified array.
|
|
43 /// </summary>
|
|
44 /// <param name="array">A destination array for components.</param>
|
|
45 /// <param name="arrayIndex">A starting index in the destination array.</param>
|
152
|
46 public void CopyTo(T[] array, int arrayIndex) {
|
216
|
47 lock (m_lock)
|
152
|
48 m_components.CopyTo(array, arrayIndex);
|
|
49 }
|
|
50
|
153
|
51 /// <summary>
|
|
52 /// Remove the specified item from the collection.
|
|
53 /// </summary>
|
|
54 /// <param name="item">The item to remove.</param>
|
152
|
55 public bool Remove(T item) {
|
216
|
56 lock (m_lock)
|
152
|
57 return m_components.Remove(item);
|
|
58 }
|
|
59
|
153
|
60 /// <summary>
|
|
61 /// Gets the count of components in the collection.
|
|
62 /// </summary>
|
152
|
63 public int Count {
|
|
64 get {
|
216
|
65 lock (m_lock)
|
152
|
66 return m_components.Count;
|
|
67 }
|
|
68 }
|
|
69
|
153
|
70 /// <summary>
|
|
71 /// Gets a value indicating whether this instance is read only.
|
|
72 /// </summary>
|
|
73 /// <remarks>
|
|
74 /// Always false.
|
|
75 /// </remarks>
|
152
|
76 public bool IsReadOnly {
|
|
77 get {
|
|
78 return false;
|
|
79 }
|
|
80 }
|
|
81
|
153
|
82 /// <summary>
|
|
83 /// Gets the enumerator for components in the collection.
|
|
84 /// </summary>
|
|
85 /// <returns>The enumerator.</returns>
|
152
|
86 public IEnumerator<T> GetEnumerator() {
|
216
|
87 T[] items = new T[m_components.Count];
|
|
88 lock (m_lock) {
|
152
|
89 m_components.CopyTo(items);
|
|
90 }
|
216
|
91 return (IEnumerator<T>)items.GetEnumerator();
|
152
|
92 }
|
|
93
|
|
94 System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator() {
|
|
95 return GetEnumerator();
|
|
96 }
|
|
97
|
153
|
98 /// <summary>
|
|
99 /// Add the specified item to the collection.
|
|
100 /// </summary>
|
|
101 /// <param name="item">The item to add.</param>
|
|
102 /// <remarks>
|
|
103 /// If the collection is alredy disposed, the item isn't added to the collection and disposed if possible.
|
|
104 /// </remarks>
|
152
|
105 public void Add(T item) {
|
|
106 Safe.ArgumentNotNull(item, "item");
|
216
|
107 bool dispose = false;
|
|
108 lock (m_lock) {
|
152
|
109 if (IsDisposed)
|
216
|
110 dispose = true;
|
152
|
111 else
|
|
112 m_components.Add(item);
|
|
113 }
|
216
|
114 if (dispose)
|
|
115 Safe.Dispose(item);
|
152
|
116 }
|
|
117
|
153
|
118 /// <summary>
|
|
119 /// Disposes the components stored in the collection.
|
|
120 /// </summary>
|
|
121 /// <param name="disposing">If set to <c>true</c> the collection is disposing.</param>
|
152
|
122 protected override void Dispose(bool disposing) {
|
216
|
123 if (disposing)
|
|
124 Clear();
|
|
125
|
152
|
126 base.Dispose(disposing);
|
|
127 }
|
|
128 }
|
|
129 }
|
|
130
|