You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
71 lines
1.7 KiB
71 lines
1.7 KiB
using System; |
|
using System.Runtime.InteropServices; |
|
using static flecs_hub.flecs; |
|
|
|
namespace gaemstone.ECS.Utility; |
|
|
|
public unsafe readonly struct ReferenceHandle |
|
: IDisposable |
|
{ |
|
public static int NumActiveHandles { get; private set; } |
|
|
|
|
|
private readonly nint _value; |
|
|
|
public object? Target => (_value != default) |
|
? ((GCHandle)_value).Target : null; |
|
|
|
private ReferenceHandle(nint value) |
|
=> _value = value; |
|
|
|
public static ReferenceHandle Alloc(object? target) |
|
{ |
|
if (target == null) return default; |
|
NumActiveHandles++; |
|
return new((nint)GCHandle.Alloc(target)); |
|
} |
|
|
|
public ReferenceHandle Clone() |
|
=> Alloc(Target); |
|
|
|
public void Dispose() |
|
{ |
|
if (_value == default) return; |
|
NumActiveHandles--; |
|
((GCHandle)_value).Free(); |
|
} |
|
|
|
|
|
[UnmanagedCallersOnly] |
|
internal static void Construct(void* ptr, int count, ecs_type_info_t* _) |
|
=> new Span<ReferenceHandle>(ptr, count).Clear(); |
|
|
|
[UnmanagedCallersOnly] |
|
internal static void Destruct(void* ptr, int count, ecs_type_info_t* _) |
|
{ |
|
var span = new Span<ReferenceHandle>(ptr, count); |
|
foreach (var handle in span) handle.Dispose(); |
|
span.Clear(); |
|
} |
|
|
|
[UnmanagedCallersOnly] |
|
internal static void Move(void* dstPtr, void* srcPtr, int count, ecs_type_info_t* _) |
|
{ |
|
var dst = new Span<ReferenceHandle>(dstPtr, count); |
|
var src = new Span<ReferenceHandle>(srcPtr, count); |
|
foreach (var handle in dst) handle.Dispose(); |
|
src.CopyTo(dst); |
|
src.Clear(); |
|
} |
|
|
|
[UnmanagedCallersOnly] |
|
internal static void Copy(void* dstPtr, void* srcPtr, int count, ecs_type_info_t* _) |
|
{ |
|
var dst = new Span<ReferenceHandle>(dstPtr, count); |
|
var src = new Span<ReferenceHandle>(srcPtr, count); |
|
for (var i = 0; i < count; i++) { |
|
dst[i].Dispose(); |
|
dst[i] = src[i].Clone(); |
|
} |
|
} |
|
}
|
|
|