This commit is contained in:
Mikhail 2024-01-07 23:19:18 +08:00
parent 14f1cf2856
commit 40141dfbb9
4 changed files with 135 additions and 125 deletions

View File

@ -37,7 +37,7 @@ namespace DCFApixels.DragonECS
internal class WorldComponentHandler<T> : IEcsWorldComponent<T> internal class WorldComponentHandler<T> : IEcsWorldComponent<T>
where T : IEcsWorldComponent<T> where T : IEcsWorldComponent<T>
{ {
private T _fakeInstnace; private T _fakeInstnace = default;
[MethodImpl(MethodImplOptions.AggressiveInlining)] [MethodImpl(MethodImplOptions.AggressiveInlining)]
public void Init(ref T component, EcsWorld world) => _fakeInstnace.Init(ref component, world); 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); public void OnDestroy(ref T component, EcsWorld world) => _fakeInstnace.OnDestroy(ref component, world);
@ -112,7 +112,7 @@ namespace DCFApixels.DragonECS
internal sealed class ComponentCopyHandler<T> : IEcsComponentCopy<T> internal sealed class ComponentCopyHandler<T> : IEcsComponentCopy<T>
where T : IEcsComponentCopy<T> where T : IEcsComponentCopy<T>
{ {
private T _fakeInstnace; private T _fakeInstnace = default;
[MethodImpl(MethodImplOptions.AggressiveInlining)] [MethodImpl(MethodImplOptions.AggressiveInlining)]
public void Copy(ref T from, ref T to) => _fakeInstnace.Copy(ref from, ref to); public void Copy(ref T from, ref T to) => _fakeInstnace.Copy(ref from, ref to);
} }

View File

@ -251,6 +251,7 @@ namespace DCFApixels.DragonECS
public unsafe ref struct Enumerator public unsafe ref struct Enumerator
{ {
#region CountComparers
private readonly struct IncCountComparer : IComparerX<int> private readonly struct IncCountComparer : IComparerX<int>
{ {
public readonly int[] counts; public readonly int[] counts;
@ -275,6 +276,8 @@ namespace DCFApixels.DragonECS
return counts[b] - counts[a]; return counts[b] - counts[a];
} }
} }
#endregion
private ReadOnlySpan<int>.Enumerator _span; private ReadOnlySpan<int>.Enumerator _span;
private readonly int[][] _entitiesComponentMasks; private readonly int[][] _entitiesComponentMasks;
@ -284,110 +287,20 @@ namespace DCFApixels.DragonECS
private UnsafeArray<EcsMaskChunck> _sortIncChunckBuffer; private UnsafeArray<EcsMaskChunck> _sortIncChunckBuffer;
private UnsafeArray<EcsMaskChunck> _sortExcChunckBuffer; private UnsafeArray<EcsMaskChunck> _sortExcChunckBuffer;
private EcsAspect aspect; //private EcsAspect aspect;
public unsafe Enumerator(EcsSpan span, EcsAspect aspect) public unsafe Enumerator(EcsSpan span, EcsAspect aspect)
{ {
this.aspect = aspect; //this.aspect = aspect;
_span = span.GetEnumerator(); _span = span.GetEnumerator();
_entitiesComponentMasks = span.World._entitiesComponentMasks; _entitiesComponentMasks = aspect.World._entitiesComponentMasks;
EcsMask mask = aspect.Mask;
UnsafeArray<int> _sortIncBuffer = aspect._sortIncBuffer;
UnsafeArray<int> _sortExcBuffer = aspect._sortExcBuffer;
_sortIncChunckBuffer = aspect._sortIncChunckBuffer; _sortIncChunckBuffer = aspect._sortIncChunckBuffer;
_sortExcChunckBuffer = aspect._sortExcChunckBuffer; _sortExcChunckBuffer = aspect._sortExcChunckBuffer;
int[] counts = mask.World._poolComponentCounts;
#region Sort #region Sort
IncCountComparer incComparer = new IncCountComparer(counts); UnsafeArray<int> _sortIncBuffer = aspect._sortIncBuffer;
ExcCountComparer excComparer = new ExcCountComparer(counts); UnsafeArray<int> _sortExcBuffer = aspect._sortExcBuffer;
UnsafeArraySortHalperX<int>.InsertionSort(_sortIncBuffer.ptr, _sortIncBuffer.Length, ref incComparer); int[] counts = aspect.World._poolComponentCounts;
UnsafeArraySortHalperX<int>.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<int>.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<EcsMaskBit>.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:;
if (_preSortedIncBuffer == null) if (_preSortedIncBuffer == null)
{ {
@ -395,19 +308,14 @@ namespace DCFApixels.DragonECS
_preSortedExcBuffer = UnmanagedArrayUtility.New<EcsMaskChunck>(256); _preSortedExcBuffer = UnmanagedArrayUtility.New<EcsMaskChunck>(256);
} }
if (_sortIncChunckBuffer.Length > 1)
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)
{ {
IncCountComparer incComparer = new IncCountComparer(counts);
UnsafeArraySortHalperX<int>.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++) for (int i = 0, ii = 0; ii < _sortIncChunckBuffer.Length; ii++)
{ {
EcsMaskChunck bas = _preSortedIncBuffer[i]; 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 (_sortExcChunckBuffer.Length > 1)
if (_sortExcBuffer.Length > 1)
{ {
ExcCountComparer excComparer = new ExcCountComparer(counts);
UnsafeArraySortHalperX<int>.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++) for (int i = 0, ii = 0; ii < _sortExcChunckBuffer.Length; ii++)
{ {
EcsMaskChunck bas = _preSortedExcBuffer[i]; EcsMaskChunck bas = _preSortedExcBuffer[i];
@ -456,10 +366,6 @@ namespace DCFApixels.DragonECS
} }
} }
} }
else
{
_sortExcChunckBuffer.ptr[0] = _preSortedExcBuffer[0];
}
#endregion #endregion
} }
public int Current public int Current
@ -467,11 +373,11 @@ namespace DCFApixels.DragonECS
[MethodImpl(MethodImplOptions.AggressiveInlining)] [MethodImpl(MethodImplOptions.AggressiveInlining)]
get => _span.Current; get => _span.Current;
} }
public entlong CurrentLong //public entlong CurrentLong
{ //{
[MethodImpl(MethodImplOptions.AggressiveInlining)] // [MethodImpl(MethodImplOptions.AggressiveInlining)]
get => aspect.World.GetEntityLong(_span.Current); // get => aspect.World.GetEntityLong(_span.Current);
} //}
[MethodImpl(MethodImplOptions.AggressiveInlining)] [MethodImpl(MethodImplOptions.AggressiveInlining)]
public bool MoveNext() public bool MoveNext()
{ {

View File

@ -30,12 +30,18 @@ namespace DCFApixels.DragonECS
internal readonly EcsMaskChunck[] excChunckMasks; internal readonly EcsMaskChunck[] excChunckMasks;
internal readonly int[] inc; internal readonly int[] inc;
internal readonly int[] exc; internal readonly int[] exc;
#region Properties
public int ID => id;
public int WorldID => worldID; public int WorldID => worldID;
public EcsWorld World => EcsWorld.GetWorld(worldID); public EcsWorld World => EcsWorld.GetWorld(worldID);
/// <summary>Including constraints</summary> /// <summary>Including constraints</summary>
public ReadOnlySpan<int> Inc => inc; public ReadOnlySpan<int> Inc => inc;
/// <summary>Excluding constraints</summary> /// <summary>Excluding constraints</summary>
public ReadOnlySpan<int> Exc => exc; public ReadOnlySpan<int> Exc => exc;
#endregion
#region Constructors
internal EcsMask(int id, int worldID, int[] inc, int[] exc) internal EcsMask(int id, int worldID, int[] inc, int[] exc)
{ {
#if DEBUG #if DEBUG
@ -79,6 +85,7 @@ namespace DCFApixels.DragonECS
} }
return result; return result;
} }
#endregion
#region Object #region Object
public override string ToString() => CreateLogString(worldID, inc, exc); public override string ToString() => CreateLogString(worldID, inc, exc);
@ -322,6 +329,7 @@ namespace DCFApixels.DragonECS
#endregion #endregion
} }
#region EcsMaskChunck
[DebuggerTypeProxy(typeof(DebuggerProxy))] [DebuggerTypeProxy(typeof(DebuggerProxy))]
public readonly struct EcsMaskChunck public readonly struct EcsMaskChunck
{ {
@ -364,4 +372,5 @@ namespace DCFApixels.DragonECS
} }
} }
} }
#endregion
} }

95
src/Utils/UnsafeArray.cs Normal file
View File

@ -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<T> : IDisposable, IEnumerable<T>
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<T> Clone()
{
return new UnsafeArray<T>(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<T> IEnumerable<T>.GetEnumerator() => GetEnumerator();
IEnumerator IEnumerable.GetEnumerator() => GetEnumerator();
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public Enumerator GetEnumerator() => new Enumerator(ptr, Length);
public struct Enumerator : IEnumerator<T>
{
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<T> instance)
{
elements = EnumerableInt.Range(0, instance.Length).Select(i => instance.ptr[i]).ToArray();
length = instance.Length;
}
}
}
}