using System; using System.Collections; using System.Collections.Generic; using System.Linq; namespace Chernobyl.DesignPatterns.Command { /// /// An that implements the composite design pattern /// (see http://en.wikipedia.org/wiki/Composite_pattern) for /// objects. This type takes in several /// objects. When is called /// on this class, it goes through it's list of objects /// and invokes on them in FIFO (first in, first out) /// order. When is called on this class, it goes through /// it's list of objects and invokes /// on them in LIFO (last in, first out) order. Note that /// is only called if the instance supports undo. /// public class CommandCollection : ICommand, ICollection { /// /// Initializes a new instance of the /// class that uses an for implementing it's /// collection. /// public CommandCollection() : this(new List()) { } /// /// Initializes a new instance of the class. /// /// The to use when /// storing objects. public CommandCollection(ICollection collection) { Collection = collection; } /// /// Calls on all of the /// instances contained within this in /// FIFO (first in, first out) order. /// public void Execute() { foreach (ICommand command in Collection) command.Execute(); } /// /// Calls on all of the /// instances contained within this in /// LIFO (last in, first out) order. Note that this method will skip /// s that do not support undo (i.e., /// is set to false). /// /// Thrown if any /// in this does not /// support undo (i.e., is false). public void Undo() { foreach (ICommand command in Collection.Where(comm => comm.CanUndo).Reverse()) command.Undo(); } /// /// Adds an item to the . /// /// The object to add to the /// . /// /// The is read-only. /// public void Add(ICommand item) { Collection.Add(item); } /// /// Removes all items from the . /// /// /// The is read-only. /// public void Clear() { Collection.Clear(); } /// /// Determines whether the contains a /// specific value. /// /// The object to locate in the /// . /// /// true if is found in the /// ; otherwise, false. /// public bool Contains(ICommand item) { return Collection.Contains(item); } /// /// Copies the elements of the to an /// , starting at a particular /// index. /// /// The one-dimensional that is /// the destination of the elements copied from . /// The must have zero-based indexing. /// The zero-based index in /// at which copying begins. /// is /// null. /// /// is less than 0. /// is /// multidimensional, is equal to or /// greater than the length of , or the number of /// elements in the source is greater than /// the available space from to the end of /// the destination . /// public void CopyTo(ICommand[] array, int arrayIndex) { Collection.CopyTo(array, arrayIndex); } /// /// Removes the first occurrence of a specific object from the /// . /// /// The object to remove from the /// . /// /// true if was successfully removed from the /// ; otherwise, false. This method also /// returns false if is not found in the original /// . /// /// The /// is read-only. public bool Remove(ICommand item) { return Collection.Remove(item); } /// /// Returns an enumerator that iterates through the collection. /// /// /// A that can be used to iterate through /// the collection. /// public IEnumerator GetEnumerator() { return Collection.GetEnumerator(); } /// /// Returns an enumerator that iterates through a collection. /// /// /// An object that can be used to iterate /// through the collection. /// IEnumerator IEnumerable.GetEnumerator() { return GetEnumerator(); } /// /// True if at least one of the instances within /// this can be reverted after a call to /// , false if otherwise. /// public bool CanUndo { get { return Collection.Any(comm => comm.CanUndo); } } /// /// Gets the number of elements contained in the . /// /// /// /// The number of elements contained in the . /// public int Count { get { return Collection.Count; } } /// /// Gets a value indicating whether the is /// read-only. /// /// /// true if the is read-only; /// otherwise, false. /// public bool IsReadOnly { get { return Collection.IsReadOnly; } } /// /// The collection of objects. /// ICollection Collection { get; set; } } }