public static IEnumerator OneTimeExplosionTest <T> (IExplosionExecutor ee, IPolygonSubtractor sub,
                                                        int numExplosions, float explosionRadius, bool hasHoles, float radius, int numEdges,
                                                        int columns, int rows) where T : DestructibleObject
    {
        // Set a constant seed so that we get the same results every time
        UnityEngine.Random.InitState(12345);

        new GameObject("Main Camera").AddComponent <Camera>().transform.position = new Vector3(0, 50, -100);

        // Meaure the time to create all destructible objects
        CreateRingsAndMeasure <T>(hasHoles, true, radius, numEdges, columns, rows);
        yield return(null);

        List <Explosion> explosions = new List <Explosion>();

        for (int i = 0; i < numExplosions; ++i)
        {
            explosions.Add(new Explosion(UnityEngine.Random.Range(-10, 10), UnityEngine.Random.Range(0, 20),
                                         explosionRadius, 24));
        }

        using (Measure.ProfilerMarkers(ProfilerMarkers.SampleGroupDefinitions)) {
            ProfilerMarkers.ProcessExplosions.Begin();
            ee.ExecuteExplosions(explosions, DestructibleObject.FindAll(), sub);
            ProfilerMarkers.ProcessExplosions.End();
        }
        yield return(null);

        // Wait to observe whether the result is correct
        yield return(WaitFrames(60));

        CleanUp();
    }
    public static IEnumerator ContinuousExplosionTest <T> (IExplosionExecutor ee, IPolygonSubtractor sub,
                                                           int numExplosions, float explosionRadius, float explosionInterval, bool hasHoles, float radius, int numEdges,
                                                           int columns, int rows, int warmupFrames, int captureFrames) where T : DestructibleObject
    {
        // Set a constant seed so that we get the same results every time
        UnityEngine.Random.InitState(12345);

        new GameObject("Main Camera").AddComponent <Camera>().transform.position = new Vector3(0, 50, -100);

        // Meaure the time to create all destructible objects
        CreateRingsAndMeasure <T>(hasHoles, true, radius, numEdges, columns, rows);

        // Set all objects to static
        var dObjs = DestructibleObject.FindAll();

        foreach (var dObj in dObjs)
        {
            dObj.GetComponent <Rigidbody2D>().bodyType = RigidbodyType2D.Static;
        }
        yield return(null);

        float explosionTimer = 0;

        // To be called every fixed update;
        // Generates a number of explosions every time the timer reaches a fixed interval.
        void explosionGenerator()
        {
            explosionTimer += Time.fixedDeltaTime;
            List <Explosion> explosions = new List <Explosion>();

            while (explosionTimer > explosionInterval)
            {
                explosionTimer -= explosionInterval;
                for (int i = 0; i < numExplosions; ++i)
                {
                    explosions.Add(new Explosion(UnityEngine.Random.Range(-10, 10), UnityEngine.Random.Range(0, 20),
                                                 explosionRadius, 24));
                }
            }

            ProfilerMarkers.ProcessExplosions.Begin();
            ee.ExecuteExplosions(explosions, DestructibleObject.FindAll(), sub);
            ProfilerMarkers.ProcessExplosions.End();
        }

        // Allow objects to collide before we measure physics
        yield return(WarmupFrames(warmupFrames, explosionGenerator));

        // Measure physics
        yield return(CaptureFrames(captureFrames, explosionGenerator));

        CleanUp();
    }
    void Update()
    {
        if (Input.GetMouseButtonDown(0))
        {
            Vector3 worldPoint = Camera.ScreenToWorldPoint(Input.mousePosition);

            List <Explosion> explosions = new List <Explosion> {
                new Explosion(worldPoint.x, worldPoint.y, 2.0f, 24),
            };

            IEnumerable <DestructibleObject> destructibleObjects = DestructibleObject.FindAll();

            var stopwatch = new System.Diagnostics.Stopwatch();
            stopwatch.Restart();

            AdvancedIterativeExplosionExecutor.Instance.ExecuteExplosions(explosions, destructibleObjects, ORourkeSubtractor.Instance);

            stopwatch.Stop();
            //stopwatch.LogTime("Execute Explosions");
        }
    }
    public static IEnumerator SimpleTest <T>(IExplosionExecutor ee, IPolygonSubtractor sub) where T : DestructibleObject
    {
        // Set a constant seed so that we get the same results every time
        UnityEngine.Random.InitState(12345);

        new GameObject("Main Camera").AddComponent <Camera>().transform.position = new Vector3(0, 50, -100);

        // Meaure the time to create all destructible objects
        T ring;

        using (Measure.ProfilerMarkers(ProfilerMarkers.SampleGroupDefinitions)) {
            ProfilerMarkers.Creation.Begin();
            ring = CreateRingObject <T>(true, 1, 4);
            ProfilerMarkers.Creation.End();

            ring.GetComponent <Rigidbody2D>().bodyType = RigidbodyType2D.Static;
        }
        yield return(null);

        ring.transform.position = new Vector2(0, 0);

        List <Explosion> explosions = new List <Explosion>()
        {
            new Explosion(-2, 0, 2, 4),
            new Explosion(2, 0, 2, 4),
        };

        using (Measure.ProfilerMarkers(ProfilerMarkers.SampleGroupDefinitions)) {
            ProfilerMarkers.ProcessExplosions.Begin();
            ee.ExecuteExplosions(explosions, DestructibleObject.FindAll(), sub);
            ProfilerMarkers.ProcessExplosions.End();
        }
        yield return(null);

        // Wait to observe whether the result is correct
        yield return(WaitFrames(60));

        CleanUp();
    }