using System; using System.Collections.Generic; using System.Linq; namespace Chernobyl.Update { /// /// A default implementation of IUpdateable. Can also /// be used as a helper class for implementing new /// IUpdateables. Do NOT handle the type Updateable /// because not all updateables derive from Updateable. /// Instead, handle the type IUpdateable. /// public class Updateable : IUpdateable { /// /// Constructor that creates a Updateable and creates a /// to hold the children. /// public Updateable() : this(new List()) { } /// /// Constructor. /// /// The list that should be used to /// hold children, like . public Updateable(ICollection childCollection) { UpdateableChildren = childCollection; } /// /// By default, this method just loops through it's children /// and calls on them, passing in /// the delta time it receives. /// /// The amount of time that has /// passed since this update was last called. public virtual void Update(TimeSpan deltaTime) { // We place the children in an array so that, if new children are // added to the UpdateableChildren during this update, we won't get // and invalidated enumerator. foreach (IUpdateable child in UpdateableChildren.ToArray()) child.Update(deltaTime); } /// /// A helper method that makes one IUpdateable the parent of another. /// /// The IUpdateable to make the parent of the child. /// The IUpdateable to make the child of the parent. /// If this child is already parented, the child will be un-parented with /// that parent and assigned the new . public static void MakeParentChild(IUpdateable parent, IUpdateable child) { // make sure the child isn't already a child of the parent if (parent.UpdateableChildren.Contains(child) == false) { parent.UpdateableChildren.Add(child); // if the child already has a parent, remove the child from that parent if (child.UpdateableParent != null) child.UpdateableParent.UpdateableChildren.Remove(child); child.UpdateableParent = parent; } } /// /// A helper method that splits apart a parent/child relationship of two /// IUpdateables. The child's parent is first checked to make sure it is /// the parent passed in. If it is, then the child's parent property is /// set to null. If not, the parent property on the child is left alone. /// /// The parent to separate from the child. /// The child to separate from the parent. public static void SeparateParentChild(IUpdateable parent, IUpdateable child) { // ensure these two are actually parented before seperating them if (child.UpdateableParent == parent) { parent.UpdateableChildren.Remove(child); child.UpdateableParent = null; } } /// /// Shallow copies the data from the /// to the /// . /// /// The to copy the /// data to. /// The to copy the data /// from. public static void ShallowCopy(IUpdateable destination, IUpdateable source) { destination.UpdateableParent = source.UpdateableParent; foreach (IUpdateable updateableChild in source.UpdateableChildren) MakeParentChild(destination, updateableChild); } /// /// The parent of this IUpdateable or null if this IUpdateable does not /// have a parent. /// public IUpdateable UpdateableParent { get; set; } /// /// Holds a collection of children that should be updated /// when this updateable decides they should be updated. /// public ICollection UpdateableChildren { get; private set; } } }