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>
|
||||
where T : IEcsWorldComponent<T>
|
||||
{
|
||||
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<T> : IEcsComponentCopy<T>
|
||||
where T : IEcsComponentCopy<T>
|
||||
{
|
||||
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);
|
||||
}
|
||||
|
144
src/EcsAspect.cs
144
src/EcsAspect.cs
@ -251,6 +251,7 @@ namespace DCFApixels.DragonECS
|
||||
|
||||
public unsafe ref struct Enumerator
|
||||
{
|
||||
#region CountComparers
|
||||
private readonly struct IncCountComparer : IComparerX<int>
|
||||
{
|
||||
public readonly int[] counts;
|
||||
@ -275,6 +276,8 @@ namespace DCFApixels.DragonECS
|
||||
return counts[b] - counts[a];
|
||||
}
|
||||
}
|
||||
#endregion
|
||||
|
||||
private ReadOnlySpan<int>.Enumerator _span;
|
||||
private readonly int[][] _entitiesComponentMasks;
|
||||
|
||||
@ -284,110 +287,20 @@ namespace DCFApixels.DragonECS
|
||||
private UnsafeArray<EcsMaskChunck> _sortIncChunckBuffer;
|
||||
private UnsafeArray<EcsMaskChunck> _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<int> _sortIncBuffer = aspect._sortIncBuffer;
|
||||
UnsafeArray<int> _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<int>.InsertionSort(_sortIncBuffer.ptr, _sortIncBuffer.Length, ref incComparer);
|
||||
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:;
|
||||
|
||||
|
||||
UnsafeArray<int> _sortIncBuffer = aspect._sortIncBuffer;
|
||||
UnsafeArray<int> _sortExcBuffer = aspect._sortExcBuffer;
|
||||
int[] counts = aspect.World._poolComponentCounts;
|
||||
|
||||
if (_preSortedIncBuffer == null)
|
||||
{
|
||||
@ -395,19 +308,14 @@ namespace DCFApixels.DragonECS
|
||||
_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++)
|
||||
{
|
||||
_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++)
|
||||
{
|
||||
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++)
|
||||
{
|
||||
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()
|
||||
{
|
||||
|
@ -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);
|
||||
/// <summary>Including constraints</summary>
|
||||
public ReadOnlySpan<int> Inc => inc;
|
||||
/// <summary>Excluding constraints</summary>
|
||||
public ReadOnlySpan<int> 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
|
||||
}
|
||||
|
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