mirror of
https://github.com/DCFApixels/DragonECS.git
synced 2025-09-18 18:14:37 +08:00
update
This commit is contained in:
parent
6f146cf555
commit
94dc9daa67
@ -2,6 +2,7 @@
|
|||||||
#undef DEBUG
|
#undef DEBUG
|
||||||
#endif
|
#endif
|
||||||
using DCFApixels.DragonECS.Core;
|
using DCFApixels.DragonECS.Core;
|
||||||
|
using DCFApixels.DragonECS.Core.Internal;
|
||||||
using DCFApixels.DragonECS.Internal;
|
using DCFApixels.DragonECS.Internal;
|
||||||
using System;
|
using System;
|
||||||
using System.Collections;
|
using System.Collections;
|
||||||
@ -113,26 +114,28 @@ namespace DCFApixels.DragonECS
|
|||||||
}
|
}
|
||||||
public static string ParseIDFromTypeName(string name)
|
public static string ParseIDFromTypeName(string name)
|
||||||
{
|
{
|
||||||
char* buffer = TempBuffer<char>.Get(name.Length);
|
using (StackAllocator.Alloc(name.Length, out char* buffer))
|
||||||
int count = 0;
|
|
||||||
//skip name[0] char
|
|
||||||
for (int i = 1, iMax = name.Length; i < iMax; i++)
|
|
||||||
{
|
{
|
||||||
char current = name[i];
|
int count = 0;
|
||||||
if (current == '_')
|
//skip name[0] char
|
||||||
|
for (int i = 1, iMax = name.Length; i < iMax; i++)
|
||||||
{
|
{
|
||||||
if (++i >= iMax) { break; }
|
char current = name[i];
|
||||||
current = name[i];
|
if (current == '_')
|
||||||
switch (current)
|
|
||||||
{
|
{
|
||||||
case '1': current = '<'; break;
|
if (++i >= iMax) { break; }
|
||||||
case '2': current = '>'; break;
|
current = name[i];
|
||||||
case '3': current = ','; break;
|
switch (current)
|
||||||
|
{
|
||||||
|
case '1': current = '<'; break;
|
||||||
|
case '2': current = '>'; break;
|
||||||
|
case '3': current = ','; break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
buffer[count++] = current;
|
||||||
}
|
}
|
||||||
buffer[count++] = current;
|
return new string(buffer, 0, count);
|
||||||
}
|
}
|
||||||
return new string(buffer, 0, count);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public static string GenerateNewUniqueIDWithAttribute()
|
public static string GenerateNewUniqueIDWithAttribute()
|
||||||
|
@ -601,7 +601,7 @@ namespace DCFApixels.DragonECS
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
preSortingBuffer = TempBuffer<EcsMaskChunck>.Get(maxBufferSize);
|
preSortingBuffer = TempBuffer<EcsMaskIterator, EcsMaskChunck>.Get(maxBufferSize);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (_sortIncChunckBuffer.Length > 1)
|
if (_sortIncChunckBuffer.Length > 1)
|
||||||
|
17
src/Internal/Allocators/AllocatorUtility.cs
Normal file
17
src/Internal/Allocators/AllocatorUtility.cs
Normal file
@ -0,0 +1,17 @@
|
|||||||
|
using System;
|
||||||
|
|
||||||
|
namespace DCFApixels.DragonECS.Core.Internal
|
||||||
|
{
|
||||||
|
internal static class AllocatorUtility
|
||||||
|
{
|
||||||
|
public static unsafe void ClearAllocatedMemory(IntPtr ptr, int startByte, int lengthInBytes)
|
||||||
|
{
|
||||||
|
ClearAllocatedMemory((byte*)ptr, startByte, lengthInBytes);
|
||||||
|
}
|
||||||
|
public static unsafe void ClearAllocatedMemory(byte* ptr, int startByte, int lengthInBytes)
|
||||||
|
{
|
||||||
|
Span<byte> memorySpan = new Span<byte>(ptr + startByte, lengthInBytes);
|
||||||
|
memorySpan.Clear();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -38,7 +38,7 @@ namespace DCFApixels.DragonECS.Core.Internal
|
|||||||
public static Handler AllocAndInit_Internal(int byteLength, Type type)
|
public static Handler AllocAndInit_Internal(int byteLength, Type type)
|
||||||
{
|
{
|
||||||
Handler handler = Alloc_Internal(byteLength, type);
|
Handler handler = Alloc_Internal(byteLength, type);
|
||||||
ClearAllocatedMemory(handler.Ptr, 0, byteLength);
|
AllocatorUtility.ClearAllocatedMemory(handler.Ptr, 0, byteLength);
|
||||||
return handler;
|
return handler;
|
||||||
}
|
}
|
||||||
#endregion
|
#endregion
|
||||||
@ -103,7 +103,7 @@ namespace DCFApixels.DragonECS.Core.Internal
|
|||||||
private static Handler ReallocAndInit_Internal(Handler target, int oldByteLength, int newByteLength, Type newType)
|
private static Handler ReallocAndInit_Internal(Handler target, int oldByteLength, int newByteLength, Type newType)
|
||||||
{
|
{
|
||||||
Handler handler = Realloc_Internal(target, newByteLength, newType);
|
Handler handler = Realloc_Internal(target, newByteLength, newType);
|
||||||
ClearAllocatedMemory(handler.Ptr, oldByteLength, newByteLength - oldByteLength);
|
AllocatorUtility.ClearAllocatedMemory(handler.Ptr, oldByteLength, newByteLength - oldByteLength);
|
||||||
return handler;
|
return handler;
|
||||||
}
|
}
|
||||||
#endregion
|
#endregion
|
||||||
@ -174,11 +174,7 @@ namespace DCFApixels.DragonECS.Core.Internal
|
|||||||
#endif
|
#endif
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
private static unsafe void ClearAllocatedMemory(IntPtr ptr, int startByte, int lengthInBytes)
|
|
||||||
{
|
|
||||||
Span<byte> memorySpan = new Span<byte>((byte*)ptr + startByte, lengthInBytes);
|
|
||||||
memorySpan.Clear();
|
|
||||||
}
|
|
||||||
internal struct Meta
|
internal struct Meta
|
||||||
{
|
{
|
||||||
#if DEBUG
|
#if DEBUG
|
||||||
@ -209,7 +205,7 @@ namespace DCFApixels.DragonECS.Core.Internal
|
|||||||
[System.Diagnostics.DebuggerDisplay("{DebuggerDisplay()}")]
|
[System.Diagnostics.DebuggerDisplay("{DebuggerDisplay()}")]
|
||||||
[System.Diagnostics.DebuggerTypeProxy(typeof(DebuggerProxy))]
|
[System.Diagnostics.DebuggerTypeProxy(typeof(DebuggerProxy))]
|
||||||
#endif
|
#endif
|
||||||
public readonly struct Handler
|
public readonly struct Handler : IDisposable
|
||||||
{
|
{
|
||||||
public static readonly Handler Empty = new Handler();
|
public static readonly Handler Empty = new Handler();
|
||||||
internal readonly Meta* Data; // Data[-1] is meta;
|
internal readonly Meta* Data; // Data[-1] is meta;
|
||||||
@ -238,6 +234,8 @@ namespace DCFApixels.DragonECS.Core.Internal
|
|||||||
public IntPtr Ptr { get { return (IntPtr)Data; } }
|
public IntPtr Ptr { get { return (IntPtr)Data; } }
|
||||||
public T* As<T>() where T : unmanaged { return (T*)Ptr; }
|
public T* As<T>() where T : unmanaged { return (T*)Ptr; }
|
||||||
|
|
||||||
|
void IDisposable.Dispose() { Free((void*)Ptr); }
|
||||||
|
|
||||||
#region Debugger
|
#region Debugger
|
||||||
#if DEBUG
|
#if DEBUG
|
||||||
#pragma warning disable IL3050 // Calling members annotated with 'RequiresDynamicCodeAttribute' may break functionality when AOT compiling.
|
#pragma warning disable IL3050 // Calling members annotated with 'RequiresDynamicCodeAttribute' may break functionality when AOT compiling.
|
249
src/Internal/Allocators/StackAllocator.cs
Normal file
249
src/Internal/Allocators/StackAllocator.cs
Normal file
@ -0,0 +1,249 @@
|
|||||||
|
#if DISABLE_DEBUG
|
||||||
|
#undef DEBUG
|
||||||
|
#endif
|
||||||
|
using DCFApixels.DragonECS.Internal;
|
||||||
|
using System;
|
||||||
|
using System.Runtime.CompilerServices;
|
||||||
|
using System.Runtime.InteropServices;
|
||||||
|
|
||||||
|
namespace DCFApixels.DragonECS.Core.Internal
|
||||||
|
{
|
||||||
|
internal unsafe class StackAllocator
|
||||||
|
{
|
||||||
|
[ThreadStatic]
|
||||||
|
private static MemoryAllocator.Handler _stackPtrHandler;
|
||||||
|
[ThreadStatic]
|
||||||
|
private static int _stackByteLength;
|
||||||
|
[ThreadStatic]
|
||||||
|
private static byte* _stackPtr;
|
||||||
|
[ThreadStatic]
|
||||||
|
private static int _currentByteLength;
|
||||||
|
[ThreadStatic]
|
||||||
|
private static byte* _currentPtr;
|
||||||
|
#if DEBUG
|
||||||
|
[ThreadStatic]
|
||||||
|
private static int _increment;
|
||||||
|
#endif
|
||||||
|
[ThreadStatic]
|
||||||
|
private static HandlerDebugInfo[] _debugInfos;
|
||||||
|
|
||||||
|
#region AllocAndInit
|
||||||
|
public static Handler AllocAndInit<T>(int count) where T : unmanaged
|
||||||
|
{
|
||||||
|
return AllocAndInit_Internal(Marshal.SizeOf<T>() * count, typeof(T));
|
||||||
|
}
|
||||||
|
public static Handler AllocAndInit(int byteLength)
|
||||||
|
{
|
||||||
|
return AllocAndInit_Internal(byteLength, null);
|
||||||
|
}
|
||||||
|
public static Handler AllocAndInit_Internal(int byteLength, Type type)
|
||||||
|
{
|
||||||
|
Handler handler = Alloc_Internal(byteLength, type);
|
||||||
|
AllocatorUtility.ClearAllocatedMemory(handler.Ptr, 0, byteLength);
|
||||||
|
return handler;
|
||||||
|
}
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
#region Alloc
|
||||||
|
/*
|
||||||
|
SAMPLE
|
||||||
|
using (StackAllocator.HybridAlloc(requiredSize, THRESHOLD, out SomeData* preSortingBuffer))
|
||||||
|
{
|
||||||
|
if (requiredSize < THRESHOLD)
|
||||||
|
{
|
||||||
|
SomeData* ptr = stackalloc SomeData[requiredSize];
|
||||||
|
preSortingBuffer = ptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
*/
|
||||||
|
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||||
|
public static Handler HybridAlloc<T>(int count, int threshold, out T* ptr) where T : unmanaged
|
||||||
|
{
|
||||||
|
if (count < threshold)
|
||||||
|
{
|
||||||
|
ptr = null;
|
||||||
|
return Handler.FromHandledPtr(_currentPtr);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return Alloc(count, out ptr);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||||
|
public static Handler Alloc<T>(int count, out T* ptr) where T : unmanaged
|
||||||
|
{
|
||||||
|
var handler = Alloc_Internal(Marshal.SizeOf<T>() * count, typeof(T));
|
||||||
|
ptr = handler.As<T>();
|
||||||
|
return handler;
|
||||||
|
}
|
||||||
|
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||||
|
public static Handler Alloc(int byteLength, out byte* ptr)
|
||||||
|
{
|
||||||
|
var handler = Alloc_Internal(byteLength, null);
|
||||||
|
ptr = handler.As<byte>();
|
||||||
|
return handler;
|
||||||
|
}
|
||||||
|
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||||
|
public static Handler Alloc_Internal(int byteLength, Type type)
|
||||||
|
{
|
||||||
|
byteLength = byteLength == 0 ? 1 : byteLength;
|
||||||
|
var requiredByteLength = byteLength + sizeof(Meta);
|
||||||
|
#if DEBUG
|
||||||
|
int id = _increment++;
|
||||||
|
#endif
|
||||||
|
if (_currentByteLength < requiredByteLength)
|
||||||
|
{
|
||||||
|
Upsize(requiredByteLength);
|
||||||
|
}
|
||||||
|
Meta* newHandledPtr = (Meta*)_currentPtr;
|
||||||
|
_currentPtr += requiredByteLength;
|
||||||
|
Handler handler = Handler.FromHandledPtr(newHandledPtr);
|
||||||
|
|
||||||
|
#if DEBUG
|
||||||
|
newHandledPtr->ID = id;
|
||||||
|
newHandledPtr->ByteLength = byteLength;
|
||||||
|
|
||||||
|
_debugInfos[id].stackTrace = new System.Diagnostics.StackTrace();
|
||||||
|
_debugInfos[id].type = type;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
return handler;
|
||||||
|
}
|
||||||
|
[MethodImpl(MethodImplOptions.NoInlining)]
|
||||||
|
private static void Upsize(int newSize)
|
||||||
|
{
|
||||||
|
if (_stackPtrHandler.IsEmpty)
|
||||||
|
{
|
||||||
|
_stackByteLength = Math.Max(512, ArrayUtility.NextPow2(newSize));
|
||||||
|
_stackPtrHandler = MemoryAllocator.Alloc<byte>(_stackByteLength);
|
||||||
|
_stackPtr = _stackPtrHandler.As<byte>();
|
||||||
|
_currentPtr = _stackPtr;
|
||||||
|
_currentByteLength = 0;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
var usedLength = _stackByteLength - _currentByteLength;
|
||||||
|
_stackByteLength = ArrayUtility.NextPow2(newSize + usedLength);
|
||||||
|
_stackPtrHandler = MemoryAllocator.Realloc<byte>(_stackPtrHandler, _stackByteLength);
|
||||||
|
_stackPtr = _stackPtrHandler.As<byte>();
|
||||||
|
_currentPtr = _stackPtr + usedLength;
|
||||||
|
_currentByteLength = _stackByteLength - usedLength;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
#region Free
|
||||||
|
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||||
|
public static void Free(ref Handler target)
|
||||||
|
{
|
||||||
|
Free_Internal(target.GetHandledPtr());
|
||||||
|
target = default;
|
||||||
|
}
|
||||||
|
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||||
|
public static void Free(void* dataPtr)
|
||||||
|
{
|
||||||
|
Free_Internal(((Meta*)dataPtr) - 1);
|
||||||
|
}
|
||||||
|
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||||
|
private static void Free_Internal(Meta* handledPtr)
|
||||||
|
{
|
||||||
|
#if DEBUG
|
||||||
|
if(handledPtr != _currentPtr) // Если значения одинаковые то это Handler из HybridAlloc, при условии что выделение памяти произошло в основном стеке, а не в StackAllocator
|
||||||
|
{
|
||||||
|
_increment--;
|
||||||
|
if (_increment-- != handledPtr->ID)
|
||||||
|
{
|
||||||
|
Throw.UndefinedException();
|
||||||
|
}
|
||||||
|
handledPtr->ID = default;
|
||||||
|
handledPtr->ByteLength = default;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
byte* ptr = (byte*)handledPtr;
|
||||||
|
long byteDifference = _currentPtr - ptr;
|
||||||
|
|
||||||
|
_currentPtr = ptr;
|
||||||
|
_currentByteLength += (int)byteDifference;
|
||||||
|
}
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
#region Other
|
||||||
|
internal struct Meta
|
||||||
|
{
|
||||||
|
#if DEBUG
|
||||||
|
public int ID;
|
||||||
|
public int ByteLength;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
#if DEBUG
|
||||||
|
[System.Diagnostics.DebuggerDisplay("{handler.DebuggerDisplay()}")]
|
||||||
|
#endif
|
||||||
|
internal struct HandlerDebugInfo
|
||||||
|
{
|
||||||
|
#if DEBUG
|
||||||
|
public System.Diagnostics.StackTrace stackTrace;
|
||||||
|
public Type type;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
|
||||||
|
public readonly struct Handler : IDisposable
|
||||||
|
{
|
||||||
|
public static Handler Empty => new Handler();
|
||||||
|
internal readonly Meta* Data; // Data[-1] is meta;
|
||||||
|
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||||
|
private Handler(Meta* dataPtr) { Data = dataPtr; }
|
||||||
|
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||||
|
public static Handler FromHandledPtr(void* ptr) { return new Handler(((Meta*)ptr) + 1); }
|
||||||
|
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||||
|
public static Handler FromDataPtr(void* ptr) { return new Handler((Meta*)ptr); }
|
||||||
|
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||||
|
internal Meta* GetHandledPtr() { return Data - 1; }
|
||||||
|
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||||
|
internal int GetID_Debug()
|
||||||
|
{
|
||||||
|
#if DEBUG
|
||||||
|
return GetHandledPtr()->ID;
|
||||||
|
#else
|
||||||
|
return 0;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||||
|
internal int GetByteLength_Debug()
|
||||||
|
{
|
||||||
|
#if DEBUG
|
||||||
|
return GetHandledPtr()->ByteLength;
|
||||||
|
#else
|
||||||
|
return 0;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
public bool IsEmpty
|
||||||
|
{
|
||||||
|
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||||
|
get { return Data == null; }
|
||||||
|
}
|
||||||
|
public IntPtr Ptr
|
||||||
|
{
|
||||||
|
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||||
|
get { return (IntPtr)Data; }
|
||||||
|
}
|
||||||
|
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||||
|
public T* As<T>() where T : unmanaged { return (T*)Ptr; }
|
||||||
|
|
||||||
|
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||||
|
void IDisposable.Dispose() { Free((void*)Ptr); }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
internal static class StackAllocatorHandlerExtensions
|
||||||
|
{
|
||||||
|
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||||
|
public static void Dispose(this ref StackAllocator.Handler self)
|
||||||
|
{
|
||||||
|
StackAllocator.Free(ref self);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
68
src/Internal/Allocators/TempBuffer.cs
Normal file
68
src/Internal/Allocators/TempBuffer.cs
Normal file
@ -0,0 +1,68 @@
|
|||||||
|
#if DISABLE_DEBUG
|
||||||
|
#undef DEBUG
|
||||||
|
#endif
|
||||||
|
using System;
|
||||||
|
using System.Runtime.CompilerServices;
|
||||||
|
using System.Runtime.InteropServices;
|
||||||
|
#if ENABLE_IL2CPP
|
||||||
|
using Unity.IL2CPP.CompilerServices;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
namespace DCFApixels.DragonECS.Core.Internal
|
||||||
|
{
|
||||||
|
#if ENABLE_IL2CPP
|
||||||
|
[Il2CppSetOption(Option.NullChecks, false)]
|
||||||
|
[Il2CppSetOption(Option.ArrayBoundsChecks, false)]
|
||||||
|
#endif
|
||||||
|
public static unsafe class TempBuffer<TContext, 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)
|
||||||
|
{
|
||||||
|
_ptr = TempBufferMemory<TContext>.Get<T>(size);
|
||||||
|
_size = size;
|
||||||
|
}
|
||||||
|
return _ptr;
|
||||||
|
}
|
||||||
|
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||||
|
public static void Clear()
|
||||||
|
{
|
||||||
|
TempBufferMemory<TContext>.Clear();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#if ENABLE_IL2CPP
|
||||||
|
[Il2CppSetOption(Option.NullChecks, false)]
|
||||||
|
[Il2CppSetOption(Option.ArrayBoundsChecks, false)]
|
||||||
|
#endif
|
||||||
|
internal static unsafe class TempBufferMemory<TContext>
|
||||||
|
{
|
||||||
|
[ThreadStatic] private static byte* _ptr;
|
||||||
|
[ThreadStatic] private static int _byteSize;
|
||||||
|
|
||||||
|
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||||
|
public static T* Get<T>(int size) where T : unmanaged
|
||||||
|
{
|
||||||
|
int byteSize = size * Marshal.SizeOf<T>();
|
||||||
|
if (_byteSize < byteSize)
|
||||||
|
{
|
||||||
|
if (_ptr != null)
|
||||||
|
{
|
||||||
|
MemoryAllocator.Free(_ptr);
|
||||||
|
}
|
||||||
|
_ptr = MemoryAllocator.Alloc<byte>(byteSize).As<byte>();
|
||||||
|
_byteSize = byteSize;
|
||||||
|
}
|
||||||
|
return (T*)_ptr;
|
||||||
|
}
|
||||||
|
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||||
|
public static void Clear()
|
||||||
|
{
|
||||||
|
AllocatorUtility.ClearAllocatedMemory(_ptr, 0, _byteSize);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -12,39 +12,6 @@ using Unity.IL2CPP.CompilerServices;
|
|||||||
|
|
||||||
namespace DCFApixels.DragonECS.Internal
|
namespace DCFApixels.DragonECS.Internal
|
||||||
{
|
{
|
||||||
#if ENABLE_IL2CPP
|
|
||||||
[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
|
#if ENABLE_IL2CPP
|
||||||
[Il2CppSetOption(Option.NullChecks, false)]
|
[Il2CppSetOption(Option.NullChecks, false)]
|
||||||
[Il2CppSetOption(Option.ArrayBoundsChecks, false)]
|
[Il2CppSetOption(Option.ArrayBoundsChecks, false)]
|
||||||
|
@ -1,4 +1,5 @@
|
|||||||
using DCFApixels.DragonECS.Internal;
|
using DCFApixels.DragonECS.Core.Internal;
|
||||||
|
using DCFApixels.DragonECS.Internal;
|
||||||
using System;
|
using System;
|
||||||
using System.Collections;
|
using System.Collections;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
@ -241,7 +242,7 @@ namespace DCFApixels.DragonECS.Core
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
var ptr = TempBuffer<VertexID>.Get(_count);
|
var ptr = TempBuffer<VertexID, VertexID>.Get(_count);
|
||||||
var buffer = UnsafeArray<VertexID>.Manual(ptr, _count);
|
var buffer = UnsafeArray<VertexID>.Manual(ptr, _count);
|
||||||
TopoSorting(buffer);
|
TopoSorting(buffer);
|
||||||
ReoderInsertionIndexes(buffer);
|
ReoderInsertionIndexes(buffer);
|
||||||
|
Loading…
Reference in New Issue
Block a user