From 316735cf9a5452b7a58a2172dcb6fcead70cbcab Mon Sep 17 00:00:00 2001 From: Mikhail <99481254+DCFApixels@users.noreply.github.com> Date: Sun, 11 Feb 2024 01:14:54 +0800 Subject: [PATCH] move EcsAspectIterator to EcsAspect.Iterator --- src/EcsAspect.cs | 453 +++++++++++++++++++++++------------------------ 1 file changed, 226 insertions(+), 227 deletions(-) diff --git a/src/EcsAspect.cs b/src/EcsAspect.cs index 08eb851..3515fd5 100644 --- a/src/EcsAspect.cs +++ b/src/EcsAspect.cs @@ -1,5 +1,4 @@ using DCFApixels.DragonECS.Internal; -using DCFApixels.DragonECS.Utils; using System; using System.Collections.Generic; using System.Reflection; @@ -13,10 +12,10 @@ namespace DCFApixels.DragonECS internal EcsMask _mask; private bool _isInit; - internal UnsafeArray _sortIncBuffer; - internal UnsafeArray _sortExcBuffer; - internal UnsafeArray _sortIncChunckBuffer; - internal UnsafeArray _sortExcChunckBuffer; + private UnsafeArray _sortIncBuffer; + private UnsafeArray _sortExcBuffer; + private UnsafeArray _sortIncChunckBuffer; + private UnsafeArray _sortExcChunckBuffer; #region Properties public EcsMask Mask => _mask; @@ -150,13 +149,13 @@ namespace DCFApixels.DragonECS #endregion #region Iterator - public EcsAspectIterator GetIterator() + public Iterator GetIterator() { - return new EcsAspectIterator(this, _source.Entities); + return new Iterator(this, _source.Entities); } - public EcsAspectIterator GetIteratorFor(EcsSpan span) + public Iterator GetIteratorFor(EcsSpan span) { - return new EcsAspectIterator(this, span); + return new Iterator(this, span); } #endregion @@ -172,6 +171,224 @@ namespace DCFApixels.DragonECS } } #endregion + + #region Iterator + public ref struct Iterator + { + public readonly int worldID; + public readonly EcsAspect aspect; + private EcsSpan _span; + + public Iterator(EcsAspect aspect, EcsSpan span) + { + worldID = aspect.World.id; + _span = span; + this.aspect = aspect; + } + public void CopyTo(EcsGroup group) + { + group.Clear(); + var enumerator = GetEnumerator(); + while (enumerator.MoveNext()) + group.AddInternal(enumerator.Current); + } + public int CopyTo(ref int[] array) + { + var enumerator = GetEnumerator(); + int count = 0; + while (enumerator.MoveNext()) + { + if (array.Length <= count) + Array.Resize(ref array, array.Length << 1); + array[count++] = enumerator.Current; + } + return count; + } + public EcsSpan CopyToSpan(ref int[] array) + { + var enumerator = GetEnumerator(); + int count = 0; + while (enumerator.MoveNext()) + { + if (array.Length <= count) + Array.Resize(ref array, array.Length << 1); + array[count++] = enumerator.Current; + } + return new EcsSpan(worldID, array, count); + } + + #region object + public override string ToString() + { + List ints = new List(); + foreach (var e in this) + { + ints.Add(e); + } + return CollectionUtility.EntitiesToString(ints, "it"); + } + #endregion + + #region Enumerator + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public Enumerator GetEnumerator() => new Enumerator(_span, aspect); + + public unsafe ref struct Enumerator + { + #region CountComparers + private readonly struct IncCountComparer : IComparerX + { + public readonly int[] counts; + public IncCountComparer(int[] counts) + { + this.counts = counts; + } + public int Compare(int a, int b) + { + return counts[a] - counts[b]; + } + } + private readonly struct ExcCountComparer : IComparerX + { + public readonly int[] counts; + public ExcCountComparer(int[] counts) + { + this.counts = counts; + } + public int Compare(int a, int b) + { + return counts[b] - counts[a]; + } + } + #endregion + + private ReadOnlySpan.Enumerator _span; + private readonly int[][] _entitiesComponentMasks; + + private static EcsMaskChunck* _preSortedIncBuffer; + private static EcsMaskChunck* _preSortedExcBuffer; + + private UnsafeArray _sortIncChunckBuffer; + private UnsafeArray _sortExcChunckBuffer; + + //private EcsAspect aspect; + + public unsafe Enumerator(EcsSpan span, EcsAspect aspect) + { + //this.aspect = aspect; + _span = span.GetEnumerator(); + _entitiesComponentMasks = aspect.World._entitiesComponentMasks; + _sortIncChunckBuffer = aspect._sortIncChunckBuffer; + _sortExcChunckBuffer = aspect._sortExcChunckBuffer; + + #region Sort + UnsafeArray _sortIncBuffer = aspect._sortIncBuffer; + UnsafeArray _sortExcBuffer = aspect._sortExcBuffer; + int[] counts = aspect.World._poolComponentCounts; + + if (_preSortedIncBuffer == null) + { + _preSortedIncBuffer = UnmanagedArrayUtility.New(256); + _preSortedExcBuffer = UnmanagedArrayUtility.New(256); + } + + if (_sortIncChunckBuffer.Length > 1) + { + IncCountComparer incComparer = new IncCountComparer(counts); + UnsafeArraySortHalperX.InsertionSort(_sortIncBuffer.ptr, _sortIncBuffer.Length, ref incComparer); + for (int i = 0; i < _sortIncBuffer.Length; i++) + { + _preSortedIncBuffer[i] = EcsMaskChunck.FromID(_sortIncBuffer.ptr[i]); + } + for (int i = 0, ii = 0; ii < _sortIncChunckBuffer.Length; ii++) + { + EcsMaskChunck bas = _preSortedIncBuffer[i]; + int chankIndexX = bas.chankIndex; + int maskX = bas.mask; + + for (int j = i + 1; j < _sortIncBuffer.Length; j++) + { + if (_preSortedIncBuffer[j].chankIndex == chankIndexX) + { + maskX |= _preSortedIncBuffer[j].mask; + } + } + _sortIncChunckBuffer.ptr[ii] = new EcsMaskChunck(chankIndexX, maskX); + while (++i < _sortIncBuffer.Length && _preSortedIncBuffer[i].chankIndex == chankIndexX) + { + // skip + } + } + } + + if (_sortExcChunckBuffer.Length > 1) + { + ExcCountComparer excComparer = new ExcCountComparer(counts); + UnsafeArraySortHalperX.InsertionSort(_sortExcBuffer.ptr, _sortExcBuffer.Length, ref excComparer); + for (int i = 0; i < _sortExcBuffer.Length; i++) + { + _preSortedExcBuffer[i] = EcsMaskChunck.FromID(_sortExcBuffer.ptr[i]); + } + + for (int i = 0, ii = 0; ii < _sortExcChunckBuffer.Length; ii++) + { + EcsMaskChunck bas = _preSortedExcBuffer[i]; + int chankIndexX = bas.chankIndex; + int maskX = bas.mask; + + for (int j = i + 1; j < _sortExcBuffer.Length; j++) + { + if (_preSortedExcBuffer[j].chankIndex == chankIndexX) + { + maskX |= _preSortedExcBuffer[j].mask; + } + } + _sortExcChunckBuffer.ptr[ii] = new EcsMaskChunck(chankIndexX, maskX); + while (++i < _sortExcBuffer.Length && _preSortedExcBuffer[i].chankIndex == chankIndexX) + { + // skip + } + } + } + #endregion + } + public int Current + { + [MethodImpl(MethodImplOptions.AggressiveInlining)] + get => _span.Current; + } + //public entlong CurrentLong + //{ + // [MethodImpl(MethodImplOptions.AggressiveInlining)] + // get => aspect.World.GetEntityLong(_span.Current); + //} + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public bool MoveNext() + { + while (_span.MoveNext()) + { + int e = _span.Current; + for (int i = 0; i < _sortIncChunckBuffer.Length; i++) + { + var bit = _sortIncChunckBuffer.ptr[i]; + if ((_entitiesComponentMasks[e][bit.chankIndex] & bit.mask) != bit.mask) + goto skip; + } + for (int i = 0; i < _sortExcChunckBuffer.Length; i++) + { + var bit = _sortExcChunckBuffer.ptr[i]; + if ((_entitiesComponentMasks[e][bit.chankIndex] & bit.mask) > 0) + goto skip; + } + return true; + skip: continue; + } + return false; + } + } + #endregion + } + #endregion } #region BuilderBase @@ -182,222 +399,4 @@ namespace DCFApixels.DragonECS public abstract TPool Optional() where TPool : IEcsPoolImplementation, new(); } #endregion - - #region Iterator - public ref struct EcsAspectIterator - { - public readonly int worldID; - public readonly EcsAspect aspect; - private EcsSpan _span; - - public EcsAspectIterator(EcsAspect aspect, EcsSpan span) - { - worldID = aspect.World.id; - _span = span; - this.aspect = aspect; - } - public void CopyTo(EcsGroup group) - { - group.Clear(); - var enumerator = GetEnumerator(); - while (enumerator.MoveNext()) - group.AddInternal(enumerator.Current); - } - public int CopyTo(ref int[] array) - { - var enumerator = GetEnumerator(); - int count = 0; - while (enumerator.MoveNext()) - { - if (array.Length <= count) - Array.Resize(ref array, array.Length << 1); - array[count++] = enumerator.Current; - } - return count; - } - public EcsSpan CopyToSpan(ref int[] array) - { - var enumerator = GetEnumerator(); - int count = 0; - while (enumerator.MoveNext()) - { - if (array.Length <= count) - Array.Resize(ref array, array.Length << 1); - array[count++] = enumerator.Current; - } - return new EcsSpan(worldID, array, count); - } - - #region object - public override string ToString() - { - List ints = new List(); - foreach (var e in this) - { - ints.Add(e); - } - return CollectionUtility.EntitiesToString(ints, "it"); - } - #endregion - - #region Enumerator - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public Enumerator GetEnumerator() => new Enumerator(_span, aspect); - - public unsafe ref struct Enumerator - { - #region CountComparers - private readonly struct IncCountComparer : IComparerX - { - public readonly int[] counts; - public IncCountComparer(int[] counts) - { - this.counts = counts; - } - public int Compare(int a, int b) - { - return counts[a] - counts[b]; - } - } - private readonly struct ExcCountComparer : IComparerX - { - public readonly int[] counts; - public ExcCountComparer(int[] counts) - { - this.counts = counts; - } - public int Compare(int a, int b) - { - return counts[b] - counts[a]; - } - } - #endregion - - private ReadOnlySpan.Enumerator _span; - private readonly int[][] _entitiesComponentMasks; - - private static EcsMaskChunck* _preSortedIncBuffer; - private static EcsMaskChunck* _preSortedExcBuffer; - - private UnsafeArray _sortIncChunckBuffer; - private UnsafeArray _sortExcChunckBuffer; - - //private EcsAspect aspect; - - public unsafe Enumerator(EcsSpan span, EcsAspect aspect) - { - //this.aspect = aspect; - _span = span.GetEnumerator(); - _entitiesComponentMasks = aspect.World._entitiesComponentMasks; - _sortIncChunckBuffer = aspect._sortIncChunckBuffer; - _sortExcChunckBuffer = aspect._sortExcChunckBuffer; - - #region Sort - UnsafeArray _sortIncBuffer = aspect._sortIncBuffer; - UnsafeArray _sortExcBuffer = aspect._sortExcBuffer; - int[] counts = aspect.World._poolComponentCounts; - - if (_preSortedIncBuffer == null) - { - _preSortedIncBuffer = UnmanagedArrayUtility.New(256); - _preSortedExcBuffer = UnmanagedArrayUtility.New(256); - } - - if (_sortIncChunckBuffer.Length > 1) - { - IncCountComparer incComparer = new IncCountComparer(counts); - UnsafeArraySortHalperX.InsertionSort(_sortIncBuffer.ptr, _sortIncBuffer.Length, ref incComparer); - for (int i = 0; i < _sortIncBuffer.Length; i++) - { - _preSortedIncBuffer[i] = EcsMaskChunck.FromID(_sortIncBuffer.ptr[i]); - } - for (int i = 0, ii = 0; ii < _sortIncChunckBuffer.Length; ii++) - { - EcsMaskChunck bas = _preSortedIncBuffer[i]; - int chankIndexX = bas.chankIndex; - int maskX = bas.mask; - - for (int j = i + 1; j < _sortIncBuffer.Length; j++) - { - if (_preSortedIncBuffer[j].chankIndex == chankIndexX) - { - maskX |= _preSortedIncBuffer[j].mask; - } - } - _sortIncChunckBuffer.ptr[ii] = new EcsMaskChunck(chankIndexX, maskX); - while (++i < _sortIncBuffer.Length && _preSortedIncBuffer[i].chankIndex == chankIndexX) - { - // skip - } - } - } - - if (_sortExcChunckBuffer.Length > 1) - { - ExcCountComparer excComparer = new ExcCountComparer(counts); - UnsafeArraySortHalperX.InsertionSort(_sortExcBuffer.ptr, _sortExcBuffer.Length, ref excComparer); - for (int i = 0; i < _sortExcBuffer.Length; i++) - { - _preSortedExcBuffer[i] = EcsMaskChunck.FromID(_sortExcBuffer.ptr[i]); - } - - for (int i = 0, ii = 0; ii < _sortExcChunckBuffer.Length; ii++) - { - EcsMaskChunck bas = _preSortedExcBuffer[i]; - int chankIndexX = bas.chankIndex; - int maskX = bas.mask; - - for (int j = i + 1; j < _sortExcBuffer.Length; j++) - { - if (_preSortedExcBuffer[j].chankIndex == chankIndexX) - { - maskX |= _preSortedExcBuffer[j].mask; - } - } - _sortExcChunckBuffer.ptr[ii] = new EcsMaskChunck(chankIndexX, maskX); - while (++i < _sortExcBuffer.Length && _preSortedExcBuffer[i].chankIndex == chankIndexX) - { - // skip - } - } - } - #endregion - } - public int Current - { - [MethodImpl(MethodImplOptions.AggressiveInlining)] - get => _span.Current; - } - //public entlong CurrentLong - //{ - // [MethodImpl(MethodImplOptions.AggressiveInlining)] - // get => aspect.World.GetEntityLong(_span.Current); - //} - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public bool MoveNext() - { - while (_span.MoveNext()) - { - int e = _span.Current; - for (int i = 0; i < _sortIncChunckBuffer.Length; i++) - { - var bit = _sortIncChunckBuffer.ptr[i]; - if ((_entitiesComponentMasks[e][bit.chankIndex] & bit.mask) != bit.mask) - goto skip; - } - for (int i = 0; i < _sortExcChunckBuffer.Length; i++) - { - var bit = _sortExcChunckBuffer.ptr[i]; - if ((_entitiesComponentMasks[e][bit.chankIndex] & bit.mask) > 0) - goto skip; - } - return true; - skip: continue; - } - return false; - } - } - #endregion - } - #endregion }