using System; using System.Runtime.InteropServices; using gaemstone.ECS.Utility; using static flecs_hub.flecs; namespace gaemstone.ECS; public static class SystemExtensions { public static unsafe Entity InitSystem(this Entity entity, QueryDesc query, Action> callback) { var world = entity.World; var internalCallback = (nint iter) => callback(new((ecs_iter_t*)iter)); using var alloc = TempAllocator.Use(); var desc = new ecs_system_desc_t { entity = entity, query = query.ToFlecs(alloc), binding_ctx = (void*)CallbackContextHelper.Create(internalCallback), binding_ctx_free = new() { Data = new() { Pointer = &FreeContext } }, callback = new() { Data = new() { Pointer = &Callback } }, }; if (ecs_system_init(world, &desc).Data == default) throw new InvalidOperationException(); return entity; } [UnmanagedCallersOnly] private static unsafe void Callback(ecs_iter_t* iter) => CallbackContextHelper .Get>((nint)iter->binding_ctx) .Invoke((nint)iter); [UnmanagedCallersOnly] private static unsafe void FreeContext(void* context) => CallbackContextHelper.Free((nint)context); }