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