diff --git a/src/DataInterfaces.cs b/src/DataInterfaces.cs index f64125c..ef4ef76 100644 --- a/src/DataInterfaces.cs +++ b/src/DataInterfaces.cs @@ -37,7 +37,7 @@ namespace DCFApixels.DragonECS internal class WorldComponentHandler : IEcsWorldComponent where T : IEcsWorldComponent { - private T _fakeInstnace; + private T _fakeInstnace = default; [MethodImpl(MethodImplOptions.AggressiveInlining)] public void Init(ref T component, EcsWorld world) => _fakeInstnace.Init(ref component, world); public void OnDestroy(ref T component, EcsWorld world) => _fakeInstnace.OnDestroy(ref component, world); @@ -112,7 +112,7 @@ namespace DCFApixels.DragonECS internal sealed class ComponentCopyHandler : IEcsComponentCopy where T : IEcsComponentCopy { - private T _fakeInstnace; + private T _fakeInstnace = default; [MethodImpl(MethodImplOptions.AggressiveInlining)] public void Copy(ref T from, ref T to) => _fakeInstnace.Copy(ref from, ref to); } diff --git a/src/EcsAspect.cs b/src/EcsAspect.cs index cbcbb0c..17c6369 100644 --- a/src/EcsAspect.cs +++ b/src/EcsAspect.cs @@ -251,6 +251,7 @@ namespace DCFApixels.DragonECS public unsafe ref struct Enumerator { + #region CountComparers private readonly struct IncCountComparer : IComparerX { public readonly int[] counts; @@ -275,6 +276,8 @@ namespace DCFApixels.DragonECS return counts[b] - counts[a]; } } + #endregion + private ReadOnlySpan.Enumerator _span; private readonly int[][] _entitiesComponentMasks; @@ -284,110 +287,20 @@ namespace DCFApixels.DragonECS private UnsafeArray _sortIncChunckBuffer; private UnsafeArray _sortExcChunckBuffer; - private EcsAspect aspect; + //private EcsAspect aspect; public unsafe Enumerator(EcsSpan span, EcsAspect aspect) { - this.aspect = aspect; + //this.aspect = aspect; _span = span.GetEnumerator(); - _entitiesComponentMasks = span.World._entitiesComponentMasks; - - EcsMask mask = aspect.Mask; - - UnsafeArray _sortIncBuffer = aspect._sortIncBuffer; - UnsafeArray _sortExcBuffer = aspect._sortExcBuffer; + _entitiesComponentMasks = aspect.World._entitiesComponentMasks; _sortIncChunckBuffer = aspect._sortIncChunckBuffer; _sortExcChunckBuffer = aspect._sortExcChunckBuffer; - int[] counts = mask.World._poolComponentCounts; #region Sort - IncCountComparer incComparer = new IncCountComparer(counts); - ExcCountComparer excComparer = new ExcCountComparer(counts); - UnsafeArraySortHalperX.InsertionSort(_sortIncBuffer.ptr, _sortIncBuffer.Length, ref incComparer); - UnsafeArraySortHalperX.InsertionSort(_sortExcBuffer.ptr, _sortExcBuffer.Length, ref excComparer); - - //if (_sortIncBuffer.Length > 1) - //{ - // //if (_sortIncBufferLength == 2) - // //{ - // // if (counts[_sortIncBuffer[0]] > counts[_sortIncBuffer[1]]) - // // { - // // int tmp = _sortIncBuffer[0]; - // // _sortIncBuffer[0] = _sortIncBuffer[1]; - // // _sortIncBuffer[1] = tmp; - // // } - // // //... - // //} - // //else - // { - // for (int i = 0, n = _sortIncBuffer.Length - 1; i < n; i++) - // { - // //int counti = counts[_sortIncBuffer[i]]; - // //if (counti <= 0) - // //{ - // // _span = ReadOnlySpan.Empty.GetEnumerator(); - // // goto skip1; - // //} - // bool noSwaped = true; - // for (int j = 0; j < n - i; ) - // { - // ref int j0 = ref _sortIncBuffer.ptr[j++]; - // if (counts[j0] > counts[_sortIncBuffer.ptr[j]]) - // { - // int tmp = _sortIncBuffer.ptr[j]; - // _sortIncBuffer.ptr[j] = j0; - // j0 = tmp; - // noSwaped = false; - // } - // } - // if (noSwaped) - // break; - // } - // } - //} - //skip1:; - //if (_sortExcBuffer.Length > 1) - //{ - // //if (_sortExcBufferLength == 2) - // //{ - // // if (counts[_sortExcBuffer[0]] < counts[_sortExcBuffer[1]]) - // // { - // // int tmp = _sortExcBuffer[0]; - // // _sortExcBuffer[0] = _sortExcBuffer[1]; - // // _sortExcBuffer[1] = tmp; - // // } - // // //... - // //} - // //else - // { - // for (int i = 0, n = _sortExcBuffer.Length - 1; i < n; i++) - // { - // //int counti = counts[_sortExcBuffer[i]]; - // //if (counti <= 0) - // //{ - // // _excChunckMasks = ReadOnlySpan.Empty; - // // goto skip2; - // //} - // bool noSwaped = true; - // for (int j = 0; j < n - i;) - // { - // ref int j0 = ref _sortExcBuffer.ptr[j++]; - // if (counts[j0] < counts[_sortExcBuffer.ptr[j]]) - // { - // int tmp = _sortExcBuffer.ptr[j]; - // _sortExcBuffer.ptr[j] = j0; - // j0 = tmp; - // noSwaped = false; - // } - // } - // if (noSwaped) - // break; - // } - // } - //} - //skip2:; - - + UnsafeArray _sortIncBuffer = aspect._sortIncBuffer; + UnsafeArray _sortExcBuffer = aspect._sortExcBuffer; + int[] counts = aspect.World._poolComponentCounts; if (_preSortedIncBuffer == null) { @@ -395,19 +308,14 @@ namespace DCFApixels.DragonECS _preSortedExcBuffer = UnmanagedArrayUtility.New(256); } - - for (int i = 0; i < _sortIncBuffer.Length; i++) - { - _preSortedIncBuffer[i] = EcsMaskChunck.FromID(_sortIncBuffer.ptr[i]); - } - for (int i = 0; i < _sortExcBuffer.Length; i++) - { - _preSortedExcBuffer[i] = EcsMaskChunck.FromID(_sortExcBuffer.ptr[i]); - } - - //if (_sortIncChunckBuffer.Length > 1)//перенести этот чек в начала сортировки, для _incChunckMasks.Length == 1 сортировка не нужна - if (_sortIncBuffer.Length > 1) + 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]; @@ -428,14 +336,16 @@ namespace DCFApixels.DragonECS } } } - else - { - _sortIncChunckBuffer.ptr[0] = _preSortedIncBuffer[0]; - } - //if (_sortExcChunckBuffer.Length > 1)//перенести этот чек в начала сортировки, для _excChunckMasks.Length == 1 сортировка не нужна - if (_sortExcBuffer.Length > 1) + 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]; @@ -456,10 +366,6 @@ namespace DCFApixels.DragonECS } } } - else - { - _sortExcChunckBuffer.ptr[0] = _preSortedExcBuffer[0]; - } #endregion } public int Current @@ -467,11 +373,11 @@ namespace DCFApixels.DragonECS [MethodImpl(MethodImplOptions.AggressiveInlining)] get => _span.Current; } - public entlong CurrentLong - { - [MethodImpl(MethodImplOptions.AggressiveInlining)] - get => aspect.World.GetEntityLong(_span.Current); - } + //public entlong CurrentLong + //{ + // [MethodImpl(MethodImplOptions.AggressiveInlining)] + // get => aspect.World.GetEntityLong(_span.Current); + //} [MethodImpl(MethodImplOptions.AggressiveInlining)] public bool MoveNext() { diff --git a/src/EcsMask.cs b/src/EcsMask.cs index 6cf6423..f6c27b2 100644 --- a/src/EcsMask.cs +++ b/src/EcsMask.cs @@ -30,12 +30,18 @@ namespace DCFApixels.DragonECS internal readonly EcsMaskChunck[] excChunckMasks; internal readonly int[] inc; internal readonly int[] exc; + + #region Properties + public int ID => id; public int WorldID => worldID; public EcsWorld World => EcsWorld.GetWorld(worldID); /// Including constraints public ReadOnlySpan Inc => inc; /// Excluding constraints public ReadOnlySpan Exc => exc; + #endregion + + #region Constructors internal EcsMask(int id, int worldID, int[] inc, int[] exc) { #if DEBUG @@ -79,6 +85,7 @@ namespace DCFApixels.DragonECS } return result; } + #endregion #region Object public override string ToString() => CreateLogString(worldID, inc, exc); @@ -322,6 +329,7 @@ namespace DCFApixels.DragonECS #endregion } + #region EcsMaskChunck [DebuggerTypeProxy(typeof(DebuggerProxy))] public readonly struct EcsMaskChunck { @@ -364,4 +372,5 @@ namespace DCFApixels.DragonECS } } } + #endregion } diff --git a/src/Utils/UnsafeArray.cs b/src/Utils/UnsafeArray.cs new file mode 100644 index 0000000..23f7fd1 --- /dev/null +++ b/src/Utils/UnsafeArray.cs @@ -0,0 +1,95 @@ +using DCFApixels.DragonECS.Utils; +using System; +using System.Collections; +using System.Collections.Generic; +using System.Diagnostics; +using System.Linq; +using System.Runtime.CompilerServices; + +namespace DCFApixels.DragonECS.Internal +{ + [DebuggerTypeProxy(typeof(UnsafeArray<>.DebuggerProxy))] + internal unsafe struct UnsafeArray : IDisposable, IEnumerable + where T : unmanaged + { + internal T* ptr; + internal int Length; + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public UnsafeArray(int length) + { + UnmanagedArrayUtility.New(out ptr, length); + Length = length; + } + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public UnsafeArray(int length, bool isInit) + { + UnmanagedArrayUtility.NewAndInit(out ptr, length); + Length = length; + } + [MethodImpl(MethodImplOptions.AggressiveInlining)] + private UnsafeArray(T* ptr, int length) + { + this.ptr = ptr; + Length = length; + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public UnsafeArray Clone() + { + return new UnsafeArray(UnmanagedArrayUtility.Clone(ptr, Length), Length); + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public void Dispose() + { + UnmanagedArrayUtility.Free(ref ptr, ref Length); + } + public override string ToString() + { + T* ptr = this.ptr; + return CollectionUtility.AutoToString(EnumerableInt.Range(0, Length).Select(i => ptr[i]), "ua"); + } + + IEnumerator IEnumerable.GetEnumerator() => GetEnumerator(); + IEnumerator IEnumerable.GetEnumerator() => GetEnumerator(); + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public Enumerator GetEnumerator() => new Enumerator(ptr, Length); + public struct Enumerator : IEnumerator + { + private readonly T* _ptr; + private readonly int _length; + private int _index; + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public Enumerator(T* ptr, int length) + { + _ptr = ptr; + _length = length; + _index = -1; + } + public T Current + { + [MethodImpl(MethodImplOptions.AggressiveInlining)] + get => _ptr[_index]; + } + object IEnumerator.Current => Current; + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public bool MoveNext() => ++_index < _length; + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public void Reset() { } + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public void Dispose() { } + } + + internal class DebuggerProxy + { + public T[] elements; + public int length; + public DebuggerProxy(UnsafeArray instance) + { + elements = EnumerableInt.Range(0, instance.Length).Select(i => instance.ptr[i]).ToArray(); + length = instance.Length; + } + } + } +}