mirror of
https://github.com/DCFApixels/DragonECS.git
synced 2025-09-18 01:44:35 +08:00
update
This commit is contained in:
parent
7652936e5b
commit
c569007e8f
193
src/EcsMask.cs
193
src/EcsMask.cs
@ -22,7 +22,6 @@ namespace DCFApixels.DragonECS
|
|||||||
{
|
{
|
||||||
using static EcsMaskIteratorUtility;
|
using static EcsMaskIteratorUtility;
|
||||||
|
|
||||||
|
|
||||||
#if ENABLE_IL2CPP
|
#if ENABLE_IL2CPP
|
||||||
[Il2CppSetOption (Option.NullChecks, false)]
|
[Il2CppSetOption (Option.NullChecks, false)]
|
||||||
[Il2CppSetOption(Option.ArrayBoundsChecks, false)]
|
[Il2CppSetOption(Option.ArrayBoundsChecks, false)]
|
||||||
@ -483,12 +482,19 @@ namespace DCFApixels.DragonECS
|
|||||||
#endif
|
#endif
|
||||||
public class EcsMaskIterator
|
public class EcsMaskIterator
|
||||||
{
|
{
|
||||||
|
// TODO есть идея перенести эти ChunckBuffer-ы в стек,
|
||||||
|
// для этого нужно проработать дизайн так чтобы память в стеке выделялась за пределами итератора и GetEnumerator,
|
||||||
|
// а далее передавались поинтеры, в противном случае использовался бы стандартный подход
|
||||||
|
|
||||||
public readonly EcsWorld World;
|
public readonly EcsWorld World;
|
||||||
public readonly EcsMask Mask;
|
public readonly EcsMask Mask;
|
||||||
|
|
||||||
private readonly UnsafeArray<int> _sortIncBuffer;
|
private readonly UnsafeArray<int> _sortIncBuffer;
|
||||||
|
/// <summary> slised _sortIncBuffer </summary>
|
||||||
private readonly UnsafeArray<int> _sortExcBuffer;
|
private readonly UnsafeArray<int> _sortExcBuffer;
|
||||||
|
|
||||||
private readonly UnsafeArray<EcsMaskChunck> _sortIncChunckBuffer;
|
private readonly UnsafeArray<EcsMaskChunck> _sortIncChunckBuffer;
|
||||||
|
/// <summary> slised _sortIncChunckBuffer </summary>
|
||||||
private readonly UnsafeArray<EcsMaskChunck> _sortExcChunckBuffer;
|
private readonly UnsafeArray<EcsMaskChunck> _sortExcChunckBuffer;
|
||||||
|
|
||||||
private readonly bool _isOnlyInc;
|
private readonly bool _isOnlyInc;
|
||||||
@ -498,21 +504,86 @@ namespace DCFApixels.DragonECS
|
|||||||
{
|
{
|
||||||
World = source;
|
World = source;
|
||||||
Mask = mask;
|
Mask = mask;
|
||||||
_sortIncBuffer = UnsafeArray<int>.FromArray(mask._incs);
|
|
||||||
_sortExcBuffer = UnsafeArray<int>.FromArray(mask._excs);
|
//_sortIncBuffer = UnsafeArray<int>.FromArray(mask._incs);
|
||||||
_sortIncChunckBuffer = UnsafeArray<EcsMaskChunck>.FromArray(mask._incChunckMasks);
|
//_sortExcBuffer = UnsafeArray<int>.FromArray(mask._excs);
|
||||||
_sortExcChunckBuffer = UnsafeArray<EcsMaskChunck>.FromArray(mask._excChunckMasks);
|
//_sortIncChunckBuffer = UnsafeArray<EcsMaskChunck>.FromArray(mask._incChunckMasks);
|
||||||
|
//_sortExcChunckBuffer = UnsafeArray<EcsMaskChunck>.FromArray(mask._excChunckMasks);
|
||||||
|
|
||||||
|
var sortBuffer = new UnsafeArray<int>(mask._incs.Length + mask._excs.Length);
|
||||||
|
var sortChunckBuffer = new UnsafeArray<EcsMaskChunck>(mask._incChunckMasks.Length + mask._excChunckMasks.Length);
|
||||||
|
|
||||||
|
_sortIncBuffer = sortBuffer.Slice(0, mask._incs.Length);
|
||||||
|
_sortIncBuffer.CopyFromArray_Unchecked(mask._incs);
|
||||||
|
_sortExcBuffer = sortBuffer.Slice(mask._incs.Length, mask._excs.Length);
|
||||||
|
_sortExcBuffer.CopyFromArray_Unchecked(mask._excs);
|
||||||
|
|
||||||
|
_sortIncChunckBuffer = sortChunckBuffer.Slice(0, mask._incChunckMasks.Length);
|
||||||
|
_sortIncChunckBuffer.CopyFromArray_Unchecked(mask._incChunckMasks);
|
||||||
|
_sortExcChunckBuffer = sortChunckBuffer.Slice(mask._incChunckMasks.Length, mask._excChunckMasks.Length);
|
||||||
|
_sortExcChunckBuffer.CopyFromArray_Unchecked(mask._excChunckMasks);
|
||||||
|
|
||||||
_isOnlyInc = _sortExcBuffer.Length <= 0;
|
_isOnlyInc = _sortExcBuffer.Length <= 0;
|
||||||
}
|
}
|
||||||
unsafe ~EcsMaskIterator()
|
unsafe ~EcsMaskIterator()
|
||||||
{
|
{
|
||||||
_sortIncBuffer.ReadonlyDispose();
|
_sortIncBuffer.ReadonlyDispose();
|
||||||
_sortExcBuffer.ReadonlyDispose();
|
//_sortExcBuffer.ReadonlyDispose();// использует общую памяять с _sortIncBuffer;
|
||||||
_sortIncChunckBuffer.ReadonlyDispose();
|
_sortIncChunckBuffer.ReadonlyDispose();
|
||||||
_sortExcChunckBuffer.ReadonlyDispose();
|
//_sortExcChunckBuffer.ReadonlyDispose();// использует общую памяять с _sortIncChunckBuffer;
|
||||||
}
|
}
|
||||||
#endregion
|
#endregion
|
||||||
|
|
||||||
|
#region SortConstraints
|
||||||
|
private unsafe int SortConstraints_Internal()
|
||||||
|
{
|
||||||
|
UnsafeArray<int> sortIncBuffer = _sortIncBuffer;
|
||||||
|
UnsafeArray<int> sortExcBuffer = _sortExcBuffer;
|
||||||
|
|
||||||
|
EcsWorld.PoolSlot[] counts = World._poolSlots;
|
||||||
|
int maxBufferSize = sortIncBuffer.Length > sortExcBuffer.Length ? sortIncBuffer.Length : sortExcBuffer.Length;
|
||||||
|
int maxEntites = int.MaxValue;
|
||||||
|
|
||||||
|
EcsMaskChunck* preSortingBuffer;
|
||||||
|
if (maxBufferSize > STACK_BUFFER_THRESHOLD)
|
||||||
|
{
|
||||||
|
preSortingBuffer = TempBuffer<EcsMaskChunck>.Get(maxBufferSize);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
EcsMaskChunck* ptr = stackalloc EcsMaskChunck[maxBufferSize];
|
||||||
|
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)
|
||||||
|
{
|
||||||
|
maxEntites = counts[_sortIncBuffer.ptr[0]].count;
|
||||||
|
if (maxEntites <= 0)
|
||||||
|
{
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (_sortExcChunckBuffer.Length > 1)
|
||||||
|
{
|
||||||
|
ExcCountComparer comparer = new ExcCountComparer(counts);
|
||||||
|
UnsafeArraySortHalperX<int>.InsertionSort(sortExcBuffer.ptr, sortExcBuffer.Length, ref comparer);
|
||||||
|
ConvertToChuncks(preSortingBuffer, sortExcBuffer, _sortExcChunckBuffer);
|
||||||
|
}
|
||||||
|
// Выражение мало IncCount < (AllEntitesCount - ExcCount) вероятно будет истинным.
|
||||||
|
// ExcCount = максимальное количество ентитей с исключеющим ограничением и IncCount = минимальоне количество ентитей с включающим ограничением
|
||||||
|
// Поэтому исключающее ограничение игнорируется для maxEntites.
|
||||||
|
|
||||||
|
return maxEntites;
|
||||||
|
}
|
||||||
|
#endregion
|
||||||
|
|
||||||
#region IterateTo
|
#region IterateTo
|
||||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||||
@ -598,7 +669,20 @@ namespace DCFApixels.DragonECS
|
|||||||
|
|
||||||
#region Enumerator
|
#region Enumerator
|
||||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||||
public Enumerator GetEnumerator() { return new Enumerator(_span, _iterator); }
|
public Enumerator GetEnumerator()
|
||||||
|
{
|
||||||
|
if (_iterator.Mask.IsBroken)
|
||||||
|
{
|
||||||
|
return new Enumerator(_span.Slice(0, 0), _iterator);
|
||||||
|
}
|
||||||
|
int maxEntities = _iterator.SortConstraints_Internal();
|
||||||
|
if (maxEntities <= 0)
|
||||||
|
{
|
||||||
|
return new Enumerator(_span.Slice(0, 0), _iterator);
|
||||||
|
}
|
||||||
|
return new Enumerator(_span, _iterator);
|
||||||
|
}
|
||||||
|
|
||||||
#if ENABLE_IL2CPP
|
#if ENABLE_IL2CPP
|
||||||
[Il2CppSetOption (Option.NullChecks, false)]
|
[Il2CppSetOption (Option.NullChecks, false)]
|
||||||
[Il2CppSetOption(Option.ArrayBoundsChecks, false)]
|
[Il2CppSetOption(Option.ArrayBoundsChecks, false)]
|
||||||
@ -621,49 +705,6 @@ namespace DCFApixels.DragonECS
|
|||||||
_entityComponentMasks = iterator.World._entityComponentMasks;
|
_entityComponentMasks = iterator.World._entityComponentMasks;
|
||||||
_entityComponentMaskLengthBitShift = iterator.World._entityComponentMaskLengthBitShift;
|
_entityComponentMaskLengthBitShift = iterator.World._entityComponentMaskLengthBitShift;
|
||||||
|
|
||||||
if (iterator.Mask.IsBroken)
|
|
||||||
{
|
|
||||||
_span = span.Slice(0, 0).GetEnumerator();
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
#region Sort
|
|
||||||
UnsafeArray<int> _sortIncBuffer = iterator._sortIncBuffer;
|
|
||||||
UnsafeArray<int> _sortExcBuffer = iterator._sortExcBuffer;
|
|
||||||
EcsWorld.PoolSlot[] counts = iterator.World._poolSlots;
|
|
||||||
int max = _sortIncBuffer.Length > _sortExcBuffer.Length ? _sortIncBuffer.Length : _sortExcBuffer.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;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (_sortExcChunckBuffer.Length > 1)
|
|
||||||
{
|
|
||||||
ExcCountComparer comparer = new ExcCountComparer(counts);
|
|
||||||
UnsafeArraySortHalperX<int>.InsertionSort(_sortExcBuffer.ptr, _sortExcBuffer.Length, ref comparer);
|
|
||||||
ConvertToChuncks(preSortingBuffer, _sortExcBuffer, _sortExcChunckBuffer);
|
|
||||||
}
|
|
||||||
#endregion
|
|
||||||
|
|
||||||
_span = span.GetEnumerator();
|
_span = span.GetEnumerator();
|
||||||
}
|
}
|
||||||
public int Current
|
public int Current
|
||||||
@ -761,7 +802,20 @@ namespace DCFApixels.DragonECS
|
|||||||
|
|
||||||
#region Enumerator
|
#region Enumerator
|
||||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||||
public Enumerator GetEnumerator() { return new Enumerator(_span, _iterator); }
|
public Enumerator GetEnumerator()
|
||||||
|
{
|
||||||
|
if (_iterator.Mask.IsBroken)
|
||||||
|
{
|
||||||
|
return new Enumerator(_span.Slice(0, 0), _iterator);
|
||||||
|
}
|
||||||
|
int maxEntities = _iterator.SortConstraints_Internal();
|
||||||
|
if (maxEntities <= 0)
|
||||||
|
{
|
||||||
|
return new Enumerator(_span.Slice(0, 0), _iterator);
|
||||||
|
}
|
||||||
|
return new Enumerator(_span, _iterator);
|
||||||
|
}
|
||||||
|
|
||||||
#if ENABLE_IL2CPP
|
#if ENABLE_IL2CPP
|
||||||
[Il2CppSetOption (Option.NullChecks, false)]
|
[Il2CppSetOption (Option.NullChecks, false)]
|
||||||
[Il2CppSetOption(Option.ArrayBoundsChecks, false)]
|
[Il2CppSetOption(Option.ArrayBoundsChecks, false)]
|
||||||
@ -782,41 +836,6 @@ namespace DCFApixels.DragonECS
|
|||||||
_entityComponentMasks = iterator.World._entityComponentMasks;
|
_entityComponentMasks = iterator.World._entityComponentMasks;
|
||||||
_entityComponentMaskLengthBitShift = iterator.World._entityComponentMaskLengthBitShift;
|
_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();
|
_span = span.GetEnumerator();
|
||||||
}
|
}
|
||||||
public int Current
|
public int Current
|
||||||
|
@ -32,25 +32,32 @@ namespace DCFApixels.DragonECS
|
|||||||
component = default;
|
component = default;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
internal readonly struct QueryCache<TExecutor, TAspcet> : IEcsWorldComponent<QueryCache<TExecutor, TAspcet>>
|
|
||||||
|
//TODO добавить сквозной кеш для инстансов TExecutor
|
||||||
|
//private readonly struct WhereCache<TExecutor> : IEcsWorldComponent<WhereCache<TExecutor>>
|
||||||
|
//{
|
||||||
|
// private readonly SparseArray<int, TExecutor> _pairs
|
||||||
|
//}
|
||||||
|
// Это не подохидт
|
||||||
|
internal readonly struct WhereQueryCache<TExecutor, TAspcet> : IEcsWorldComponent<WhereQueryCache<TExecutor, TAspcet>>
|
||||||
where TExecutor : EcsQueryExecutor, new()
|
where TExecutor : EcsQueryExecutor, new()
|
||||||
where TAspcet : EcsAspect, new()
|
where TAspcet : EcsAspect, new()
|
||||||
{
|
{
|
||||||
public readonly TExecutor Executor;
|
public readonly TExecutor Executor;
|
||||||
public readonly TAspcet Aspcet;
|
public readonly TAspcet Aspcet;
|
||||||
public QueryCache(TExecutor executor, TAspcet aspcet)
|
public WhereQueryCache(TExecutor executor, TAspcet aspcet)
|
||||||
{
|
{
|
||||||
Executor = executor;
|
Executor = executor;
|
||||||
Aspcet = aspcet;
|
Aspcet = aspcet;
|
||||||
}
|
}
|
||||||
void IEcsWorldComponent<QueryCache<TExecutor, TAspcet>>.Init(ref QueryCache<TExecutor, TAspcet> component, EcsWorld world)
|
void IEcsWorldComponent<WhereQueryCache<TExecutor, TAspcet>>.Init(ref WhereQueryCache<TExecutor, TAspcet> component, EcsWorld world)
|
||||||
{
|
{
|
||||||
TExecutor instance = new TExecutor();
|
TExecutor instance = new TExecutor();
|
||||||
TAspcet aspect = world.GetAspect<TAspcet>();
|
TAspcet aspect = world.GetAspect<TAspcet>();
|
||||||
instance.Initialize(world, aspect.Mask);
|
instance.Initialize(world, aspect.Mask);
|
||||||
component = new QueryCache<TExecutor, TAspcet>(instance, aspect);
|
component = new WhereQueryCache<TExecutor, TAspcet>(instance, aspect);
|
||||||
}
|
}
|
||||||
void IEcsWorldComponent<QueryCache<TExecutor, TAspcet>>.OnDestroy(ref QueryCache<TExecutor, TAspcet> component, EcsWorld world)
|
void IEcsWorldComponent<WhereQueryCache<TExecutor, TAspcet>>.OnDestroy(ref WhereQueryCache<TExecutor, TAspcet> component, EcsWorld world)
|
||||||
{
|
{
|
||||||
component = default;
|
component = default;
|
||||||
}
|
}
|
||||||
|
@ -234,7 +234,7 @@ namespace DCFApixels.DragonECS
|
|||||||
where TExecutor : EcsQueryExecutor, new()
|
where TExecutor : EcsQueryExecutor, new()
|
||||||
where TAspect : EcsAspect, new()
|
where TAspect : EcsAspect, new()
|
||||||
{
|
{
|
||||||
ref var cmp = ref Get<QueryCache<TExecutor, TAspect>>();
|
ref var cmp = ref Get<WhereQueryCache<TExecutor, TAspect>>();
|
||||||
executor = cmp.Executor;
|
executor = cmp.Executor;
|
||||||
aspect = cmp.Aspcet;
|
aspect = cmp.Aspcet;
|
||||||
}
|
}
|
||||||
|
@ -250,6 +250,8 @@ namespace DCFApixels.DragonECS.Internal
|
|||||||
new IntPtr(oldPointer),
|
new IntPtr(oldPointer),
|
||||||
new IntPtr(MetaCache<T>.Size * newCount))).ToPointer();
|
new IntPtr(MetaCache<T>.Size * newCount))).ToPointer();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public static class CollectionUtility
|
public static class CollectionUtility
|
||||||
|
@ -2,13 +2,15 @@
|
|||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
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
|
||||||
{
|
{
|
||||||
//TODO разработать возможность ручного устанавливания ID типам.
|
//TODO разработать возможность ручного устанавливания ID типам.
|
||||||
//это нужно для упрощения разработки сетевух
|
//это нужно для упрощения разработки сетевух
|
||||||
#if ENABLE_IL2CPP
|
#if ENABLE_IL2CPP
|
||||||
using Unity.IL2CPP.CompilerServices;
|
|
||||||
[Il2CppSetOption(Option.NullChecks, false)]
|
[Il2CppSetOption(Option.NullChecks, false)]
|
||||||
[Il2CppSetOption(Option.ArrayBoundsChecks, false)]
|
[Il2CppSetOption(Option.ArrayBoundsChecks, false)]
|
||||||
#endif
|
#endif
|
||||||
|
@ -2,7 +2,6 @@
|
|||||||
using System.Collections;
|
using System.Collections;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Diagnostics;
|
using System.Diagnostics;
|
||||||
using System.Linq;
|
|
||||||
using System.Runtime.CompilerServices;
|
using System.Runtime.CompilerServices;
|
||||||
#if ENABLE_IL2CPP
|
#if ENABLE_IL2CPP
|
||||||
using Unity.IL2CPP.CompilerServices;
|
using Unity.IL2CPP.CompilerServices;
|
||||||
@ -63,6 +62,8 @@ namespace DCFApixels.DragonECS.Internal
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||||
public UnsafeArray(int length)
|
public UnsafeArray(int length)
|
||||||
{
|
{
|
||||||
@ -82,6 +83,34 @@ namespace DCFApixels.DragonECS.Internal
|
|||||||
Length = length;
|
Length = length;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||||
|
public UnsafeArray<T> Slice(int start)
|
||||||
|
{
|
||||||
|
if ((uint)start > (uint)Length)
|
||||||
|
{
|
||||||
|
throw new ArgumentOutOfRangeException();
|
||||||
|
}
|
||||||
|
return new UnsafeArray<T>(ptr + start, Length - start);
|
||||||
|
}
|
||||||
|
|
||||||
|
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||||
|
public UnsafeArray<T> Slice(int start, int length)
|
||||||
|
{
|
||||||
|
if ((uint)start > (uint)Length || (uint)length > (uint)(Length - start))
|
||||||
|
{
|
||||||
|
throw new ArgumentOutOfRangeException();
|
||||||
|
}
|
||||||
|
return new UnsafeArray<T>(ptr + start, length);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void CopyFromArray_Unchecked(T[] array)
|
||||||
|
{
|
||||||
|
for (int i = 0; i < array.Length; i++)
|
||||||
|
{
|
||||||
|
ptr[i] = array[i];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||||
public UnsafeArray<T> Clone()
|
public UnsafeArray<T> Clone()
|
||||||
{
|
{
|
||||||
@ -101,7 +130,12 @@ namespace DCFApixels.DragonECS.Internal
|
|||||||
public override string ToString()
|
public override string ToString()
|
||||||
{
|
{
|
||||||
T* ptr = this.ptr;
|
T* ptr = this.ptr;
|
||||||
return CollectionUtility.AutoToString(EnumerableInt.Range(0, Length).Select(i => ptr[i]), "ua");
|
var elements = new T[Length];
|
||||||
|
for (int i = 0; i < Length; i++)
|
||||||
|
{
|
||||||
|
elements[i] = ptr[i];
|
||||||
|
}
|
||||||
|
return CollectionUtility.AutoToString(elements, "ua");
|
||||||
}
|
}
|
||||||
|
|
||||||
IEnumerator<T> IEnumerable<T>.GetEnumerator() { return GetEnumerator(); }
|
IEnumerator<T> IEnumerable<T>.GetEnumerator() { return GetEnumerator(); }
|
||||||
@ -139,8 +173,12 @@ namespace DCFApixels.DragonECS.Internal
|
|||||||
public int length;
|
public int length;
|
||||||
public DebuggerProxy(UnsafeArray<T> instance)
|
public DebuggerProxy(UnsafeArray<T> instance)
|
||||||
{
|
{
|
||||||
elements = EnumerableInt.Range(0, instance.Length).Select(i => instance.ptr[i]).ToArray();
|
|
||||||
length = instance.Length;
|
length = instance.Length;
|
||||||
|
elements = new T[length];
|
||||||
|
for (int i = 0; i < length; i++)
|
||||||
|
{
|
||||||
|
elements[i] = instance.ptr[i];
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user