Net.Like.Xue.Tokyo/Assets/BITKit/Core/kcp2k/kcp/Pool.cs

47 lines
1.5 KiB
C#
Raw Normal View History

2024-11-03 16:42:23 +08:00
// Pool to avoid allocations (from libuv2k & Mirror)
using System;
using System.Collections.Generic;
namespace kcp2k
{
public class Pool<T>
{
// Mirror is single threaded, no need for concurrent collections
2025-04-17 19:36:08 +08:00
private readonly Stack<T> _objects = new Stack<T>();
2024-11-03 16:42:23 +08:00
// some types might need additional parameters in their constructor, so
// we use a Func<T> generator
2025-04-17 19:36:08 +08:00
private readonly Func<T> _objectGenerator;
2024-11-03 16:42:23 +08:00
// some types might need additional cleanup for returned objects
2025-04-17 19:36:08 +08:00
private readonly Action<T> _objectResetter;
2024-11-03 16:42:23 +08:00
public Pool(Func<T> objectGenerator, Action<T> objectResetter, int initialCapacity)
{
2025-04-17 19:36:08 +08:00
_objectGenerator = objectGenerator;
_objectResetter = objectResetter;
2024-11-03 16:42:23 +08:00
// allocate an initial pool so we have fewer (if any)
// allocations in the first few frames (or seconds).
2025-04-17 19:36:08 +08:00
for (var i = 0; i < initialCapacity; ++i)
_objects.Push(objectGenerator());
2024-11-03 16:42:23 +08:00
}
// take an element from the pool, or create a new one if empty
2025-04-17 19:36:08 +08:00
public T Take() => _objects.Count > 0 ? _objects.Pop() : _objectGenerator();
2024-11-03 16:42:23 +08:00
// return an element to the pool
public void Return(T item)
{
2025-04-17 19:36:08 +08:00
_objectResetter?.Invoke(item);
_objects.Push(item);
2024-11-03 16:42:23 +08:00
}
// clear the pool
2025-04-17 19:36:08 +08:00
public void Clear() => _objects.Clear();
2024-11-03 16:42:23 +08:00
// count to see how many objects are in the pool. useful for tests.
2025-04-17 19:36:08 +08:00
public int Count => _objects.Count;
2024-11-03 16:42:23 +08:00
}
}