diff --git a/src/IndexableSet.cs b/src/IndexableSet.cs index 35ca411..06be701 100644 --- a/src/IndexableSet.cs +++ b/src/IndexableSet.cs @@ -1,15 +1,15 @@ using System; -using System.Collections; using System.Collections.Generic; -using System.Runtime.InteropServices; +using System.Runtime.CompilerServices; namespace MoonTools.ECS { - internal class IndexableSet : IEnumerable where T : unmanaged + internal class IndexableSet where T : unmanaged { private Dictionary indices; private T[] array; public int Count { get; private set; } + public Enumerator GetEnumerator() => new Enumerator(this); public IndexableSet(int size = 32) { @@ -64,25 +64,47 @@ namespace MoonTools.ECS return true; } - public IEnumerator 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() { Count = 0; } + + public struct Enumerator + { + /// The set being enumerated. + private readonly IndexableSet _set; + /// The next index to yield. + private int _index; + + /// Initialize the enumerator. + /// The set to enumerate. + [MethodImpl(MethodImplOptions.AggressiveInlining)] + internal Enumerator(IndexableSet set) + { + _set = set; + _index = _set.Count; + } + + /// Advances the enumerator to the next element of the span. + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public bool MoveNext() + { + int index = _index - 1; + if (index >= 0) + { + _index = index; + return true; + } + + return false; + } + + /// Gets the element at the current position of the enumerator. + public T Current + { + [MethodImpl(MethodImplOptions.AggressiveInlining)] + get => _set[_index]; + } + } } }