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