Mercurial > pub > ImplabNet
diff Implab/Components/ComponentContainer.cs @ 152:240aa6994018 v2
component model refactoring
author | cin |
---|---|
date | Thu, 11 Feb 2016 01:56:27 +0300 |
parents | |
children | b933ec88446e |
line wrap: on
line diff
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Implab/Components/ComponentContainer.cs Thu Feb 11 01:56:27 2016 +0300 @@ -0,0 +1,84 @@ +using System; +using System.Collections.Generic; +using System.Linq; + +namespace Implab.Components { + /// <summary> + /// Component container. + /// </summary> + /// <remarks>Instanses of this class are thread safe.</remarks> + public class ComponentContainer<T> : Disposable, ICollection<T> { + readonly HashSet<T> m_components = new HashSet<T>(); + + public void Clear() { + T[] removed; + + lock (m_components) { + removed = new T[m_components.Count]; + m_components.CopyTo(removed); + m_components.Clear(); + } + + foreach (var item in removed.OfType<IDisposable>()) + item.Dispose(); + } + + public bool Contains(T item) { + lock (m_components) + return m_components.Contains(item); + } + + public void CopyTo(T[] array, int arrayIndex) { + lock (m_components) + m_components.CopyTo(array, arrayIndex); + } + + public bool Remove(T item) { + lock (m_components) + return m_components.Remove(item); + } + + public int Count { + get { + lock (m_components) + return m_components.Count; + } + } + + public bool IsReadOnly { + get { + return false; + } + } + + public IEnumerator<T> GetEnumerator() { + T[] items; + lock (m_components) { + items = new T[m_components.Count]; + m_components.CopyTo(items); + return (IEnumerator<T>)items.GetEnumerator(); + } + } + + System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator() { + return GetEnumerator(); + } + + public void Add(T item) { + Safe.ArgumentNotNull(item, "item"); + + lock (m_components) { + if (IsDisposed) + Safe.Dispose(item); + else + m_components.Add(item); + } + } + + protected override void Dispose(bool disposing) { + base.Dispose(disposing); + Clear(); + } + } +} +