Skip to content

Commit

Permalink
Rewrite binding context invokers to UnmanagedCallersOnly and change G…
Browse files Browse the repository at this point in the history
…roupBy, GroupCreate, GroupDelete, AtFini, PostFrame callback signatures
  • Loading branch information
BeanCheeseBurrito committed Oct 12, 2024
1 parent 775b4ee commit 1157d03
Show file tree
Hide file tree
Showing 36 changed files with 1,226 additions and 992 deletions.
4 changes: 2 additions & 2 deletions src/Flecs.NET.Codegen/Generators/BindingContext.cs
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ public static string GenerateFunctions(int i)
internal static void {{callback}}(ecs_iter_t* iter)
{
{{(Generator.GetCallbackIsRun(callback) ? "RunContext" : "IteratorContext")}}* context = ({{(Generator.GetCallbackIsRun(callback) ? "RunContext" : "IteratorContext")}}*)iter->{{(Generator.GetCallbackIsRun(callback) ? "run_ctx" : "callback_ctx")}};
Invoker.{{Generator.GetInvokerName(callback)}}(iter, ({{Generator.GetCallbackType(callback, i)}}){{(Generator.GetCallbackIsDelegate(callback) ? "context->Callback.GcHandle.Target!" : "context->Callback.Pointer")}});
Invoker.{{Generator.GetInvokerName(callback)}}(iter, ({{Generator.GetCallbackType(callback, i)}}){{(Generator.GetCallbackIsDelegate(callback) ? "context->Callback.Delegate.Target!" : "context->Callback.Pointer")}});
}
""");

Expand All @@ -48,7 +48,7 @@ internal static unsafe partial class Functions<{{Generator.TypeParameters[i]}}>
public static string GeneratePointers(int i)
{
IEnumerable<string> pointers = Generator.CallbacksRunAndIterAndEach.Select((Callback callback) => $$"""
internal static readonly IntPtr {{callback}} = (IntPtr)(delegate* <ecs_iter_t*, void>)&Functions<{{Generator.TypeParameters[i]}}>.{{callback}};
internal static readonly nint {{callback}} = (nint)(delegate* <ecs_iter_t*, void>)&Functions<{{Generator.TypeParameters[i]}}>.{{callback}};
""");

return $$"""
Expand Down
2 changes: 1 addition & 1 deletion src/Flecs.NET.Codegen/Generators/NodeBuilder.cs
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ public static string GenerateExtensions(Type builderType, Type returnType, int i
{
{{Generator.GetTypeName(Type.TypeHelper, i)}}.AssertReferenceTypes({{(Generator.GetCallbackIsUnmanaged(callback) ? "false" : "true")}});
{{Generator.GetTypeName(Type.TypeHelper, i)}}.AssertSparseTypes(World, {{(Generator.GetCallbackIsIter(callback) ? "false" : "true")}});
return {{(Generator.GetCallbackIsRun(callback) ? "SetRun" : "SetCallback")}}({{(Generator.GetCallbackIsDelegate(callback) ? string.Empty : "(IntPtr)")}}callback, Pointers<{{Generator.TypeParameters[i]}}>.{{callback}}).Build();
return {{(Generator.GetCallbackIsRun(callback) ? "SetRun" : "SetCallback")}}({{(Generator.GetCallbackIsDelegate(callback) ? string.Empty : "(nint)")}}callback, Pointers<{{Generator.TypeParameters[i]}}>.{{callback}}).Build();
}
""");

Expand Down
8 changes: 4 additions & 4 deletions src/Flecs.NET.Codegen/Generators/ObserverBuilder.cs
Original file line number Diff line number Diff line change
Expand Up @@ -147,25 +147,25 @@ public void Dispose()
return ref this;
}
private ref {{Generator.GetTypeName(Type.ObserverBuilder, i)}} SetCallback<T>(T callback, IntPtr invoker) where T : Delegate
private ref {{Generator.GetTypeName(Type.ObserverBuilder, i)}} SetCallback<T>(T callback, nint invoker) where T : Delegate
{
_observerBuilder.SetCallback(callback, invoker);
return ref this;
}
private ref {{Generator.GetTypeName(Type.ObserverBuilder, i)}} SetCallback(IntPtr callback, IntPtr invoker)
private ref {{Generator.GetTypeName(Type.ObserverBuilder, i)}} SetCallback(nint callback, nint invoker)
{
_observerBuilder.SetCallback(callback, invoker);
return ref this;
}
private ref {{Generator.GetTypeName(Type.ObserverBuilder, i)}} SetRun<T>(T callback, IntPtr invoker) where T : Delegate
private ref {{Generator.GetTypeName(Type.ObserverBuilder, i)}} SetRun<T>(T callback, nint invoker) where T : Delegate
{
_observerBuilder.SetRun(callback, invoker);
return ref this;
}
private ref {{Generator.GetTypeName(Type.ObserverBuilder, i)}} SetRun(IntPtr callback, IntPtr invoker)
private ref {{Generator.GetTypeName(Type.ObserverBuilder, i)}} SetRun(nint callback, nint invoker)
{
_observerBuilder.SetRun(callback, invoker);
return ref this;
Expand Down
6 changes: 3 additions & 3 deletions src/Flecs.NET.Codegen/Generators/Query.cs
Original file line number Diff line number Diff line change
Expand Up @@ -99,10 +99,10 @@ public bool Changed()
return _query.GroupInfo(groupId);
}
/// <inheritdoc cref="Query.GroupCtx(ulong)"/>
public void* GroupCtx(ulong groupId)
/// <inheritdoc cref="Query.GroupCtx{T}(ulong)"/>
public ref T GroupCtx<T>(ulong group)
{
return _query.GroupCtx(groupId);
return ref _query.GroupCtx<T>(group);
}
/// <inheritdoc cref="Query.EachTerm(Ecs.TermCallback)"/>
Expand Down
54 changes: 20 additions & 34 deletions src/Flecs.NET.Codegen/Generators/QueryBuilder.cs
Original file line number Diff line number Diff line change
Expand Up @@ -1038,17 +1038,17 @@ public unsafe partial struct {{Generator.GetTypeName(type, i)}}
return ref this;
}
/// <inheritdoc cref="Core.QueryBuilder.OrderBy(ulong, Ecs.OrderByAction)"/>
public ref {{Generator.GetTypeName(type, i)}} OrderBy(ulong component, Ecs.OrderByAction compare)
/// <inheritdoc cref="Core.QueryBuilder.OrderBy(ulong, Ecs.OrderByCallback)"/>
public ref {{Generator.GetTypeName(type, i)}} OrderBy(ulong component, Ecs.OrderByCallback callback)
{
Ecs.GetQueryBuilder(ref this).OrderBy(component, compare);
Ecs.GetQueryBuilder(ref this).OrderBy(component, callback);
return ref this;
}
/// <inheritdoc cref="Core.QueryBuilder.OrderBy{T}(Ecs.OrderByAction)"/>
public ref {{Generator.GetTypeName(type, i)}} OrderBy<T>(Ecs.OrderByAction compare)
/// <inheritdoc cref="Core.QueryBuilder.OrderBy{T}(Ecs.OrderByCallback)"/>
public ref {{Generator.GetTypeName(type, i)}} OrderBy<T>(Ecs.OrderByCallback callback)
{
Ecs.GetQueryBuilder(ref this).OrderBy<T>(compare);
Ecs.GetQueryBuilder(ref this).OrderBy<T>(callback);
return ref this;
}
Expand All @@ -1066,20 +1066,6 @@ public unsafe partial struct {{Generator.GetTypeName(type, i)}}
return ref this;
}
/// <inheritdoc cref="Core.QueryBuilder.GroupBy(ulong, Ecs.GroupByAction)"/>
public ref {{Generator.GetTypeName(type, i)}} GroupBy(ulong component, Ecs.GroupByAction callback)
{
Ecs.GetQueryBuilder(ref this).GroupBy(component, callback);
return ref this;
}
/// <inheritdoc cref="Core.QueryBuilder.GroupBy{T}(Ecs.GroupByAction)"/>
public ref {{Generator.GetTypeName(type, i)}} GroupBy<T>(Ecs.GroupByAction callback)
{
Ecs.GetQueryBuilder(ref this).GroupBy<T>(callback);
return ref this;
}
/// <inheritdoc cref="Core.QueryBuilder.GroupBy(ulong, Ecs.GroupByCallback)"/>
public ref {{Generator.GetTypeName(type, i)}} GroupBy(ulong component, Ecs.GroupByCallback callback)
{
Expand All @@ -1094,31 +1080,31 @@ public unsafe partial struct {{Generator.GetTypeName(type, i)}}
return ref this;
}
///
public ref {{Generator.GetTypeName(type, i)}} GroupByCtx(void* ctx, Ecs.ContextFree contextFree)
/// <inheritdoc cref="Core.QueryBuilder.OnGroupCreate(Ecs.GroupCreateCallback)"/>
public ref {{Generator.GetTypeName(type, i)}} OnGroupCreate(Ecs.GroupCreateCallback callback)
{
Ecs.GetQueryBuilder(ref this).GroupByCtx(ctx, contextFree);
Ecs.GetQueryBuilder(ref this).OnGroupCreate(callback);
return ref this;
}
///
public ref {{Generator.GetTypeName(type, i)}} GroupByCtx(void* ctx)
/// <inheritdoc cref="Core.QueryBuilder.OnGroupCreate{T}(Ecs.GroupCreateCallback{T})"/>
public ref {{Generator.GetTypeName(type, i)}} OnGroupCreate<T>(Ecs.GroupCreateCallback<T> callback)
{
Ecs.GetQueryBuilder(ref this).GroupByCtx(ctx);
Ecs.GetQueryBuilder(ref this).OnGroupCreate(callback);
return ref this;
}
/// <inheritdoc cref="Core.QueryBuilder.OnGroupCreate(Ecs.GroupCreateAction)"/>
public ref {{Generator.GetTypeName(type, i)}} OnGroupCreate(Ecs.GroupCreateAction onGroupCreate)
/// <inheritdoc cref="Core.QueryBuilder.OnGroupDelete(Ecs.GroupDeleteCallback)"/>
public ref {{Generator.GetTypeName(type, i)}} OnGroupDelete(Ecs.GroupDeleteCallback callback)
{
Ecs.GetQueryBuilder(ref this).OnGroupCreate(onGroupCreate);
Ecs.GetQueryBuilder(ref this).OnGroupDelete(callback);
return ref this;
}
/// <inheritdoc cref="Core.QueryBuilder.OnGroupDelete(Ecs.GroupDeleteAction)"/>
public ref {{Generator.GetTypeName(type, i)}} OnGroupDelete(Ecs.GroupDeleteAction onGroupDelete)
/// <inheritdoc cref="Core.QueryBuilder.OnGroupDelete{T}(Ecs.GroupDeleteCallback{T})"/>
public ref {{Generator.GetTypeName(type, i)}} OnGroupDelete<T>(Ecs.GroupDeleteCallback<T> callback)
{
Ecs.GetQueryBuilder(ref this).OnGroupDelete(onGroupDelete);
Ecs.GetQueryBuilder(ref this).OnGroupDelete(callback);
return ref this;
}
}
Expand Down
8 changes: 4 additions & 4 deletions src/Flecs.NET.Codegen/Generators/SystemBuilder.cs
Original file line number Diff line number Diff line change
Expand Up @@ -196,25 +196,25 @@ public void Dispose()
return ref this;
}
internal ref {{Generator.GetTypeName(Type.SystemBuilder, i)}} SetCallback<T>(T callback, IntPtr invoker) where T : Delegate
internal ref {{Generator.GetTypeName(Type.SystemBuilder, i)}} SetCallback<T>(T callback, nint invoker) where T : Delegate
{
_systemBuilder.SetCallback(callback, invoker);
return ref this;
}
internal ref {{Generator.GetTypeName(Type.SystemBuilder, i)}} SetCallback(IntPtr callback, IntPtr invoker)
internal ref {{Generator.GetTypeName(Type.SystemBuilder, i)}} SetCallback(nint callback, nint invoker)
{
_systemBuilder.SetCallback(callback, invoker);
return ref this;
}
internal ref {{Generator.GetTypeName(Type.SystemBuilder, i)}} SetRun<T>(T callback, IntPtr invoker) where T : Delegate
internal ref {{Generator.GetTypeName(Type.SystemBuilder, i)}} SetRun<T>(T callback, nint invoker) where T : Delegate
{
_systemBuilder.SetRun(callback, invoker);
return ref this;
}
internal ref {{Generator.GetTypeName(Type.SystemBuilder, i)}} SetRun(IntPtr callback, IntPtr invoker)
internal ref {{Generator.GetTypeName(Type.SystemBuilder, i)}} SetRun(nint callback, nint invoker)
{
_systemBuilder.SetRun(callback, invoker);
return ref this;
Expand Down
36 changes: 12 additions & 24 deletions src/Flecs.NET.Examples/Queries/GroupByCallbacks.cs
Original file line number Diff line number Diff line change
Expand Up @@ -41,32 +41,20 @@ public static void Main()
// Grouped query
using Query<Position> q = world.QueryBuilder<Position>()
.GroupBy<Group>()
// Callback invoked when a new group is created
.OnGroupCreate((
flecs.ecs_world_t* world,
ulong id, // id of the group that was created
void* groupByArg) => // group_by_ctx parameter in ecs_query_desc_t struct
// Callback invoked when a new group is created. Including the third "out T" parameter
// allows you to provide a user context.
.OnGroupCreate((World world, ulong id, out GroupCtx ctx) =>
{
World w = new(world);
Console.WriteLine($"Group {w.Entity(id)} created");
Console.WriteLine($"Group {world.Entity(id)} created");

// Return data that will be associated with the group
GroupCtx* ctx = (GroupCtx*)NativeMemory.AllocZeroed((nuint)sizeof(GroupCtx));
ctx->Counter = ++groupCounter;
return ctx;
// Set data that will be associated with the group
ctx = new GroupCtx(++groupCounter);
})
// Callback invoked when a group is deleted
.OnGroupDelete((
flecs.ecs_world_t* world,
ulong id, // id of the group that was deleted
void* ctx, // group context
void* groupByArg) => // group_by_ctx parameter in ecs_query_desc_t struct
// Callback invoked when a group is deleted. Including the third "ref T" parameter
// provides access to the user context object.
.OnGroupDelete((World world, ulong id, ref GroupCtx ctx) =>
{
World w = new(world);
Console.WriteLine($"Group {w.Entity(id)} deleted");

// Free data associated with group
NativeMemory.Free(ctx);
Console.WriteLine($"Group {world.Entity(id)} deleted");
})
.Build();

Expand Down Expand Up @@ -109,10 +97,10 @@ public static void Main()
Field<Position> p = it.Field<Position>(0);

Entity group = it.World().Entity(it.GroupId());
GroupCtx* ctx = (GroupCtx*)q.GroupCtx(group);
ref GroupCtx ctx = ref it.Query().GroupCtx<GroupCtx>(group);

Console.WriteLine($" - Group {group.Path()}: table [{it.Table().Str()}]");
Console.WriteLine($" Counter: {ctx->Counter}");
Console.WriteLine($" Counter: {ctx.Counter}");

foreach (int i in it)
Console.WriteLine($" ({p[i].X}, {p[i].Y})");
Expand Down
2 changes: 1 addition & 1 deletion src/Flecs.NET.Examples/Queries/GroupByCustom.cs
Original file line number Diff line number Diff line change
Expand Up @@ -84,7 +84,7 @@ public static void Main()
});
}

private static ulong GroupByRelation(World world, Table table, Entity id)
private static ulong GroupByRelation(World world, Table table, ulong id)
{
if (table.Search(id, Ecs.Wildcard, out Id match) != -1)
return match.Second();
Expand Down
20 changes: 10 additions & 10 deletions src/Flecs.NET.Tests/CSharp/Core/QueryBuilderTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -15,21 +15,21 @@ private void GroupBy()
world.Component<Tag0>();
world.Component<Tag1>();
world.Component<Tag2>();
world.Component<Tag23>();
world.Component<Tag3>();

using Query q = world.QueryBuilder()
.With<Tag23>()
.GroupBy<Tag23>(GroupByFirstId)
.With<Tag3>()
.GroupBy<Tag3>(GroupByFirstId)
.Build();

using Query qReverse = world.QueryBuilder()
.With<Tag23>()
.GroupBy<Tag23>(GroupByFirstIdNegated)
.With<Tag3>()
.GroupBy<Tag3>(GroupByFirstIdNegated)
.Build();

Entity e3 = world.Entity().Add<Tag23>().Add<Tag2>();
Entity e2 = world.Entity().Add<Tag23>().Add<Tag1>();
Entity e1 = world.Entity().Add<Tag23>().Add<Tag0>();
Entity e3 = world.Entity().Add<Tag3>().Add<Tag2>();
Entity e2 = world.Entity().Add<Tag3>().Add<Tag1>();
Entity e1 = world.Entity().Add<Tag3>().Add<Tag0>();

int count = 0;
q.Iter((Iter it) =>
Expand Down Expand Up @@ -70,13 +70,13 @@ private void GroupBy()

return;

static ulong GroupByFirstId(World world, Table table, Entity id)
static ulong GroupByFirstId(World world, Table table, ulong id)
{
Types type = table.Type();
return type.Get(0);
}

static ulong GroupByFirstIdNegated(World world, Table table, Entity id)
static ulong GroupByFirstIdNegated(World world, Table table, ulong id)
{
return ~GroupByFirstId(world, table, id);
}
Expand Down
Loading

0 comments on commit 1157d03

Please sign in to comment.