|
|
|
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<TContext> InitSystem<TContext>(this Entity<TContext> entity,
|
|
|
|
QueryDesc query, Action<Iterator<TContext>> 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<Action<nint>>((nint)iter->binding_ctx)
|
|
|
|
.Invoke((nint)iter);
|
|
|
|
|
|
|
|
[UnmanagedCallersOnly]
|
|
|
|
private static unsafe void FreeContext(void* context)
|
|
|
|
=> CallbackContextHelper.Free((nint)context);
|
|
|
|
}
|