mirror of
https://github.com/DCFApixels/DragonECS.git
synced 2025-09-18 01:44:35 +08:00
update mask iterator
This commit is contained in:
parent
7544d18d1e
commit
57b0ba225a
@ -260,7 +260,8 @@ namespace DCFApixels.DragonECS
|
|||||||
}
|
}
|
||||||
public EcsSpan CopyToSpan(ref int[] array)
|
public EcsSpan CopyToSpan(ref int[] array)
|
||||||
{
|
{
|
||||||
return iterator.CopyToSpan(ref array);
|
int count = CopyTo(ref array);
|
||||||
|
return new EcsSpan(worldID, array, count);
|
||||||
}
|
}
|
||||||
#endregion
|
#endregion
|
||||||
|
|
||||||
|
473
src/EcsMask.cs
473
src/EcsMask.cs
@ -11,6 +11,7 @@ using Unity.IL2CPP.CompilerServices;
|
|||||||
|
|
||||||
namespace DCFApixels.DragonECS
|
namespace DCFApixels.DragonECS
|
||||||
{
|
{
|
||||||
|
using static EcsMaskIteratorUtility;
|
||||||
public interface IEcsComponentMask
|
public interface IEcsComponentMask
|
||||||
{
|
{
|
||||||
EcsMask ToMask(EcsWorld world);
|
EcsMask ToMask(EcsWorld world);
|
||||||
@ -283,7 +284,7 @@ namespace DCFApixels.DragonECS
|
|||||||
do
|
do
|
||||||
{
|
{
|
||||||
EcsMaskChunck bitJ = EcsMaskChunck.FromID(sortedArray[i]);
|
EcsMaskChunck bitJ = EcsMaskChunck.FromID(sortedArray[i]);
|
||||||
if (bitJ.chankIndex != chankIndexX)
|
if (bitJ.chunkIndex != chankIndexX)
|
||||||
{
|
{
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@ -554,7 +555,7 @@ namespace DCFApixels.DragonECS
|
|||||||
|
|
||||||
#endregion
|
#endregion
|
||||||
|
|
||||||
#region AbstractMask
|
#region StaticMask
|
||||||
public static EcsMask FromStatic(EcsWorld world, EcsStaticMask abstractMask)
|
public static EcsMask FromStatic(EcsWorld world, EcsStaticMask abstractMask)
|
||||||
{
|
{
|
||||||
return world.Get<WorldMaskComponent>().ConvertFromAbstract(abstractMask);
|
return world.Get<WorldMaskComponent>().ConvertFromAbstract(abstractMask);
|
||||||
@ -849,11 +850,11 @@ namespace DCFApixels.DragonECS
|
|||||||
internal const int DIV_SHIFT = 5;
|
internal const int DIV_SHIFT = 5;
|
||||||
internal const int MOD_MASK = BITS - 1;
|
internal const int MOD_MASK = BITS - 1;
|
||||||
|
|
||||||
public readonly int chankIndex;
|
public readonly int chunkIndex;
|
||||||
public readonly int mask;
|
public readonly int mask;
|
||||||
public EcsMaskChunck(int chankIndex, int mask)
|
public EcsMaskChunck(int chankIndex, int mask)
|
||||||
{
|
{
|
||||||
this.chankIndex = chankIndex;
|
this.chunkIndex = chankIndex;
|
||||||
this.mask = mask;
|
this.mask = mask;
|
||||||
}
|
}
|
||||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||||
@ -863,7 +864,7 @@ namespace DCFApixels.DragonECS
|
|||||||
}
|
}
|
||||||
public override string ToString()
|
public override string ToString()
|
||||||
{
|
{
|
||||||
return $"mask({chankIndex}, {mask}, {BitsUtility.CountBits(mask)})";
|
return $"mask({chunkIndex}, {mask}, {BitsUtility.CountBits(mask)})";
|
||||||
}
|
}
|
||||||
internal class DebuggerProxy
|
internal class DebuggerProxy
|
||||||
{
|
{
|
||||||
@ -873,7 +874,7 @@ namespace DCFApixels.DragonECS
|
|||||||
public string bits;
|
public string bits;
|
||||||
public DebuggerProxy(EcsMaskChunck maskbits)
|
public DebuggerProxy(EcsMaskChunck maskbits)
|
||||||
{
|
{
|
||||||
chunk = maskbits.chankIndex;
|
chunk = maskbits.chunkIndex;
|
||||||
mask = (uint)maskbits.mask;
|
mask = (uint)maskbits.mask;
|
||||||
BitsUtility.GetBitNumbersNoAlloc(mask, ref values);
|
BitsUtility.GetBitNumbersNoAlloc(mask, ref values);
|
||||||
for (int i = 0; i < values.Length; i++)
|
for (int i = 0; i < values.Length; i++)
|
||||||
@ -893,103 +894,75 @@ namespace DCFApixels.DragonECS
|
|||||||
#endif
|
#endif
|
||||||
public class EcsMaskIterator
|
public class EcsMaskIterator
|
||||||
{
|
{
|
||||||
#region CountStructComparers
|
public readonly EcsWorld World;
|
||||||
private readonly struct IncCountComparer : IStructComparer<int>
|
public readonly EcsMask Mask;
|
||||||
{
|
|
||||||
public readonly EcsWorld.PoolSlot[] counts;
|
|
||||||
public IncCountComparer(EcsWorld.PoolSlot[] counts)
|
|
||||||
{
|
|
||||||
this.counts = counts;
|
|
||||||
}
|
|
||||||
public int Compare(int a, int b)
|
|
||||||
{
|
|
||||||
return counts[a].count - counts[b].count;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
private readonly struct ExcCountComparer : IStructComparer<int>
|
|
||||||
{
|
|
||||||
public readonly EcsWorld.PoolSlot[] counts;
|
|
||||||
public ExcCountComparer(EcsWorld.PoolSlot[] counts)
|
|
||||||
{
|
|
||||||
this.counts = counts;
|
|
||||||
}
|
|
||||||
public int Compare(int a, int b)
|
|
||||||
{
|
|
||||||
return counts[b].count - counts[a].count;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
#endregion
|
|
||||||
|
|
||||||
internal EcsWorld _source;
|
private readonly UnsafeArray<int> _sortIncBuffer;
|
||||||
internal EcsMask _mask;
|
private readonly UnsafeArray<int> _sortExcBuffer;
|
||||||
|
private readonly UnsafeArray<EcsMaskChunck> _sortIncChunckBuffer;
|
||||||
|
private readonly UnsafeArray<EcsMaskChunck> _sortExcChunckBuffer;
|
||||||
|
|
||||||
private UnsafeArray<int> _sortIncBuffer;
|
private readonly bool _isOnlyInc;
|
||||||
private UnsafeArray<int> _sortExcBuffer;
|
|
||||||
private UnsafeArray<EcsMaskChunck> _sortIncChunckBuffer;
|
|
||||||
private UnsafeArray<EcsMaskChunck> _sortExcChunckBuffer;
|
|
||||||
|
|
||||||
#region Constructors
|
#region Constructors/Finalizator
|
||||||
public unsafe EcsMaskIterator(EcsWorld source, EcsMask mask)
|
public unsafe EcsMaskIterator(EcsWorld source, EcsMask mask)
|
||||||
{
|
{
|
||||||
_source = source;
|
World = source;
|
||||||
_mask = mask;
|
Mask = mask;
|
||||||
|
_sortIncBuffer = UnsafeArray<int>.FromArray(mask._inc);
|
||||||
_sortIncBuffer = new UnsafeArray<int>(_mask._inc.Length);
|
_sortExcBuffer = UnsafeArray<int>.FromArray(mask._exc);
|
||||||
_sortExcBuffer = new UnsafeArray<int>(_mask._exc.Length);
|
_sortIncChunckBuffer = UnsafeArray<EcsMaskChunck>.FromArray(mask._incChunckMasks);
|
||||||
_sortIncChunckBuffer = new UnsafeArray<EcsMaskChunck>(_mask._incChunckMasks.Length);
|
_sortExcChunckBuffer = UnsafeArray<EcsMaskChunck>.FromArray(mask._excChunckMasks);
|
||||||
_sortExcChunckBuffer = new UnsafeArray<EcsMaskChunck>(_mask._excChunckMasks.Length);
|
_isOnlyInc = _sortExcBuffer.Length <= 0;
|
||||||
|
|
||||||
for (int i = 0; i < _sortIncBuffer.Length; i++)
|
|
||||||
{
|
|
||||||
_sortIncBuffer.ptr[i] = _mask._inc[i];
|
|
||||||
}
|
|
||||||
for (int i = 0; i < _sortExcBuffer.Length; i++)
|
|
||||||
{
|
|
||||||
_sortExcBuffer.ptr[i] = _mask._exc[i];
|
|
||||||
}
|
|
||||||
|
|
||||||
for (int i = 0; i < _sortIncChunckBuffer.Length; i++)
|
|
||||||
{
|
|
||||||
_sortIncChunckBuffer.ptr[i] = _mask._incChunckMasks[i];
|
|
||||||
}
|
|
||||||
for (int i = 0; i < _sortExcChunckBuffer.Length; i++)
|
|
||||||
{
|
|
||||||
_sortExcChunckBuffer.ptr[i] = _mask._excChunckMasks[i];
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
#endregion
|
|
||||||
|
|
||||||
#region Finalizator
|
|
||||||
unsafe ~EcsMaskIterator()
|
unsafe ~EcsMaskIterator()
|
||||||
{
|
{
|
||||||
_sortIncBuffer.Dispose();
|
_sortIncBuffer.ReadonlyDispose();
|
||||||
_sortExcBuffer.Dispose();
|
_sortExcBuffer.ReadonlyDispose();
|
||||||
_sortIncChunckBuffer.Dispose();
|
_sortIncChunckBuffer.ReadonlyDispose();
|
||||||
_sortExcChunckBuffer.Dispose();
|
_sortExcChunckBuffer.ReadonlyDispose();
|
||||||
}
|
}
|
||||||
#endregion
|
#endregion
|
||||||
|
|
||||||
#region Properties
|
|
||||||
public EcsWorld World
|
#region IterateTo
|
||||||
|
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||||
|
public void IterateTo(EcsSpan source, EcsGroup group)
|
||||||
{
|
{
|
||||||
get { return _source; }
|
if (_isOnlyInc)
|
||||||
|
{
|
||||||
|
IterateOnlyInc(source).CopyTo(group);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
Iterate(source).CopyTo(group);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
public EcsMask Mask
|
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||||
|
public int IterateTo(EcsSpan source, ref int[] array)
|
||||||
{
|
{
|
||||||
get { return _mask; }
|
if (_isOnlyInc)
|
||||||
|
{
|
||||||
|
return IterateOnlyInc(source).CopyTo(ref array);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return Iterate(source).CopyTo(ref array);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
#endregion
|
#endregion
|
||||||
|
|
||||||
#region Enumerable
|
#region Iterate/Enumerable
|
||||||
public Enumerable Iterate(EcsSpan span)
|
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||||
{
|
public Enumerable Iterate(EcsSpan span) { return new Enumerable(this, span); }
|
||||||
return new Enumerable(this, span);
|
#if ENABLE_IL2CPP
|
||||||
}
|
[Il2CppSetOption (Option.NullChecks, false)]
|
||||||
|
[Il2CppSetOption(Option.ArrayBoundsChecks, false)]
|
||||||
|
#endif
|
||||||
public readonly ref struct Enumerable
|
public readonly ref struct Enumerable
|
||||||
{
|
{
|
||||||
private readonly EcsMaskIterator _iterator;
|
private readonly EcsMaskIterator _iterator;
|
||||||
private readonly EcsSpan _span;
|
private readonly EcsSpan _span;
|
||||||
|
|
||||||
public Enumerable(EcsMaskIterator iterator, EcsSpan span)
|
public Enumerable(EcsMaskIterator iterator, EcsSpan span)
|
||||||
{
|
{
|
||||||
_iterator = iterator;
|
_iterator = iterator;
|
||||||
@ -997,6 +970,7 @@ namespace DCFApixels.DragonECS
|
|||||||
}
|
}
|
||||||
|
|
||||||
#region CopyTo
|
#region CopyTo
|
||||||
|
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||||
public void CopyTo(EcsGroup group)
|
public void CopyTo(EcsGroup group)
|
||||||
{
|
{
|
||||||
group.Clear();
|
group.Clear();
|
||||||
@ -1006,6 +980,7 @@ namespace DCFApixels.DragonECS
|
|||||||
group.AddUnchecked(enumerator.Current);
|
group.AddUnchecked(enumerator.Current);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||||
public int CopyTo(ref int[] array)
|
public int CopyTo(ref int[] array)
|
||||||
{
|
{
|
||||||
int count = 0;
|
int count = 0;
|
||||||
@ -1020,50 +995,41 @@ namespace DCFApixels.DragonECS
|
|||||||
}
|
}
|
||||||
return count;
|
return count;
|
||||||
}
|
}
|
||||||
public EcsSpan CopyToSpan(ref int[] array)
|
|
||||||
{
|
|
||||||
int count = CopyTo(ref array);
|
|
||||||
return new EcsSpan(_iterator.World.id, array, count);
|
|
||||||
}
|
|
||||||
#endregion
|
#endregion
|
||||||
|
|
||||||
#region Other
|
#region Other
|
||||||
public override string ToString()
|
public List<int> ToList()
|
||||||
{
|
{
|
||||||
List<int> ints = new List<int>();
|
List<int> ints = new List<int>();
|
||||||
foreach (var e in this)
|
foreach (var e in this) { ints.Add(e); }
|
||||||
{
|
return ints;
|
||||||
ints.Add(e);
|
|
||||||
}
|
|
||||||
return CollectionUtility.EntitiesToString(ints, "it");
|
|
||||||
}
|
}
|
||||||
|
public override string ToString() { return CollectionUtility.EntitiesToString(ToList(), "it"); }
|
||||||
#endregion
|
#endregion
|
||||||
|
|
||||||
#region Enumerator
|
#region Enumerator
|
||||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||||
public Enumerator GetEnumerator() { return new Enumerator(_span, _iterator); }
|
public Enumerator GetEnumerator() { return new Enumerator(_span, _iterator); }
|
||||||
|
#if ENABLE_IL2CPP
|
||||||
|
[Il2CppSetOption (Option.NullChecks, false)]
|
||||||
|
[Il2CppSetOption(Option.ArrayBoundsChecks, false)]
|
||||||
|
#endif
|
||||||
public unsafe ref struct Enumerator
|
public unsafe ref struct Enumerator
|
||||||
{
|
{
|
||||||
private ReadOnlySpan<int>.Enumerator _span;
|
private ReadOnlySpan<int>.Enumerator _span;
|
||||||
|
|
||||||
|
private readonly UnsafeArray<EcsMaskChunck> _sortIncChunckBuffer;
|
||||||
|
private readonly UnsafeArray<EcsMaskChunck> _sortExcChunckBuffer;
|
||||||
|
|
||||||
private readonly int[] _entityComponentMasks;
|
private readonly int[] _entityComponentMasks;
|
||||||
|
|
||||||
[ThreadStatic]
|
|
||||||
private static EcsMaskChunck* _preSortedIncBuffer;
|
|
||||||
[ThreadStatic]
|
|
||||||
private static EcsMaskChunck* _preSortedExcBuffer;
|
|
||||||
|
|
||||||
private UnsafeArray<EcsMaskChunck> _sortIncChunckBuffer;
|
|
||||||
private UnsafeArray<EcsMaskChunck> _sortExcChunckBuffer;
|
|
||||||
|
|
||||||
private readonly int _entityComponentMaskLengthBitShift;
|
private readonly int _entityComponentMaskLengthBitShift;
|
||||||
|
|
||||||
public unsafe Enumerator(EcsSpan span, EcsMaskIterator iterator)
|
public unsafe Enumerator(EcsSpan span, EcsMaskIterator iterator)
|
||||||
{
|
{
|
||||||
_entityComponentMasks = iterator.World._entityComponentMasks;
|
|
||||||
_sortIncChunckBuffer = iterator._sortIncChunckBuffer;
|
_sortIncChunckBuffer = iterator._sortIncChunckBuffer;
|
||||||
_sortExcChunckBuffer = iterator._sortExcChunckBuffer;
|
_sortExcChunckBuffer = iterator._sortExcChunckBuffer;
|
||||||
|
|
||||||
|
_entityComponentMasks = iterator.World._entityComponentMasks;
|
||||||
_entityComponentMaskLengthBitShift = iterator.World._entityComponentMaskLengthBitShift;
|
_entityComponentMaskLengthBitShift = iterator.World._entityComponentMaskLengthBitShift;
|
||||||
|
|
||||||
if (iterator.Mask.IsBroken)
|
if (iterator.Mask.IsBroken)
|
||||||
@ -1076,74 +1042,36 @@ namespace DCFApixels.DragonECS
|
|||||||
UnsafeArray<int> _sortIncBuffer = iterator._sortIncBuffer;
|
UnsafeArray<int> _sortIncBuffer = iterator._sortIncBuffer;
|
||||||
UnsafeArray<int> _sortExcBuffer = iterator._sortExcBuffer;
|
UnsafeArray<int> _sortExcBuffer = iterator._sortExcBuffer;
|
||||||
EcsWorld.PoolSlot[] counts = iterator.World._poolSlots;
|
EcsWorld.PoolSlot[] counts = iterator.World._poolSlots;
|
||||||
|
int max = _sortIncBuffer.Length > _sortExcBuffer.Length ? _sortIncBuffer.Length : _sortExcBuffer.Length;
|
||||||
|
|
||||||
if (_preSortedIncBuffer == null)
|
EcsMaskChunck* preSortingBuffer;
|
||||||
|
if (max > STACK_BUFFER_THRESHOLD)
|
||||||
{
|
{
|
||||||
_preSortedIncBuffer = UnmanagedArrayUtility.New<EcsMaskChunck>(256);
|
preSortingBuffer = TempBuffer<EcsMaskChunck>.Get(max);
|
||||||
_preSortedExcBuffer = UnmanagedArrayUtility.New<EcsMaskChunck>(256);
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
EcsMaskChunck* ptr = stackalloc EcsMaskChunck[max];
|
||||||
|
preSortingBuffer = ptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (_sortIncChunckBuffer.Length > 1)
|
if (_sortIncChunckBuffer.Length > 1)
|
||||||
{
|
{
|
||||||
IncCountComparer incComparer = new IncCountComparer(counts);
|
var comparer = new IncCountComparer(counts);
|
||||||
UnsafeArraySortHalperX<int>.InsertionSort(_sortIncBuffer.ptr, _sortIncBuffer.Length, ref incComparer);
|
UnsafeArraySortHalperX<int>.InsertionSort(_sortIncBuffer.ptr, _sortIncBuffer.Length, ref comparer);
|
||||||
for (int i = 0; i < _sortIncBuffer.Length; i++)
|
ConvertToChuncks(preSortingBuffer, _sortIncBuffer, _sortIncChunckBuffer);
|
||||||
{
|
|
||||||
_preSortedIncBuffer[i] = EcsMaskChunck.FromID(_sortIncBuffer.ptr[i]);
|
|
||||||
}
|
|
||||||
for (int i = 0, ii = 0; ii < _sortIncChunckBuffer.Length; ii++)
|
|
||||||
{
|
|
||||||
EcsMaskChunck chunkX = _preSortedIncBuffer[i];
|
|
||||||
int chankIndexX = chunkX.chankIndex;
|
|
||||||
int maskX = chunkX.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 (_sortIncChunckBuffer.Length > 0 && counts[_sortIncBuffer.ptr[0]].count <= 0)
|
if (_sortIncChunckBuffer.Length > 0 && counts[_sortIncBuffer.ptr[0]].count <= 0)
|
||||||
{
|
{
|
||||||
_span = span.Slice(0, 0).GetEnumerator();
|
_span = span.Slice(0, 0).GetEnumerator();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (_sortExcChunckBuffer.Length > 1)
|
if (_sortExcChunckBuffer.Length > 1)
|
||||||
{
|
{
|
||||||
ExcCountComparer excComparer = new ExcCountComparer(counts);
|
ExcCountComparer comparer = new ExcCountComparer(counts);
|
||||||
UnsafeArraySortHalperX<int>.InsertionSort(_sortExcBuffer.ptr, _sortExcBuffer.Length, ref excComparer);
|
UnsafeArraySortHalperX<int>.InsertionSort(_sortExcBuffer.ptr, _sortExcBuffer.Length, ref comparer);
|
||||||
for (int i = 0; i < _sortExcBuffer.Length; i++)
|
ConvertToChuncks(preSortingBuffer, _sortExcBuffer, _sortExcChunckBuffer);
|
||||||
{
|
|
||||||
_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
|
#endregion
|
||||||
|
|
||||||
@ -1163,7 +1091,7 @@ namespace DCFApixels.DragonECS
|
|||||||
for (int i = 0; i < _sortIncChunckBuffer.Length; i++)
|
for (int i = 0; i < _sortIncChunckBuffer.Length; i++)
|
||||||
{
|
{
|
||||||
var bit = _sortIncChunckBuffer.ptr[i];
|
var bit = _sortIncChunckBuffer.ptr[i];
|
||||||
if ((_entityComponentMasks[chunck + bit.chankIndex] & bit.mask) != bit.mask)
|
if ((_entityComponentMasks[chunck + bit.chunkIndex] & bit.mask) != bit.mask)
|
||||||
{
|
{
|
||||||
goto skip;
|
goto skip;
|
||||||
}
|
}
|
||||||
@ -1171,7 +1099,152 @@ namespace DCFApixels.DragonECS
|
|||||||
for (int i = 0; i < _sortExcChunckBuffer.Length; i++)
|
for (int i = 0; i < _sortExcChunckBuffer.Length; i++)
|
||||||
{
|
{
|
||||||
var bit = _sortExcChunckBuffer.ptr[i];
|
var bit = _sortExcChunckBuffer.ptr[i];
|
||||||
if ((_entityComponentMasks[chunck + bit.chankIndex] & bit.mask) != 0)
|
if ((_entityComponentMasks[chunck + bit.chunkIndex] & bit.mask) != 0)
|
||||||
|
{
|
||||||
|
goto skip;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
skip: continue;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endregion
|
||||||
|
}
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
#region Iterate/Enumerable OnlyInc
|
||||||
|
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||||
|
public OnlyIncEnumerable IterateOnlyInc(EcsSpan span) { return new OnlyIncEnumerable(this, span); }
|
||||||
|
#if ENABLE_IL2CPP
|
||||||
|
[Il2CppSetOption (Option.NullChecks, false)]
|
||||||
|
[Il2CppSetOption(Option.ArrayBoundsChecks, false)]
|
||||||
|
#endif
|
||||||
|
public readonly ref struct OnlyIncEnumerable
|
||||||
|
{
|
||||||
|
private readonly EcsMaskIterator _iterator;
|
||||||
|
private readonly EcsSpan _span;
|
||||||
|
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||||
|
public OnlyIncEnumerable(EcsMaskIterator iterator, EcsSpan span)
|
||||||
|
{
|
||||||
|
_iterator = iterator;
|
||||||
|
_span = span;
|
||||||
|
}
|
||||||
|
|
||||||
|
#region CopyTo
|
||||||
|
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||||
|
public void CopyTo(EcsGroup group)
|
||||||
|
{
|
||||||
|
group.Clear();
|
||||||
|
var enumerator = GetEnumerator();
|
||||||
|
while (enumerator.MoveNext())
|
||||||
|
{
|
||||||
|
group.AddUnchecked(enumerator.Current);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||||
|
public int CopyTo(ref int[] array)
|
||||||
|
{
|
||||||
|
int count = 0;
|
||||||
|
var enumerator = GetEnumerator();
|
||||||
|
while (enumerator.MoveNext())
|
||||||
|
{
|
||||||
|
if (array.Length <= count)
|
||||||
|
{
|
||||||
|
Array.Resize(ref array, array.Length << 1);
|
||||||
|
}
|
||||||
|
array[count++] = enumerator.Current;
|
||||||
|
}
|
||||||
|
return count;
|
||||||
|
}
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
#region Other
|
||||||
|
public List<int> ToList()
|
||||||
|
{
|
||||||
|
List<int> ints = new List<int>();
|
||||||
|
foreach (var e in this) { ints.Add(e); }
|
||||||
|
return ints;
|
||||||
|
}
|
||||||
|
public override string ToString() { return CollectionUtility.EntitiesToString(ToList(), "inc_it"); }
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
#region Enumerator
|
||||||
|
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||||
|
public Enumerator GetEnumerator() { return new Enumerator(_span, _iterator); }
|
||||||
|
#if ENABLE_IL2CPP
|
||||||
|
[Il2CppSetOption (Option.NullChecks, false)]
|
||||||
|
[Il2CppSetOption(Option.ArrayBoundsChecks, false)]
|
||||||
|
#endif
|
||||||
|
public unsafe ref struct Enumerator
|
||||||
|
{
|
||||||
|
private ReadOnlySpan<int>.Enumerator _span;
|
||||||
|
|
||||||
|
private readonly UnsafeArray<EcsMaskChunck> _sortIncChunckBuffer;
|
||||||
|
|
||||||
|
private readonly int[] _entityComponentMasks;
|
||||||
|
private readonly int _entityComponentMaskLengthBitShift;
|
||||||
|
|
||||||
|
public unsafe Enumerator(EcsSpan span, EcsMaskIterator iterator)
|
||||||
|
{
|
||||||
|
_sortIncChunckBuffer = iterator._sortIncChunckBuffer;
|
||||||
|
|
||||||
|
_entityComponentMasks = iterator.World._entityComponentMasks;
|
||||||
|
_entityComponentMaskLengthBitShift = iterator.World._entityComponentMaskLengthBitShift;
|
||||||
|
|
||||||
|
if (iterator.Mask.IsBroken)
|
||||||
|
{
|
||||||
|
_span = span.Slice(0, 0).GetEnumerator();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
#region Sort
|
||||||
|
UnsafeArray<int> _sortIncBuffer = iterator._sortIncBuffer;
|
||||||
|
EcsWorld.PoolSlot[] counts = iterator.World._poolSlots;
|
||||||
|
int max = _sortIncBuffer.Length;
|
||||||
|
|
||||||
|
EcsMaskChunck* preSortingBuffer;
|
||||||
|
if (max > STACK_BUFFER_THRESHOLD)
|
||||||
|
{
|
||||||
|
preSortingBuffer = TempBuffer<EcsMaskChunck>.Get(max);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
EcsMaskChunck* ptr = stackalloc EcsMaskChunck[max];
|
||||||
|
preSortingBuffer = ptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (_sortIncChunckBuffer.Length > 1)
|
||||||
|
{
|
||||||
|
var comparer = new IncCountComparer(counts);
|
||||||
|
UnsafeArraySortHalperX<int>.InsertionSort(_sortIncBuffer.ptr, _sortIncBuffer.Length, ref comparer);
|
||||||
|
ConvertToChuncks(preSortingBuffer, _sortIncBuffer, _sortIncChunckBuffer);
|
||||||
|
}
|
||||||
|
if (_sortIncChunckBuffer.Length > 0 && counts[_sortIncBuffer.ptr[0]].count <= 0)
|
||||||
|
{
|
||||||
|
_span = span.Slice(0, 0).GetEnumerator();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
_span = span.GetEnumerator();
|
||||||
|
}
|
||||||
|
public int Current
|
||||||
|
{
|
||||||
|
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||||
|
get { return _span.Current; }
|
||||||
|
}
|
||||||
|
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||||
|
public bool MoveNext()
|
||||||
|
{
|
||||||
|
while (_span.MoveNext())
|
||||||
|
{
|
||||||
|
int chunck = _span.Current << _entityComponentMaskLengthBitShift;
|
||||||
|
for (int i = 0; i < _sortIncChunckBuffer.Length; i++)
|
||||||
|
{
|
||||||
|
var bit = _sortIncChunckBuffer.ptr[i];
|
||||||
|
if ((_entityComponentMasks[chunck + bit.chunkIndex] & bit.mask) != bit.mask)
|
||||||
{
|
{
|
||||||
goto skip;
|
goto skip;
|
||||||
}
|
}
|
||||||
@ -1187,4 +1260,84 @@ namespace DCFApixels.DragonECS
|
|||||||
#endregion
|
#endregion
|
||||||
}
|
}
|
||||||
#endregion
|
#endregion
|
||||||
|
}
|
||||||
|
|
||||||
|
namespace DCFApixels.DragonECS.Internal
|
||||||
|
{
|
||||||
|
#region EcsMaskIteratorUtility
|
||||||
|
#if ENABLE_IL2CPP
|
||||||
|
[Il2CppSetOption (Option.NullChecks, false)]
|
||||||
|
[Il2CppSetOption(Option.ArrayBoundsChecks, false)]
|
||||||
|
#endif
|
||||||
|
internal unsafe class EcsMaskIteratorUtility
|
||||||
|
{
|
||||||
|
internal const int STACK_BUFFER_THRESHOLD = 256;
|
||||||
|
|
||||||
|
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||||
|
internal static void ConvertToChuncks(EcsMaskChunck* ptr, UnsafeArray<int> input, UnsafeArray<EcsMaskChunck> output)
|
||||||
|
{
|
||||||
|
for (int i = 0; i < input.Length; i++)
|
||||||
|
{
|
||||||
|
ptr[i] = EcsMaskChunck.FromID(input.ptr[i]);
|
||||||
|
}
|
||||||
|
|
||||||
|
for (int inputI = 0, outputI = 0; outputI < output.Length; inputI++, ptr++)
|
||||||
|
{
|
||||||
|
int maskX = ptr->mask;
|
||||||
|
if (maskX == 0) { continue; }
|
||||||
|
int chunkIndexX = ptr->chunkIndex;
|
||||||
|
|
||||||
|
EcsMaskChunck* subptr = ptr;
|
||||||
|
for (int j = 1; j < input.Length - inputI; j++, subptr++)
|
||||||
|
{
|
||||||
|
if (subptr->chunkIndex == chunkIndexX)
|
||||||
|
{
|
||||||
|
maskX |= subptr->mask;
|
||||||
|
*subptr = default;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
output.ptr[outputI] = new EcsMaskChunck(chunkIndexX, maskX);
|
||||||
|
outputI++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#if ENABLE_IL2CPP
|
||||||
|
[Il2CppSetOption (Option.NullChecks, false)]
|
||||||
|
[Il2CppSetOption(Option.ArrayBoundsChecks, false)]
|
||||||
|
#endif
|
||||||
|
internal readonly struct IncCountComparer : IStructComparer<int>
|
||||||
|
{
|
||||||
|
public readonly EcsWorld.PoolSlot[] counts;
|
||||||
|
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||||
|
public IncCountComparer(EcsWorld.PoolSlot[] counts)
|
||||||
|
{
|
||||||
|
this.counts = counts;
|
||||||
|
}
|
||||||
|
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||||
|
public int Compare(int a, int b)
|
||||||
|
{
|
||||||
|
return counts[a].count - counts[b].count;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#if ENABLE_IL2CPP
|
||||||
|
[Il2CppSetOption (Option.NullChecks, false)]
|
||||||
|
[Il2CppSetOption(Option.ArrayBoundsChecks, false)]
|
||||||
|
#endif
|
||||||
|
internal readonly struct ExcCountComparer : IStructComparer<int>
|
||||||
|
{
|
||||||
|
public readonly EcsWorld.PoolSlot[] counts;
|
||||||
|
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||||
|
public ExcCountComparer(EcsWorld.PoolSlot[] counts)
|
||||||
|
{
|
||||||
|
this.counts = counts;
|
||||||
|
}
|
||||||
|
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||||
|
public int Compare(int a, int b)
|
||||||
|
{
|
||||||
|
return counts[b].count - counts[a].count;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endregion
|
||||||
}
|
}
|
@ -82,7 +82,7 @@ namespace DCFApixels.DragonECS
|
|||||||
|
|
||||||
// Если система одновременно явялется и системой и модулем то сначала будет вызван IEcsModule
|
// Если система одновременно явялется и системой и модулем то сначала будет вызван IEcsModule
|
||||||
// При этом дается возможность ручной установки порядка импорта системы вызовом Add(this)
|
// При этом дается возможность ручной установки порядка импорта системы вызовом Add(this)
|
||||||
if(_systemModule == system)
|
if (_systemModule == system)
|
||||||
{
|
{
|
||||||
_systemModuleAdded = true;
|
_systemModuleAdded = true;
|
||||||
}
|
}
|
||||||
@ -413,7 +413,7 @@ namespace DCFApixels.DragonECS
|
|||||||
// Автоматический слой нужный только для метода Add
|
// Автоматический слой нужный только для метода Add
|
||||||
// Идея в том что метод Add добавляет слои до EcsConsts.END_LAYER и EcsConsts.POST_END_LAYER
|
// Идея в том что метод Add добавляет слои до EcsConsts.END_LAYER и EcsConsts.POST_END_LAYER
|
||||||
private const string ADD_LAYERS_LAYER = nameof(LayerList) + "." + nameof(ADD_LAYERS_LAYER);
|
private const string ADD_LAYERS_LAYER = nameof(LayerList) + "." + nameof(ADD_LAYERS_LAYER);
|
||||||
|
|
||||||
|
|
||||||
private Builder _source;
|
private Builder _source;
|
||||||
private List<string> _layers;
|
private List<string> _layers;
|
||||||
|
@ -238,7 +238,7 @@ namespace DCFApixels.DragonECS
|
|||||||
slot.count++;
|
slot.count++;
|
||||||
slot.version++;
|
slot.version++;
|
||||||
_entities[entityID].componentsCount++;
|
_entities[entityID].componentsCount++;
|
||||||
_entityComponentMasks[(entityID << _entityComponentMaskLengthBitShift) + maskBit.chankIndex] |= maskBit.mask;
|
_entityComponentMasks[(entityID << _entityComponentMaskLengthBitShift) + maskBit.chunkIndex] |= maskBit.mask;
|
||||||
}
|
}
|
||||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||||
private void UnregisterEntityComponent(int entityID, int componentTypeID, EcsMaskChunck maskBit)
|
private void UnregisterEntityComponent(int entityID, int componentTypeID, EcsMaskChunck maskBit)
|
||||||
@ -248,7 +248,7 @@ namespace DCFApixels.DragonECS
|
|||||||
slot.count--;
|
slot.count--;
|
||||||
slot.version++;
|
slot.version++;
|
||||||
var count = --_entities[entityID].componentsCount;
|
var count = --_entities[entityID].componentsCount;
|
||||||
_entityComponentMasks[(entityID << _entityComponentMaskLengthBitShift) + maskBit.chankIndex] &= ~maskBit.mask;
|
_entityComponentMasks[(entityID << _entityComponentMaskLengthBitShift) + maskBit.chunkIndex] &= ~maskBit.mask;
|
||||||
|
|
||||||
if (count == 0 && IsUsed(entityID))
|
if (count == 0 && IsUsed(entityID))
|
||||||
{
|
{
|
||||||
@ -263,7 +263,7 @@ namespace DCFApixels.DragonECS
|
|||||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||||
private bool TryRegisterEntityComponent(int entityID, int componentTypeID, EcsMaskChunck maskBit)
|
private bool TryRegisterEntityComponent(int entityID, int componentTypeID, EcsMaskChunck maskBit)
|
||||||
{
|
{
|
||||||
ref int chunk = ref _entityComponentMasks[(entityID << _entityComponentMaskLengthBitShift) + maskBit.chankIndex];
|
ref int chunk = ref _entityComponentMasks[(entityID << _entityComponentMaskLengthBitShift) + maskBit.chunkIndex];
|
||||||
int newChunk = chunk | maskBit.mask;
|
int newChunk = chunk | maskBit.mask;
|
||||||
if (chunk != newChunk)
|
if (chunk != newChunk)
|
||||||
{
|
{
|
||||||
@ -280,7 +280,7 @@ namespace DCFApixels.DragonECS
|
|||||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||||
private bool TryUnregisterEntityComponent(int entityID, int componentTypeID, EcsMaskChunck maskBit)
|
private bool TryUnregisterEntityComponent(int entityID, int componentTypeID, EcsMaskChunck maskBit)
|
||||||
{
|
{
|
||||||
ref int chunk = ref _entityComponentMasks[(entityID << _entityComponentMaskLengthBitShift) + maskBit.chankIndex];
|
ref int chunk = ref _entityComponentMasks[(entityID << _entityComponentMaskLengthBitShift) + maskBit.chunkIndex];
|
||||||
int newChunk = chunk & ~maskBit.mask;
|
int newChunk = chunk & ~maskBit.mask;
|
||||||
if (chunk != newChunk)
|
if (chunk != newChunk)
|
||||||
{
|
{
|
||||||
@ -316,7 +316,7 @@ namespace DCFApixels.DragonECS
|
|||||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||||
private bool HasEntityComponent(int entityID, EcsMaskChunck maskBit)
|
private bool HasEntityComponent(int entityID, EcsMaskChunck maskBit)
|
||||||
{
|
{
|
||||||
return (_entityComponentMasks[(entityID << _entityComponentMaskLengthBitShift) + maskBit.chankIndex] & maskBit.mask) == maskBit.mask;
|
return (_entityComponentMasks[(entityID << _entityComponentMaskLengthBitShift) + maskBit.chunkIndex] & maskBit.mask) == maskBit.mask;
|
||||||
}
|
}
|
||||||
#endregion
|
#endregion
|
||||||
|
|
||||||
|
@ -48,7 +48,7 @@ namespace DCFApixels.DragonECS.Internal
|
|||||||
if (_lastWorldVersion != World.Version || _versionsChecker.NextEquals() == false)
|
if (_lastWorldVersion != World.Version || _versionsChecker.NextEquals() == false)
|
||||||
{
|
{
|
||||||
_version++;
|
_version++;
|
||||||
_filteredAllEntitiesCount = _iterator.Iterate(World.Entities).CopyTo(ref _filteredAllEntities);
|
_filteredAllEntitiesCount = _iterator.IterateTo(World.Entities, ref _filteredAllEntities);
|
||||||
}
|
}
|
||||||
_lastWorldVersion = World.Version;
|
_lastWorldVersion = World.Version;
|
||||||
}
|
}
|
||||||
@ -63,7 +63,7 @@ namespace DCFApixels.DragonECS.Internal
|
|||||||
{
|
{
|
||||||
_filteredEntities = new int[32];
|
_filteredEntities = new int[32];
|
||||||
}
|
}
|
||||||
_filteredEntitiesCount = _iterator.Iterate(span).CopyTo(ref _filteredEntities);
|
_filteredEntitiesCount = _iterator.IterateTo(span, ref _filteredEntities);
|
||||||
}
|
}
|
||||||
|
|
||||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||||
|
@ -49,7 +49,7 @@ namespace DCFApixels.DragonECS.Internal
|
|||||||
if (_lastWorldVersion != World.Version || _versionsChecker.NextEquals() == false)
|
if (_lastWorldVersion != World.Version || _versionsChecker.NextEquals() == false)
|
||||||
{
|
{
|
||||||
_version++;
|
_version++;
|
||||||
_iterator.Iterate(World.Entities).CopyTo(_filteredAllGroup);
|
_iterator.IterateTo(World.Entities, _filteredAllGroup);
|
||||||
}
|
}
|
||||||
_lastWorldVersion = World.Version;
|
_lastWorldVersion = World.Version;
|
||||||
}
|
}
|
||||||
@ -64,7 +64,7 @@ namespace DCFApixels.DragonECS.Internal
|
|||||||
{
|
{
|
||||||
_filteredGroup = EcsGroup.New(World);
|
_filteredGroup = EcsGroup.New(World);
|
||||||
}
|
}
|
||||||
_iterator.Iterate(span).CopyTo(_filteredGroup);
|
_iterator.IterateTo(span, _filteredGroup);
|
||||||
}
|
}
|
||||||
|
|
||||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||||
|
@ -4,11 +4,45 @@ using System.Collections.Generic;
|
|||||||
using System.Diagnostics;
|
using System.Diagnostics;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using System.Runtime.CompilerServices;
|
using System.Runtime.CompilerServices;
|
||||||
|
#if ENABLE_IL2CPP
|
||||||
|
using Unity.IL2CPP.CompilerServices;
|
||||||
|
#endif
|
||||||
|
|
||||||
namespace DCFApixels.DragonECS.Internal
|
namespace DCFApixels.DragonECS.Internal
|
||||||
{
|
{
|
||||||
#if ENABLE_IL2CPP
|
#if ENABLE_IL2CPP
|
||||||
using Unity.IL2CPP.CompilerServices;
|
[Il2CppSetOption (Option.NullChecks, false)]
|
||||||
|
[Il2CppSetOption(Option.ArrayBoundsChecks, false)]
|
||||||
|
#endif
|
||||||
|
public static unsafe class TempBuffer<T> where T : unmanaged
|
||||||
|
{
|
||||||
|
[ThreadStatic] private static T* _ptr;
|
||||||
|
[ThreadStatic] private static int _size;
|
||||||
|
|
||||||
|
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||||
|
public static T* Get(int size)
|
||||||
|
{
|
||||||
|
if (_size < size)
|
||||||
|
{
|
||||||
|
if (_ptr != null)
|
||||||
|
{
|
||||||
|
UnmanagedArrayUtility.Free(_ptr);
|
||||||
|
}
|
||||||
|
_ptr = UnmanagedArrayUtility.New<T>(size);
|
||||||
|
_size = size;
|
||||||
|
}
|
||||||
|
return _ptr;
|
||||||
|
}
|
||||||
|
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||||
|
public static void Clear()
|
||||||
|
{
|
||||||
|
for (int i = 0; i < _size; i++)
|
||||||
|
{
|
||||||
|
_ptr[i] = default;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#if ENABLE_IL2CPP
|
||||||
[Il2CppSetOption (Option.NullChecks, false)]
|
[Il2CppSetOption (Option.NullChecks, false)]
|
||||||
[Il2CppSetOption(Option.ArrayBoundsChecks, false)]
|
[Il2CppSetOption(Option.ArrayBoundsChecks, false)]
|
||||||
#endif
|
#endif
|
||||||
@ -19,6 +53,16 @@ namespace DCFApixels.DragonECS.Internal
|
|||||||
internal T* ptr;
|
internal T* ptr;
|
||||||
internal int Length;
|
internal int Length;
|
||||||
|
|
||||||
|
public static UnsafeArray<T> FromArray(T[] array)
|
||||||
|
{
|
||||||
|
UnsafeArray<T> result = new UnsafeArray<T>(array.Length);
|
||||||
|
for (int i = 0; i < array.Length; i++)
|
||||||
|
{
|
||||||
|
result.ptr[i] = array[i];
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||||
public UnsafeArray(int length)
|
public UnsafeArray(int length)
|
||||||
{
|
{
|
||||||
@ -49,6 +93,11 @@ namespace DCFApixels.DragonECS.Internal
|
|||||||
{
|
{
|
||||||
UnmanagedArrayUtility.Free(ref ptr, ref Length);
|
UnmanagedArrayUtility.Free(ref ptr, ref Length);
|
||||||
}
|
}
|
||||||
|
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||||
|
public void ReadonlyDispose()
|
||||||
|
{
|
||||||
|
UnmanagedArrayUtility.Free(ptr);
|
||||||
|
}
|
||||||
public override string ToString()
|
public override string ToString()
|
||||||
{
|
{
|
||||||
T* ptr = this.ptr;
|
T* ptr = this.ptr;
|
||||||
|
Loading…
Reference in New Issue
Block a user