Alternative managed wrapper around flecs-cs bindings for using the ECS framework Flecs in modern .NET.
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

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();
}
}
}