Skip to content

Instantly share code, notes, and snippets.

@AnsisMalins
Last active May 19, 2019 11:12
Show Gist options
  • Save AnsisMalins/f16bff2552881cc3af1dc05d3610e226 to your computer and use it in GitHub Desktop.
Save AnsisMalins/f16bff2552881cc3af1dc05d3610e226 to your computer and use it in GitHub Desktop.
Array Pool
public static class ArrayPool<T>
{
private static readonly List<T[]> pool = new List<T[]>();
public static Item Get(int length)
{
for (int i = pool.Count - 1; i >= 0; i--)
{
var array = pool[i];
if (array.Length >= length)
{
pool.RemoveAtSwap(i);
return new Item(array, length);
}
}
return new Item(new T[length], length);
}
public struct Item : IDisposable
{
public T[] Array { get; private set; }
public int Length { get; private set; }
internal Item(T[] array, int length)
{
Array = array;
Length = length;
}
public ref T this[int index]
{
get { return ref Array[index]; }
}
public static implicit operator T[] (Item item)
{
return item.Array;
}
void IDisposable.Dispose()
{
if (Array != null)
{
// Only clear the portion of the array we used.
System.Array.Clear(Array, 0, Length);
pool.Add(Array);
Array = null;
}
}
}
}
public static class Extensions
{
/// <summary>Removes an item quickly by using the swap trick. The order of items in the List is not
/// preserved.</summary>
public static void RemoveAtSwap<T>(this List<T> list, int index)
{
var indexOfLastItem = list.Count - 1;
if (index < indexOfLastItem)
list[index] = list[indexOfLastItem];
list.RemoveAt(indexOfLastItem);
}
}
@AnsisMalins
Copy link
Author

Usage:

public static RaycastHit RaycastTerrain(Vector3 origin, Vector3 direction)
{
    using (var hits = ArrayPool<RaycastHit>.Get(64))
    {
        int hitCount = Physics.RaycastNonAlloc(origin, direction, hits, float.PositiveInfinity,
            1 << Layer.Default);

        if (hitCount == hits.Length)
            Debug.LogWarning($"RaycastNonAlloc used up all {hits.Length} array items");

        for (int i = 0; i < hitCount; i++)
            if (hits[i].collider is TerrainCollider)
                return hits[i];
    }

    return new RaycastHit();
}

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment