value type enumerator on IndexableSet

filter_relations
cosmonaut 2022-12-08 12:08:35 -08:00
parent 8d1274cba0
commit b6485f345b
1 changed files with 41 additions and 19 deletions

View File

@ -1,15 +1,15 @@
using System; using System;
using System.Collections;
using System.Collections.Generic; using System.Collections.Generic;
using System.Runtime.InteropServices; using System.Runtime.CompilerServices;
namespace MoonTools.ECS namespace MoonTools.ECS
{ {
internal class IndexableSet<T> : IEnumerable<T> where T : unmanaged internal class IndexableSet<T> where T : unmanaged
{ {
private Dictionary<T, int> indices; private Dictionary<T, int> indices;
private T[] array; private T[] array;
public int Count { get; private set; } public int Count { get; private set; }
public Enumerator GetEnumerator() => new Enumerator(this);
public IndexableSet(int size = 32) public IndexableSet(int size = 32)
{ {
@ -64,25 +64,47 @@ namespace MoonTools.ECS
return true; return true;
} }
public IEnumerator<T> GetEnumerator()
{
for (var i = Count - 1; i >= 0; i -= 1)
{
yield return array[i];
}
}
IEnumerator IEnumerable.GetEnumerator()
{
for (var i = Count - 1; i >= 0; i -= 1)
{
yield return array[i];
}
}
public void Clear() public void Clear()
{ {
Count = 0; Count = 0;
} }
public struct Enumerator
{
/// <summary>The set being enumerated.</summary>
private readonly IndexableSet<T> _set;
/// <summary>The next index to yield.</summary>
private int _index;
/// <summary>Initialize the enumerator.</summary>
/// <param name="set">The set to enumerate.</param>
[MethodImpl(MethodImplOptions.AggressiveInlining)]
internal Enumerator(IndexableSet<T> set)
{
_set = set;
_index = _set.Count;
}
/// <summary>Advances the enumerator to the next element of the span.</summary>
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public bool MoveNext()
{
int index = _index - 1;
if (index >= 0)
{
_index = index;
return true;
}
return false;
}
/// <summary>Gets the element at the current position of the enumerator.</summary>
public T Current
{
[MethodImpl(MethodImplOptions.AggressiveInlining)]
get => _set[_index];
}
}
} }
} }