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, Entity @event, FilterDesc filter, Action callback) { 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 } }, }; desc.events[0] = @event; 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)>((nint)iter->binding_ctx); callback(new Iterator(world, null, *iter)); } [UnmanagedCallersOnly] private static unsafe void FreeContext(void* context) => CallbackContextHelper.Free((nint)context); }