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.

43 lines
1.4 KiB

using System;
using System.Runtime.InteropServices;
using gaemstone.Utility;
using static flecs_hub.flecs;
namespace gaemstone.ECS;
public static class ObserverExtensions
{
public static unsafe EntityRef InitObserver(this EntityRef entity,
FilterDesc filter, Action<Iterator> callback, params Entity[] events)
{
if (events.Length == 0) throw new ArgumentException("Must specify at least 1 event", nameof(events));
if (events.Length > 8) throw new ArgumentException("Must specify at most 8 events", nameof(events));
var world = entity.World;
using var alloc = TempAllocator.Use();
var desc = new ecs_observer_desc_t {
entity = entity,
filter = filter.ToFlecs(alloc),
binding_ctx = (void*)CallbackContextHelper.Create((world, callback)),
binding_ctx_free = new() { Data = new() { Pointer = &FreeContext } },
callback = new() { Data = new() { Pointer = &Callback } },
};
var span = desc.events;
for (var i = 0; i < events.Length; i++)
span[i] = events[i];
return new(world, new(ecs_observer_init(world, &desc)));
}
[UnmanagedCallersOnly]
private static unsafe void Callback(ecs_iter_t* iter)
{
var (world, callback) = CallbackContextHelper
.Get<(World, Action<Iterator>)>((nint)iter->binding_ctx);
callback(new Iterator(world, null, *iter));
}
[UnmanagedCallersOnly]
private static unsafe void FreeContext(void* context)
=> CallbackContextHelper.Free((nint)context);
}