2025-05-17 15:49:52 +08:00
#if DISABLE_DEBUG
#undef DEBUG
#endif
2025-05-17 14:55:31 +08:00
using System ;
2025-07-20 16:06:30 +08:00
using System.Collections.Generic ;
2026-03-16 21:52:45 +08:00
using System.Runtime.CompilerServices ;
2025-05-17 14:55:31 +08:00
using System.Runtime.InteropServices ;
namespace DCFApixels.DragonECS.Core.Internal
{
internal unsafe static class MemoryAllocator
{
2025-05-17 15:49:52 +08:00
#if DEBUG
2025-05-17 14:55:31 +08:00
private static IdDispenser _idDispenser ;
private static HandlerDebugInfo [ ] _debugInfos ;
2025-05-17 15:49:52 +08:00
#endif
2025-05-17 14:55:31 +08:00
static MemoryAllocator ( )
{
StaticInit ( ) ;
}
private static void StaticInit ( )
{
2025-05-17 15:49:52 +08:00
#if DEBUG
2025-05-17 14:55:31 +08:00
_idDispenser = new IdDispenser ( ) ;
_debugInfos = new HandlerDebugInfo [ 32 ] ;
2025-05-17 15:49:52 +08:00
#endif
2025-05-17 14:55:31 +08:00
}
#region AllocAndInit
2026-03-16 21:52:45 +08:00
public static HMem < T > AllocAndInit < T > ( int count ) where T : unmanaged
2025-05-17 14:55:31 +08:00
{
2026-03-16 21:52:45 +08:00
return new HMem < T > ( AllocAndInit_Internal ( Marshal . SizeOf < T > ( ) * count , typeof ( T ) ) , count ) ;
2025-05-17 14:55:31 +08:00
}
2026-03-16 21:52:45 +08:00
public static HMem < byte > AllocAndInit ( int byteLength )
2025-05-17 14:55:31 +08:00
{
2026-03-16 21:52:45 +08:00
return new HMem < byte > ( AllocAndInit_Internal ( byteLength , null ) , byteLength ) ;
2025-05-17 14:55:31 +08:00
}
public static Handler AllocAndInit_Internal ( int byteLength , Type type )
{
2025-05-17 15:49:52 +08:00
Handler handler = Alloc_Internal ( byteLength , type ) ;
2026-03-16 21:52:45 +08:00
AllocatorUtility . ClearAllocatedMemory ( handler . RawPtr , 0 , byteLength ) ;
2025-05-17 15:49:52 +08:00
return handler ;
2025-05-17 14:55:31 +08:00
}
#endregion
#region Alloc
2026-03-16 21:52:45 +08:00
public static HMem < T > Alloc < T > ( int count ) where T : unmanaged
2025-05-17 14:55:31 +08:00
{
2026-03-16 21:52:45 +08:00
return new HMem < T > ( Alloc_Internal ( Marshal . SizeOf < T > ( ) * count , typeof ( T ) ) , count ) ;
2025-05-17 14:55:31 +08:00
}
2026-03-16 21:52:45 +08:00
public static HMem < byte > Alloc ( int byteLength )
2025-05-17 14:55:31 +08:00
{
2026-03-16 21:52:45 +08:00
return new HMem < byte > ( Alloc_Internal ( byteLength , null ) , byteLength ) ; ;
2025-05-17 14:55:31 +08:00
}
public static Handler Alloc_Internal ( int byteLength , Type type )
{
byteLength = byteLength = = 0 ? 1 : byteLength ;
2025-05-17 15:49:52 +08:00
#if DEBUG
2025-05-17 14:55:31 +08:00
int id = 0 ;
lock ( _idDispenser )
{
if ( _debugInfos . Length < = _idDispenser . Count )
{
2025-08-26 14:50:36 +08:00
Array . Resize ( ref _debugInfos , ArrayUtility . NextPow2 ( _idDispenser . Count ) ) ;
2025-05-17 14:55:31 +08:00
}
id = _idDispenser . UseFree ( ) ;
}
2025-05-17 15:49:52 +08:00
#endif
2025-05-17 14:55:31 +08:00
Meta * newHandledPtr = ( Meta * ) Marshal . AllocHGlobal ( byteLength + sizeof ( Meta ) ) ;
2025-05-17 15:49:52 +08:00
Handler handler = Handler . FromHandledPtr ( newHandledPtr ) ;
2025-05-17 14:55:31 +08:00
2025-05-17 15:49:52 +08:00
#if DEBUG
2025-05-17 14:55:31 +08:00
newHandledPtr - > ID = id ;
newHandledPtr - > ByteLength = byteLength ;
2025-05-18 11:31:17 +08:00
#if DRAGONECS_DEEP_DEBUG
2025-05-17 16:22:05 +08:00
_debugInfos [ id ] . stackTrace = new System . Diagnostics . StackTrace ( ) ;
2025-05-18 11:31:17 +08:00
#endif
2025-05-17 14:55:31 +08:00
_debugInfos [ id ] . type = type ;
_debugInfos [ id ] . handler = handler ;
2025-05-17 15:49:52 +08:00
#endif
2025-05-17 14:55:31 +08:00
return handler ;
}
#endregion
#region ReallocAndInit
2026-03-17 15:34:31 +08:00
public static HMem < T > ReallocAndInit < T > ( T * target , int oldCount , int newCount ) where T : unmanaged
2025-05-17 14:55:31 +08:00
{
return ReallocAndInit < T > ( Handler . FromDataPtr ( target ) , oldCount , newCount ) ;
}
2026-03-16 21:52:45 +08:00
public static HMem < byte > ReallocAndInit ( void * target , int oldByteLength , int newByteLength )
2025-05-17 14:55:31 +08:00
{
return ReallocAndInit ( Handler . FromDataPtr ( target ) , oldByteLength , newByteLength ) ;
}
2026-03-16 21:52:45 +08:00
public static HMem < T > ReallocAndInit < T > ( HMem < T > target , int newCount ) where T : unmanaged
2025-05-17 14:55:31 +08:00
{
var size = Marshal . SizeOf < T > ( ) ;
2026-03-16 21:52:45 +08:00
return new HMem < T > ( ReallocAndInit_Internal ( target , size * target . Length , size * newCount , typeof ( T ) ) , newCount ) ;
2025-05-17 14:55:31 +08:00
}
2026-03-16 21:52:45 +08:00
public static HMem < T > ReallocAndInit < T > ( Handler target , int oldCount , int newCount ) where T : unmanaged
2025-05-17 14:55:31 +08:00
{
2026-03-16 21:52:45 +08:00
var size = Marshal . SizeOf < T > ( ) ;
return new HMem < T > ( ReallocAndInit_Internal ( target , size * oldCount , size * newCount , typeof ( T ) ) , newCount ) ;
}
public static HMem < byte > ReallocAndInit ( Handler target , int oldByteLength , int newByteLength )
{
return new HMem < byte > ( ReallocAndInit_Internal ( target , oldByteLength , newByteLength , null ) , newByteLength ) ;
2025-05-17 14:55:31 +08:00
}
private static Handler ReallocAndInit_Internal ( Handler target , int oldByteLength , int newByteLength , Type newType )
{
2025-05-17 15:49:52 +08:00
Handler handler = Realloc_Internal ( target , newByteLength , newType ) ;
2026-03-16 21:52:45 +08:00
AllocatorUtility . ClearAllocatedMemory ( handler . RawPtr , oldByteLength , newByteLength - oldByteLength ) ;
2025-05-17 15:49:52 +08:00
return handler ;
2025-05-17 14:55:31 +08:00
}
#endregion
#region Realloc
2026-03-17 15:34:31 +08:00
public static HMem < T > Realloc < T > ( T * target , int newCount ) where T : unmanaged
2025-07-20 16:06:30 +08:00
{
return Realloc < T > ( Handler . FromDataPtr ( target ) , Marshal . SizeOf < T > ( ) * newCount ) ;
}
2026-03-16 21:52:45 +08:00
public static HMem < byte > Realloc ( void * target , int newByteLength )
2025-07-20 16:06:30 +08:00
{
2026-03-16 21:52:45 +08:00
return new HMem < byte > ( Realloc ( Handler . FromDataPtr ( target ) , newByteLength ) , newByteLength ) ;
2025-07-20 16:06:30 +08:00
}
2026-03-16 21:52:45 +08:00
public static HMem < T > Realloc < T > ( Handler target , int newCount ) where T : unmanaged
2025-07-20 16:06:30 +08:00
{
2026-03-16 21:52:45 +08:00
return new HMem < T > ( Realloc_Internal ( target , Marshal . SizeOf < T > ( ) * newCount , typeof ( T ) ) , newCount ) ;
2025-05-17 14:55:31 +08:00
}
2026-03-16 21:52:45 +08:00
public static HMem < byte > Realloc ( Handler target , int newByteLength )
2025-05-17 14:55:31 +08:00
{
2026-03-16 21:52:45 +08:00
return new HMem < byte > ( Realloc_Internal ( target , newByteLength , null ) , newByteLength ) ;
2025-05-17 14:55:31 +08:00
}
private static Handler Realloc_Internal ( Handler target , int newByteLength , Type newType )
{
newByteLength = newByteLength = = 0 ? 1 : newByteLength ;
2026-03-16 21:52:45 +08:00
if ( target . IsCreated = = false )
{
return Alloc_Internal ( newByteLength , newType ) ;
}
#if DEBUG
int id = 0 ;
lock ( _idDispenser )
{
if ( _debugInfos . Length < = _idDispenser . Count )
{
Array . Resize ( ref _debugInfos , ArrayUtility . NextPow2 ( _idDispenser . Count ) ) ;
}
id = _idDispenser . UseFree ( ) ;
}
#endif
Meta * newHandledPtr = ( Meta * ) Marshal . ReAllocHGlobal (
2026-03-17 09:57:50 +08:00
( IntPtr ) target . GetHandledPtr ( ) ,
2026-03-16 21:52:45 +08:00
( IntPtr ) newByteLength + sizeof ( Meta ) ) ;
2025-05-17 15:49:52 +08:00
Handler handler = Handler . FromHandledPtr ( newHandledPtr ) ;
#if DEBUG
2026-03-16 21:52:45 +08:00
newHandledPtr - > ID = id ;
newHandledPtr - > ByteLength = newByteLength ;
2025-05-18 11:31:17 +08:00
#if DRAGONECS_DEEP_DEBUG
2025-05-17 16:22:05 +08:00
_debugInfos [ newHandledPtr - > ID ] . stackTrace = new System . Diagnostics . StackTrace ( ) ;
2025-05-18 11:31:17 +08:00
#endif
2025-05-17 14:55:31 +08:00
_debugInfos [ newHandledPtr - > ID ] . type = newType ;
2025-05-17 15:49:52 +08:00
_debugInfos [ newHandledPtr - > ID ] . handler = handler ;
#endif
return handler ;
2025-05-17 14:55:31 +08:00
}
#endregion
2026-03-16 21:52:45 +08:00
#region Clone
public static HMem < T > From < T > ( HMem < T > source )
where T : unmanaged
{
var result = Alloc < T > ( source . Length ) ;
source . AsSpan ( ) . CopyTo ( result . AsSpan ( ) ) ;
return result ;
}
public static HMem < T > From < T > ( T * ptr , int length )
where T : unmanaged
{
return From < T > ( new ReadOnlySpan < T > ( ptr , length ) ) ;
}
2026-03-16 23:18:00 +08:00
public static HMem < T > From < T > ( T [ ] source )
where T : unmanaged
{
return From ( new ReadOnlySpan < T > ( source ) ) ;
}
2026-03-16 21:52:45 +08:00
public static HMem < T > From < T > ( ReadOnlySpan < T > source )
where T : unmanaged
{
var result = Alloc < T > ( source . Length ) ;
source . CopyTo ( result . AsSpan ( ) ) ;
return result ;
}
#endregion
2025-05-17 14:55:31 +08:00
#region Free
2025-05-21 17:41:28 +08:00
public static void Free ( Handler target )
{
Free_Internal ( target . GetHandledPtr ( ) ) ;
}
2026-03-16 21:52:45 +08:00
public static void FreeAndClear < T > ( ref HMem < T > target )
where T : unmanaged
{
Free_Internal ( target . Handler . GetHandledPtr ( ) ) ;
target = default ;
}
2025-05-21 17:41:28 +08:00
public static void FreeAndClear ( ref Handler target )
2025-05-17 14:55:31 +08:00
{
Free_Internal ( target . GetHandledPtr ( ) ) ;
target = default ;
}
public static void Free ( void * dataPtr )
{
Free_Internal ( ( ( Meta * ) dataPtr ) - 1 ) ;
}
private static void Free_Internal ( Meta * handledPtr )
{
2025-05-17 15:49:52 +08:00
#if DEBUG
2026-03-16 21:52:45 +08:00
if ( handledPtr = = null )
{
throw new ArgumentNullException ( ) ;
}
2025-05-17 14:55:31 +08:00
lock ( _idDispenser )
{
_idDispenser . Release ( handledPtr - > ID ) ;
_debugInfos [ handledPtr - > ID ] = default ;
}
handledPtr - > ID = default ;
handledPtr - > ByteLength = default ;
2025-05-17 15:49:52 +08:00
#endif
2025-05-17 14:55:31 +08:00
Marshal . FreeHGlobal ( ( IntPtr ) handledPtr ) ;
}
#endregion
#region Other
internal static StateDebugInfo GetHandlerInfos_Debug ( )
{
StateDebugInfo result = default ;
2025-05-17 15:49:52 +08:00
#if DEBUG
2025-05-17 14:55:31 +08:00
result . idDispenser = _idDispenser ;
result . debugInfos = _debugInfos ;
2025-05-17 15:49:52 +08:00
#endif
2025-05-17 14:55:31 +08:00
return result ;
}
2025-05-18 00:49:12 +08:00
2025-05-17 14:55:31 +08:00
internal struct Meta
{
2025-05-17 15:49:52 +08:00
#if DEBUG
2025-05-17 14:55:31 +08:00
public int ID ;
public int ByteLength ;
2025-05-17 15:49:52 +08:00
#endif
2025-05-17 14:55:31 +08:00
}
#if DEBUG
2025-05-17 16:22:05 +08:00
[System.Diagnostics.DebuggerDisplay("{handler.DebuggerDisplay()}")]
2025-05-17 14:55:31 +08:00
#endif
internal struct HandlerDebugInfo
{
2025-05-17 15:49:52 +08:00
#if DEBUG
2025-05-18 11:31:17 +08:00
#if DRAGONECS_DEEP_DEBUG
2025-05-17 16:22:05 +08:00
public System . Diagnostics . StackTrace stackTrace ;
2025-05-18 11:31:17 +08:00
#endif
2025-05-17 14:55:31 +08:00
public Type type ;
public Handler handler ;
2025-05-17 15:49:52 +08:00
#endif
2025-05-17 14:55:31 +08:00
}
internal struct StateDebugInfo
{
public HandlerDebugInfo [ ] debugInfos ;
public IdDispenser idDispenser ;
}
#endregion
2026-03-16 21:52:45 +08:00
public readonly struct HMem < T > : IDisposable , IEquatable < HMem < T > >
where T : unmanaged
{
public readonly T * Ptr ;
public readonly int Length ;
2026-03-17 10:27:48 +08:00
[MethodImpl(MethodImplOptions.AggressiveInlining)]
2026-03-16 21:52:45 +08:00
internal HMem ( Handler handler , int length )
{
Ptr = handler . As < T > ( ) ;
Length = length ;
}
public bool IsCreated
{
[MethodImpl(MethodImplOptions.AggressiveInlining)]
get { return Ptr ! = null ; }
}
public IntPtr RawPtr
{
[MethodImpl(MethodImplOptions.AggressiveInlining)]
get { return new IntPtr ( Ptr ) ; }
}
public Handler Handler
{
[MethodImpl(MethodImplOptions.AggressiveInlining)]
get { return Handler . FromDataPtr ( Ptr ) ; }
}
2026-03-17 10:27:48 +08:00
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public HMem < U > As < U > ( ) where U : unmanaged
2026-03-16 21:52:45 +08:00
{
if ( IsCreated )
{
return default ;
}
long totalBytes = ( long ) Length * sizeof ( T ) ;
long newLengthLong = totalBytes / sizeof ( U ) ;
#if DEBUG
if ( totalBytes % sizeof ( U ) ! = 0 )
{
throw new InvalidOperationException ( $"Cannot cast Memory<{typeof(T).Name}> to Memory<{typeof(U).Name}> because the size of the underlying memory ({totalBytes} bytes) is not a multiple of the size of {typeof(U).Name} ({sizeof(U)} bytes)." ) ;
}
if ( newLengthLong > int . MaxValue )
{
throw new InvalidOperationException ( $"Resulting length ({newLengthLong}) exceeds int.MaxValue." ) ;
}
#endif
return new HMem < U > ( Handler , ( int ) newLengthLong ) ;
}
public void Dispose ( )
{
Handler . Dispose ( ) ;
}
2026-03-17 09:57:50 +08:00
#if DEBUG
2026-03-17 10:27:48 +08:00
public override string ToString ( ) { return Handler . DebuggerDisplay ( ) ; }
2026-03-17 09:57:50 +08:00
#endif
2026-03-16 21:52:45 +08:00
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public override int GetHashCode ( ) { return RawPtr . GetHashCode ( ) ; }
public override bool Equals ( object obj ) { return obj is Handler h & & h = = this ; }
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public bool Equals ( HMem < T > other ) { return other . Ptr = = Ptr ; }
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static bool operator = = ( HMem < T > a , HMem < T > b ) { return a . Ptr = = b . Ptr ; }
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static bool operator ! = ( HMem < T > a , HMem < T > b ) { return a . Ptr ! = b . Ptr ; }
2026-03-17 10:27:48 +08:00
[MethodImpl(MethodImplOptions.AggressiveInlining)]
2026-03-16 21:52:45 +08:00
public Span < T > AsSpan ( ) { return new Span < T > ( Ptr , Length ) ; }
2026-03-17 10:27:48 +08:00
[MethodImpl(MethodImplOptions.AggressiveInlining)]
2026-03-16 21:52:45 +08:00
public Span < T > AsSpan ( int length )
{
#if DEBUG
if ( length > Length ) { Throw . UndefinedException ( ) ; }
#endif
return new Span < T > ( Ptr , length ) ;
}
2026-03-17 10:27:48 +08:00
[MethodImpl(MethodImplOptions.AggressiveInlining)]
2026-03-16 21:52:45 +08:00
public static implicit operator Handler ( HMem < T > memory ) { return memory . Handler ; }
}
2025-05-17 14:55:31 +08:00
#if DEBUG
2025-05-17 16:22:05 +08:00
[System.Diagnostics.DebuggerDisplay("{DebuggerDisplay()}")]
[System.Diagnostics.DebuggerTypeProxy(typeof(DebuggerProxy))]
2025-05-17 14:55:31 +08:00
#endif
2026-03-16 21:52:45 +08:00
public readonly struct Handler : IDisposable , IEquatable < Handler >
2025-05-17 14:55:31 +08:00
{
public static readonly Handler Empty = new Handler ( ) ;
internal readonly Meta * Data ; // Data[-1] is meta;
private Handler ( Meta * dataPtr ) { Data = dataPtr ; }
public static Handler FromHandledPtr ( void * ptr ) { return new Handler ( ( ( Meta * ) ptr ) + 1 ) ; }
public static Handler FromDataPtr ( void * ptr ) { return new Handler ( ( Meta * ) ptr ) ; }
internal Meta * GetHandledPtr ( ) { return Data - 1 ; }
2025-05-18 10:52:24 +08:00
internal int GetID_Debug ( )
2025-05-17 15:49:52 +08:00
{
#if DEBUG
2025-05-18 10:52:24 +08:00
return GetHandledPtr ( ) - > ID ;
2025-05-17 15:49:52 +08:00
#else
return 0 ;
#endif
}
2025-05-18 10:52:24 +08:00
internal int GetByteLength_Debug ( )
2025-05-17 15:49:52 +08:00
{
#if DEBUG
2025-05-18 10:52:24 +08:00
return GetHandledPtr ( ) - > ByteLength ;
2025-05-17 15:49:52 +08:00
#else
return 0 ;
#endif
}
2025-05-17 14:55:31 +08:00
2026-03-16 21:52:45 +08:00
public bool IsCreated
{
[MethodImpl(MethodImplOptions.AggressiveInlining)]
get { return Data ! = null ; }
}
public IntPtr RawPtr
{
[MethodImpl(MethodImplOptions.AggressiveInlining)]
get { return ( IntPtr ) Data ; }
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public T * As < T > ( ) where T : unmanaged { return ( T * ) RawPtr ; }
public void Dispose ( ) { Free ( ( void * ) RawPtr ) ; }
2025-05-17 14:55:31 +08:00
2026-03-17 09:57:50 +08:00
#if DEBUG
2026-03-16 21:52:45 +08:00
public override string ToString ( ) { return DebuggerDisplay ( ) ; }
2026-03-17 09:57:50 +08:00
#endif
2026-03-16 21:52:45 +08:00
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public override int GetHashCode ( ) { return RawPtr . GetHashCode ( ) ; }
public override bool Equals ( object obj ) { return obj is Handler h & & h = = this ; }
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public bool Equals ( Handler other ) { return other . Data = = Data ; }
2025-05-17 14:55:31 +08:00
2026-03-16 21:52:45 +08:00
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static bool operator = = ( Handler a , Handler b ) { return a . Data = = b . Data ; }
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static bool operator ! = ( Handler a , Handler b ) { return a . Data ! = b . Data ; }
2025-05-18 00:49:12 +08:00
2025-05-17 14:55:31 +08:00
#region Debugger
#if DEBUG
2025-05-17 15:24:07 +08:00
#pragma warning disable IL3050 // Calling members annotated with 'RequiresDynamicCodeAttribute' may break functionality when AOT compiling.
2026-03-16 21:52:45 +08:00
internal string DebuggerDisplay ( )
2025-05-17 14:55:31 +08:00
{
2025-05-18 10:52:24 +08:00
if ( Data = = null )
2025-05-17 14:55:31 +08:00
{
return "-" ;
}
Meta meta = GetHandledPtr ( ) [ 0 ] ;
HandlerDebugInfo info = _debugInfos [ meta . ID ] ;
if ( info . type = = null )
{
return $"Count: {meta.ByteLength} Unknown" ;
}
return $"Count: {meta.ByteLength / Marshal.SizeOf(info.type)} {info.type.Name}" ;
}
internal static Array CreateArray_Debug ( Type type , int count , byte * data , int byteLength )
{
var array = Array . CreateInstance ( type , count ) ;
if ( array . Length > 0 )
{
Union union = default ;
union . array = array ;
fixed ( byte * arrayPtr = union . bytes )
{
for ( int i = 0 ; i < byteLength ; i + + )
{
arrayPtr [ i ] = data [ i ] ;
}
}
}
return array ;
}
2026-03-16 21:52:45 +08:00
2025-05-17 14:55:31 +08:00
[StructLayout(LayoutKind.Explicit)]
private unsafe struct Union
{
[FieldOffset(0)]
public Array array ;
[FieldOffset(0)]
public byte [ ] bytes ;
}
private class DebuggerProxy
{
private byte * _data ;
private Type _type ;
private int _count ;
public bool IsAlive ;
public Meta Meta ;
public HandlerDebugInfo DebugInfo ;
public Array Data ;
public HandlerDebugInfo [ ] OtherHandlersInfo ;
2026-03-16 21:52:45 +08:00
public DebuggerProxy ( Handler handler )
2025-05-17 14:55:31 +08:00
{
2026-03-16 21:52:45 +08:00
IsAlive = handler . RawPtr . ToPointer ( ) ! = null ;
2025-05-17 14:55:31 +08:00
if ( IsAlive = = false ) { return ; }
Meta = handler . GetHandledPtr ( ) [ 0 ] ;
2026-03-16 21:52:45 +08:00
_data = ( byte * ) handler . RawPtr ;
2025-05-17 14:55:31 +08:00
DebugInfo = _debugInfos [ Meta . ID ] ;
if ( DebugInfo . type = = null )
{
_type = typeof ( byte ) ;
}
else
{
_type = DebugInfo . type ;
}
var size = Marshal . SizeOf ( _type ) ;
_count = Meta . ByteLength / size ;
Data = CreateArray_Debug ( _type , _count , _data , Meta . ByteLength ) ;
OtherHandlersInfo = _debugInfos ;
}
}
2025-05-17 15:24:07 +08:00
#pragma warning restore IL3050 // Calling members annotated with 'RequiresDynamicCodeAttribute' may break functionality when AOT compiling.
2025-05-17 14:55:31 +08:00
#endif
#endregion
}
}
2025-07-20 16:06:30 +08:00
internal ref struct AllocBuilder
{
//[ThreadStatic]
//private static Stack<AllocBuilder> _buildersPool;
//private AllocBuilder() { }
//public static AllocBuilder New()
//{
// if (_buildersPool == null) { _buildersPool = new Stack<AllocBuilder>(4); }
// if(_buildersPool.TryPop(out var result) == false)
// {
// result = new AllocBuilder();
// }
// return result;
//}
public static AllocBuilder New ( )
{
return new AllocBuilder ( 0 ) ;
}
private int _byteLength ;
private AllocBuilder ( int byteLength )
{
_byteLength = byteLength ;
}
public void Add < T > ( int count ) where T : unmanaged
{
Add ( Marshal . SizeOf < T > ( ) ) ;
}
public void Add ( int byteLength )
{
_byteLength + = byteLength ;
}
public MemoryAllocator . Handler Alloc ( )
{
return MemoryAllocator . Alloc ( _byteLength ) ;
}
public MemoryAllocator . Handler Realloc ( MemoryAllocator . Handler handler )
{
return MemoryAllocator . Realloc ( handler , _byteLength ) ;
}
}
2025-05-17 14:55:31 +08:00
internal static class MemoryAllocatorHandlerExtensions
{
2026-03-16 21:52:45 +08:00
public static void DisposeAndReset ( this ref MemoryAllocator . Handler self )
2025-05-17 14:55:31 +08:00
{
2025-05-21 17:41:28 +08:00
MemoryAllocator . FreeAndClear ( ref self ) ;
2025-05-17 14:55:31 +08:00
}
2026-03-16 21:52:45 +08:00
public static void DisposeAndReset < T > ( this ref MemoryAllocator . HMem < T > self )
where T : unmanaged
{
self . Dispose ( ) ;
self = default ;
}
2025-05-17 14:55:31 +08:00
}
}