view 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 source

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();
        }
    }
}