using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using Chernobyl.Mathematics.Geometry;
namespace Chernobyl.Mathematics.Collision
{
///
/// An
/// that holds
///
/// instances. This class acts like a composite; for example, calling
/// returns the
/// instances from the contained
///
/// that were collided against.
///
/// The type of
/// being held
/// within this .
/// This ICollidable type must derive from .
/// The type that will
/// be passed in to check for collisions against the
/// instances contained within
/// this .
public class CollidableEnumerableComposite
: ShapeCollection, ICollidableEnumerable
where TContainedCollidable : IExtendedCollidable
{
///
/// Initializes a new instance of the
///
/// class.
///
/// The
///
/// this list is composed of.
public CollidableEnumerableComposite(IEnumerable> collidables)
: base(collidables.Cast().ToList())
{
Collidables = collidables;
}
///
/// Returns an that can be iterated
/// over to collect the objects that are colliding with the passed in
/// . Note this method should never
/// pre-compute the collisions. It should return an
/// that returns an
/// that checks for collisions as it
/// iterates.
///
/// The to check
/// against for collisions.
///
/// The that can be iterated over
/// to get the s that are being collided
/// against.
///
public IEnumerable GetCollidables(TCollider collidable)
{
return Collidables.SelectMany(collidables => collidables.GetCollidables(collidable));
}
///
/// Returns an enumerator that iterates through the collection.
///
/// A that can be used to iterate
/// through the collection.
public new IEnumerator GetEnumerator()
{
return Collidables.SelectMany(containedCollidables => containedCollidables).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();
}
///
/// Tests for a collision between all of the and the
///
/// instances contained within this instance and the
/// passed in.
///
/// The to
/// test for collision against.
///
/// True if there was a collision with any of the contained
///
/// instances, false if otherwise.
///
public bool IsColliding(TCollider collidable)
{
return Collidables.Any(collidableEnumerables => collidableEnumerables.IsColliding(collidable));
}
///
/// An event that is raised when a has
/// started colliding with this . When the
/// collision has ended, will be invoked.
///
public event EventHandler OnCollisionStarted;
///
/// An event that is raised when the collision with a
/// has ended. This will event will be raised
/// after the invocation of .
///
public event EventHandler OnCollisionEnded;
///
/// Called when this has started colliding
/// with another .
///
/// The object that was just hit.
public void HandleCollisionStarted(ICollidable collider)
{
if (OnCollisionStarted != null)
OnCollisionStarted(this, EventArgs.Empty);
}
///
/// Called when this has stopped colliding
/// with another .
///
/// The object that was just hit.
public void HandleCollisionEnded(ICollidable collider)
{
if (OnCollisionEnded != null)
OnCollisionEnded(this, EventArgs.Empty);
}
///
/// The
/// this list is composed of.
///
public IEnumerable> Collidables { get; private set; }
}
}