summaryrefslogtreecommitdiff
path: root/Plugins/MonoGame.Extended/benchmarks/MonoGame.Extended.Benchmarks.Collisions/DifferentPoolSizeCollision.cs
blob: a4ac85880449d1690f863e20dca3a6fed5f86981 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
using BenchmarkDotNet.Attributes;
using BenchmarkDotNet.Engines;
using Microsoft.Xna.Framework;
using MonoGame.Extended.Collisions;
using MonoGame.Extended.Collisions.Layers;
using MonoGame.Extended.Collisions.QuadTree;

namespace MonoGame.Extended.Benchmarks.Collisions;

[SimpleJob(RunStrategy.ColdStart, launchCount:3)]
public class DifferentPoolSizeCollision
{
    private const int COMPONENT_BOUNDARY_SIZE = 1000;

    private readonly CollisionComponent _collisionComponent;
    private readonly Random _random = new Random();
    private readonly GameTime _gameTime = new GameTime(TimeSpan.Zero, TimeSpan.FromMilliseconds(16));

    public DifferentPoolSizeCollision()
    {
        var size = new Size2(COMPONENT_BOUNDARY_SIZE, COMPONENT_BOUNDARY_SIZE);
        _collisionComponent = new CollisionComponent(new RectangleF(Point2.Zero, size));
    }

    class Collider: ICollisionActor
    {
        public Collider(Point2 position)
        {
            Bounds = new RectangleF(position, new Size2(1, 1));
        }

        public IShapeF Bounds { get; set; }
        public Vector2 Shift { get; set; }

        public Point2 Position {
            get => Bounds.Position;
            set => Bounds.Position = value;
        }

        public void OnCollision(CollisionEventArgs collisionInfo)
        {
        }
    }

    [Params(100, 500, 1000)]
    public int N { get; set; }


    [Params(1, 2)]
    public int LayersCount { get; set; }

    public int UpdateCount { get; set; } = 100;


    private List<Collider> _colliders = new();
    private List<Layer> _layers = new();

    [GlobalSetup]
    public void GlobalSetup()
    {
        if (LayersCount > 1)
        {
            for (int i = 0; i < LayersCount; i++)
            {
                var size = new Size2(COMPONENT_BOUNDARY_SIZE, COMPONENT_BOUNDARY_SIZE);
                var layer = new Layer(new SpatialHash(new Size2(5, 5)));//new QuadTreeSpace(new RectangleF(Point2.Zero, size)))));
                _collisionComponent.Add(i.ToString(), layer);
                _layers.Add(layer);
            }
            for (int i = 0; i < LayersCount - 1; i++)
                _collisionComponent.AddCollisionBetweenLayer(_layers[i], _layers[i + 1]);

        }

        for (int i = 0; i < N; i++)
        {
            var layer = LayersCount == 1
                ? _collisionComponent.Layers.First().Value
                : _layers[i % LayersCount];

            var collider = new Collider(new Point2(
                _random.Next(COMPONENT_BOUNDARY_SIZE),
                _random.Next(COMPONENT_BOUNDARY_SIZE)))
            {
                Shift = new Vector2(
                    _random.Next(4) - 2,
                    _random.Next(4) - 2),
            };
            _colliders.Add(collider);
            layer.Space.Insert(collider);
        }
    }

    [GlobalCleanup]
    public void GlobalCleanup()
    {
        foreach (var collider in _colliders)
            _collisionComponent.Remove(collider);
        _colliders.Clear();
        foreach (var layer in _layers)
            _collisionComponent.Remove(layer: layer);
        _layers.Clear();
    }

    [Benchmark]
    public void Benchmark()
    {
        for (int i = 0; i < UpdateCount; i++)
        {
            foreach (var collider in _colliders)
                collider.Position += collider.Shift;
            //_collisionComponent.Update(_gameTime);
        }
    }
}