using System;
using System.Collections.Generic;
using System.Linq;
namespace Implab.Components {
///
/// Component container, used to store track components in multi-threaded environmment.
///
/// Instanses of this class are thread safe.
public class ComponentContainer : Disposable, ICollection {
List m_components = new List();
readonly object m_lock = new object();
///
/// Removes currently stored compoenents from the container and disposes them if possible.
///
///
/// A new components may be added before this method completes.
///
public void Clear() {
List removed;
lock (m_lock) {
removed = m_components;
m_components = new List();
}
foreach (var item in removed.OfType())
item.Dispose();
}
///
/// Checks whether the specified item in the collection.
///
/// The item to check.
public bool Contains(T item) {
lock (m_lock)
return m_components.Contains(item);
}
///
/// Copies currently stored components to the specified array.
///
/// A destination array for components.
/// A starting index in the destination array.
public void CopyTo(T[] array, int arrayIndex) {
lock (m_lock)
m_components.CopyTo(array, arrayIndex);
}
///
/// Remove the specified item from the collection.
///
/// The item to remove.
public bool Remove(T item) {
lock (m_lock)
return m_components.Remove(item);
}
///
/// Gets the count of components in the collection.
///
public int Count {
get {
lock (m_lock)
return m_components.Count;
}
}
///
/// Gets a value indicating whether this instance is read only.
///
///
/// Always false.
///
public bool IsReadOnly {
get {
return false;
}
}
///
/// Gets the enumerator for components in the collection.
///
/// The enumerator.
public IEnumerator GetEnumerator() {
T[] items = new T[m_components.Count];
lock (m_lock) {
m_components.CopyTo(items);
}
return (IEnumerator)items.GetEnumerator();
}
System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator() {
return GetEnumerator();
}
///
/// Add the specified item to the collection.
///
/// The item to add.
///
/// If the collection is alredy disposed, the item isn't added to the collection and disposed if possible.
///
public void Add(T item) {
Safe.ArgumentNotNull(item, "item");
bool dispose = false;
lock (m_lock) {
if (IsDisposed)
dispose = true;
else
m_components.Add(item);
}
if (dispose)
Safe.Dispose(item);
}
///
/// Disposes the components stored in the collection.
///
/// If set to true the collection is disposing.
protected override void Dispose(bool disposing) {
if (disposing)
Clear();
base.Dispose(disposing);
}
}
}