/// <summary>
 /// Unmonitors the provided collidable.  The Collided function and OnCollision event will no longer be triggered when an actual collision may have occurred.  Disposing a monitored collidable will automatically be unmonitored.
 /// </summary>
 /// <param name="obj">Collidable to unmonitor.</param>
 public void Unmonitor(Collidable obj)
 {
     lock (_collidableRemoveLock)
     {
         _collidableRemovals.Enqueue(obj);
     }
 }
 /// <summary>
 /// Monitors the provided collidable and will trigger its Collided function and OnCollision event whenever a collision occurs with it and another Collidable.  If the provided collidable gets disposed it will automatically become unmonitored.
 /// </summary>
 /// <param name="obj">Collidable to monitor.</param>
 public void Monitor(Collidable obj)
 {
     lock (_collidableAddLock)
     {
         _enabled = true;
         _collidableAdditions.Enqueue(obj);
     }
 }
        public void CollisionManagerWorksWithinGame()
        {
            var rect = new Collidable(new BoundingRectangle(Vector2d.Zero, new Size2d(30, 50)));
            var circle = new Collidable(new BoundingCircle(Vector2d.Zero, 10));
            var game = new CollisionManagerGame();

            game.MonitorCollision(rect);
            game.MonitorCollision(circle);

            int rectCollisionTriggered = 0;
            int circleCollisionTriggered = 0;
            int managerCollisionTriggered = 0;

            rect.OnCollision += collisionData =>
            {
                Assert.Equal(circle, collisionData.With);
                rectCollisionTriggered++;
            };

            circle.OnCollision += collisionData =>
            {
                Assert.Equal(rect, collisionData.With);
                circleCollisionTriggered++;
            };

            game.RegisterCollisionEvent((first, second) =>
            {
                Assert.NotNull(first);
                Assert.NotNull(second);
                Assert.Equal(first, rect);
                Assert.Equal(second, circle);
                managerCollisionTriggered++;
            });

            Thread.Sleep(TimeSpan.FromSeconds(1));

            Assert.True(rectCollisionTriggered > 10);
            Assert.True(circleCollisionTriggered > 10);
            Assert.True(managerCollisionTriggered > 10);

            rect.Dispose();
            var savedRectCollisions = rectCollisionTriggered;
            var savedCircleCollisions = circleCollisionTriggered;
            var savedmanagerCollisions = managerCollisionTriggered;

            Thread.Sleep(TimeSpan.FromSeconds(1));

            Assert.Equal(savedRectCollisions, rectCollisionTriggered);
            Assert.Equal(savedCircleCollisions, circleCollisionTriggered);
            Assert.Equal(savedmanagerCollisions, managerCollisionTriggered);
        }
 public void MonitorCollision(Collidable obj)
 {
     CollisionManager.Monitor(obj);
 }
        public void CollisionManagerDetectsCollisions()
        {
            var cm = new CollisionManager();
            var rect = new Collidable(new BoundingRectangle(Vector2d.Zero, new Size2d(30, 50)));
            var circle = new Collidable(new BoundingCircle(Vector2d.Zero, 10));
            bool rectCollisionTriggered = false;
            bool circleCollisionTriggered = false;
            bool managerCollisionTriggered = false;

            cm.Monitor(rect);
            cm.Monitor(circle);

            rect.OnCollision += collisionData =>
            {
                Assert.Equal(circle, collisionData.With);
                rectCollisionTriggered = true;
            };

            circle.OnCollision += collisionData =>
            {
                Assert.Equal(rect, collisionData.With);
                circleCollisionTriggered = true;
            };

            cm.OnCollision += (first, second) =>
            {
                Assert.NotNull(first);
                Assert.NotNull(second);
                Assert.Equal(first, rect);
                Assert.Equal(second, circle);
                managerCollisionTriggered = true;
            };

            cm.Update(null);

            Assert.True(rectCollisionTriggered);
            Assert.True(circleCollisionTriggered);
            Assert.True(managerCollisionTriggered);

            rectCollisionTriggered = false;
            circleCollisionTriggered = false;
            managerCollisionTriggered = false;

            cm.Unmonitor(circle);
            cm.Update(null);

            Assert.False(rectCollisionTriggered);
            Assert.False(circleCollisionTriggered);
            Assert.False(managerCollisionTriggered);

            cm.Monitor(circle);
            cm.Update(null);

            Assert.True(rectCollisionTriggered);
            Assert.True(circleCollisionTriggered);
            Assert.True(managerCollisionTriggered);

            rectCollisionTriggered = false;
            circleCollisionTriggered = false;
            managerCollisionTriggered = false;

            circle.Dispose();

            cm.Update(null);

            Assert.False(rectCollisionTriggered);
            Assert.False(circleCollisionTriggered);
            Assert.False(managerCollisionTriggered);
        }
 /// <summary>
 /// Determines if the provided collidable is colliding with this Collidable.
 /// </summary>
 /// <param name="other">Collidable to check collision with.</param>
 /// <returns>Whether a collision is present.</returns>
 public bool IsCollidingWith(Collidable other)
 {
     return this.Bounds.Intersects(other.Bounds);
 }
 /// <summary>
 /// Creates a new instance of the CollisionData object.
 /// </summary>
 /// <param name="with">Initial value of the With component of CollisionData.</param>
 public CollisionData(Collidable with)
 {
     With = with;
 }