mirror of
https://github.com/DCFApixels/DragonECS.git
synced 2025-09-19 02:24:37 +08:00
update
This commit is contained in:
parent
14f1cf2856
commit
40141dfbb9
@ -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);
|
||||||
}
|
}
|
||||||
|
144
src/EcsAspect.cs
144
src/EcsAspect.cs
@ -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)
|
||||||
|
{
|
||||||
|
IncCountComparer incComparer = new IncCountComparer(counts);
|
||||||
|
UnsafeArraySortHalperX<int>.InsertionSort(_sortIncBuffer.ptr, _sortIncBuffer.Length, ref incComparer);
|
||||||
for (int i = 0; i < _sortIncBuffer.Length; i++)
|
for (int i = 0; i < _sortIncBuffer.Length; i++)
|
||||||
{
|
{
|
||||||
_preSortedIncBuffer[i] = EcsMaskChunck.FromID(_sortIncBuffer.ptr[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)
|
|
||||||
{
|
|
||||||
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
|
|
||||||
|
if (_sortExcChunckBuffer.Length > 1)
|
||||||
{
|
{
|
||||||
_sortIncChunckBuffer.ptr[0] = _preSortedIncBuffer[0];
|
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]);
|
||||||
}
|
}
|
||||||
|
|
||||||
//if (_sortExcChunckBuffer.Length > 1)//перенести этот чек в начала сортировки, для _excChunckMasks.Length == 1 сортировка не нужна
|
|
||||||
if (_sortExcBuffer.Length > 1)
|
|
||||||
{
|
|
||||||
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()
|
||||||
{
|
{
|
||||||
|
@ -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
95
src/Utils/UnsafeArray.cs
Normal 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;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user