From 152b0e93dbc4cac2e286d92b28817e5bbfc98be9 Mon Sep 17 00:00:00 2001 From: Syntriax Date: Mon, 9 Jun 2025 18:28:54 +0300 Subject: [PATCH] feat: added list pools --- Engine.Core/Helpers/ListPool.cs | 40 +++++++++++++++++++++++++++ Engine.Physics2D/PhysicsEngine2D.cs | 22 +++++++++++---- Engine.Physics2D/RaycastResolver2D.cs | 4 +-- 3 files changed, 58 insertions(+), 8 deletions(-) create mode 100644 Engine.Core/Helpers/ListPool.cs diff --git a/Engine.Core/Helpers/ListPool.cs b/Engine.Core/Helpers/ListPool.cs new file mode 100644 index 0000000..19884e6 --- /dev/null +++ b/Engine.Core/Helpers/ListPool.cs @@ -0,0 +1,40 @@ +using System; +using System.Collections.Generic; + +namespace Syntriax.Engine.Core; + +public class ListPool : IPool> +{ + public Event>, List> OnReturned { get; } = new(); + public Event>, List> OnRemoved { get; } = new(); + + private readonly Func> generator = null!; + private readonly Queue> queue = new(); + + public List Get() + { + if (!queue.TryDequeue(out List? result)) + result = generator(); + + result.Clear(); + OnRemoved?.Invoke(this, result); + return result; + } + + public void Return(List list) + { + if (queue.Contains(list)) + return; + + list.Clear(); + queue.Enqueue(list); + OnReturned?.Invoke(this, list); + } + + public ListPool(Func> generator, int initialCapacity = 1) + { + this.generator = generator; + for (int i = 0; i < initialCapacity; i++) + queue.Enqueue(generator()); + } +} diff --git a/Engine.Physics2D/PhysicsEngine2D.cs b/Engine.Physics2D/PhysicsEngine2D.cs index a39b8e1..4e84b5b 100644 --- a/Engine.Physics2D/PhysicsEngine2D.cs +++ b/Engine.Physics2D/PhysicsEngine2D.cs @@ -25,6 +25,12 @@ public class PhysicsEngine2D : Behaviour, IPreUpdate, IPhysicsEngine2D protected BehaviourCollector rigidBodyCollector = new(); protected BehaviourCollector colliderCollector = new(); + private readonly ListPool colliderPool = new(() => new(32)); + private readonly ListPool prePhysicsUpdatePool = new(() => new(32)); + private readonly ListPool physicsUpdatePool = new(() => new(32)); + private readonly ListPool physicsIterationPool = new(() => new(32)); + private readonly ListPool postPhysicsUpdatePool = new(() => new(32)); + public int IterationPerStep { get => _iterationPerStep; set => _iterationPerStep = value < 1 ? 1 : value; } public float IterationPeriod { get => _iterationPeriod; set => _iterationPeriod = value.Max(0.0001f); } @@ -111,11 +117,11 @@ public class PhysicsEngine2D : Behaviour, IPreUpdate, IPhysicsEngine2D { float intervalDeltaTime = deltaTime / IterationPerStep; - List childColliders = []; - List physicsPreUpdates = []; - List physicsUpdates = []; - List physicsIterations = []; - List physicsPostUpdates = []; + List childColliders = colliderPool.Get(); + List physicsPreUpdates = prePhysicsUpdatePool.Get(); + List physicsUpdates = physicsUpdatePool.Get(); + List physicsIterations = physicsIterationPool.Get(); + List physicsPostUpdates = postPhysicsUpdatePool.Get(); rigidBody.BehaviourController.GetBehavioursInChildren(childColliders); rigidBody.BehaviourController.GetBehavioursInChildren(physicsPreUpdates); @@ -159,6 +165,12 @@ public class PhysicsEngine2D : Behaviour, IPreUpdate, IPhysicsEngine2D for (int i = physicsPostUpdates.Count - 1; i >= 0; i--) physicsPostUpdates[i].PostPhysicsUpdate(deltaTime); + + colliderPool.Return(childColliders); + prePhysicsUpdatePool.Return(physicsPreUpdates); + physicsUpdatePool.Return(physicsUpdates); + physicsIterationPool.Return(physicsIterations); + postPhysicsUpdatePool.Return(physicsPostUpdates); } private void ResolveColliders(ICollider2D colliderX, ICollider2D colliderY) diff --git a/Engine.Physics2D/RaycastResolver2D.cs b/Engine.Physics2D/RaycastResolver2D.cs index c04dd78..881e4ad 100644 --- a/Engine.Physics2D/RaycastResolver2D.cs +++ b/Engine.Physics2D/RaycastResolver2D.cs @@ -6,7 +6,7 @@ namespace Syntriax.Engine.Physics2D; public class RaycastResolver2D : IRaycastResolver2D { - private readonly Pool> lineCacheQueue = new(() => new List(4)); + private readonly ListPool lineCacheQueue = new(() => new(4)); RaycastResult? IRaycastResolver2D.RaycastAgainst(T shape, Ray2D ray, float length) { @@ -21,7 +21,6 @@ public class RaycastResolver2D : IRaycastResolver2D public RaycastResult? RaycastAgainstShape(IShapeCollider2D shapeCollider, Ray2D ray, float length) { List line2Ds = lineCacheQueue.Get(); - line2Ds.Clear(); RaycastResult? raycastResult = null; float closestRaycastResultSquared = float.MaxValue; @@ -60,7 +59,6 @@ public class RaycastResolver2D : IRaycastResolver2D } } - line2Ds.Clear(); lineCacheQueue.Return(line2Ds); return raycastResult;