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