diff --git a/Sia/Components/ Delegates/ComponentFilter.cs b/Sia/Components/ Delegates/ComponentFilter.cs new file mode 100644 index 0000000..f723270 --- /dev/null +++ b/Sia/Components/ Delegates/ComponentFilter.cs @@ -0,0 +1,15 @@ +namespace Sia; + +public delegate bool ComponentFilter(ref C1 c1); +public delegate bool ComponentFilter(ref C1 c1, ref C2 c2); +public delegate bool ComponentFilter(ref C1 c1, ref C2 c2, ref C3 c3); +public delegate bool ComponentFilter(ref C1 c1, ref C2 c2, ref C3 c3, ref C4 c4); +public delegate bool ComponentFilter(ref C1 c1, ref C2 c2, ref C3 c3, ref C4 c4, ref C5 c5); +public delegate bool ComponentFilter(ref C1 c1, ref C2 c2, ref C3 c3, ref C4 c4, ref C5 c5, ref C6 c6); + +public delegate bool DataComponentFilter(in TData data, ref C1 c1); +public delegate bool DataComponentFilter(in TData data, ref C1 c1, ref C2 c2); +public delegate bool DataComponentFilter(in TData data, ref C1 c1, ref C2 c2, ref C3 c3); +public delegate bool DataComponentFilter(in TData data, ref C1 c1, ref C2 c2, ref C3 c3, ref C4 c4); +public delegate bool DataComponentFilter(in TData data, ref C1 c1, ref C2 c2, ref C3 c3, ref C4 c4, ref C5 c5); +public delegate bool DataComponentFilter(in TData data, ref C1 c1, ref C2 c2, ref C3 c3, ref C4 c4, ref C5 c5, ref C6 c6); \ No newline at end of file diff --git a/Sia/Entities/Extensions/EntityHostExtensions.ForEach.cs b/Sia/Entities/Extensions/EntityHostExtensions.ForEach.cs index 1204c6a..7a1b066 100644 --- a/Sia/Entities/Extensions/EntityHostExtensions.ForEach.cs +++ b/Sia/Entities/Extensions/EntityHostExtensions.ForEach.cs @@ -517,4 +517,488 @@ public unsafe static void ForSliceOnParallel( #endregion // ParallelRunner #endregion // ComponentHandler + + #region ComponentFilter + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public unsafe static void Filter( + this IEntityHost host, ComponentFilter filter, EntityHandler handler, TRunner runner) + where TRunner : IRunner + => host.Handle((filter, handler), + static (IEntityHost host, in (ComponentFilter, EntityHandler) fs, int from, int to) => { + var desc = host.Descriptor; + var slots = host.AllocatedSlots; + var (filter, handler) = fs; + + var c1Offset = desc.GetOffset(); + + for (int i = from; i != to; ++i) { + ref readonly var slot = ref slots[i]; + ref var byteRef = ref host.UnsafeGetByteRef(slot); + + if (filter(ref Unsafe.As(ref Unsafe.AddByteOffset(ref byteRef, c1Offset)))) { + handler(new(slot, host)); + } + } + }, runner); + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public unsafe static void Filter( + this IEntityHost host, ComponentFilter filter, EntityHandler handler, TRunner runner) + where TRunner : IRunner + => host.Handle((filter, handler), + static (IEntityHost host, in (ComponentFilter, EntityHandler) fs, int from, int to) => { + var desc = host.Descriptor; + var slots = host.AllocatedSlots; + var (filter, handler) = fs; + + var c1Offset = desc.GetOffset(); + var c2Offset = desc.GetOffset(); + + for (int i = from; i != to; ++i) { + ref readonly var slot = ref slots[i]; + ref var byteRef = ref host.UnsafeGetByteRef(slot); + + if (filter( + ref Unsafe.As(ref Unsafe.AddByteOffset(ref byteRef, c1Offset)), + ref Unsafe.As(ref Unsafe.AddByteOffset(ref byteRef, c2Offset)))) { + handler(new(slot, host)); + } + } + }, runner); + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public unsafe static void Filter( + this IEntityHost host, ComponentFilter filter, EntityHandler handler, TRunner runner) + where TRunner : IRunner + => host.Handle((filter, handler), + static (IEntityHost host, in (ComponentFilter, EntityHandler) fs, int from, int to) => { + var desc = host.Descriptor; + var slots = host.AllocatedSlots; + var (filter, handler) = fs; + + var c1Offset = desc.GetOffset(); + var c2Offset = desc.GetOffset(); + var c3Offset = desc.GetOffset(); + + for (int i = from; i != to; ++i) { + ref readonly var slot = ref slots[i]; + ref var byteRef = ref host.UnsafeGetByteRef(slot); + + if (filter( + ref Unsafe.As(ref Unsafe.AddByteOffset(ref byteRef, c1Offset)), + ref Unsafe.As(ref Unsafe.AddByteOffset(ref byteRef, c2Offset)), + ref Unsafe.As(ref Unsafe.AddByteOffset(ref byteRef, c3Offset)))) { + handler(new(slot, host)); + } + } + }, runner); + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public unsafe static void Filter( + this IEntityHost host, ComponentFilter filter, EntityHandler handler, TRunner runner) + where TRunner : IRunner + => host.Handle((filter, handler), + static (IEntityHost host, in (ComponentFilter, EntityHandler) fs, int from, int to) => { + var desc = host.Descriptor; + var slots = host.AllocatedSlots; + var (filter, handler) = fs; + + var c1Offset = desc.GetOffset(); + var c2Offset = desc.GetOffset(); + var c3Offset = desc.GetOffset(); + var c4Offset = desc.GetOffset(); + + for (int i = from; i != to; ++i) { + ref readonly var slot = ref slots[i]; + ref var byteRef = ref host.UnsafeGetByteRef(slot); + + if (filter( + ref Unsafe.As(ref Unsafe.AddByteOffset(ref byteRef, c1Offset)), + ref Unsafe.As(ref Unsafe.AddByteOffset(ref byteRef, c2Offset)), + ref Unsafe.As(ref Unsafe.AddByteOffset(ref byteRef, c3Offset)), + ref Unsafe.As(ref Unsafe.AddByteOffset(ref byteRef, c4Offset)))) { + handler(new(slot, host)); + } + } + }, runner); + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public unsafe static void Filter( + this IEntityHost host, ComponentFilter filter, EntityHandler handler, TRunner runner) + where TRunner : IRunner + => host.Handle((filter, handler), + static (IEntityHost host, in (ComponentFilter, EntityHandler) fs, int from, int to) => { + var desc = host.Descriptor; + var slots = host.AllocatedSlots; + var (filter, handler) = fs; + + var c1Offset = desc.GetOffset(); + var c2Offset = desc.GetOffset(); + var c3Offset = desc.GetOffset(); + var c4Offset = desc.GetOffset(); + var c5Offset = desc.GetOffset(); + + for (int i = from; i != to; ++i) { + ref readonly var slot = ref slots[i]; + ref var byteRef = ref host.UnsafeGetByteRef(slot); + + if (filter( + ref Unsafe.As(ref Unsafe.AddByteOffset(ref byteRef, c1Offset)), + ref Unsafe.As(ref Unsafe.AddByteOffset(ref byteRef, c2Offset)), + ref Unsafe.As(ref Unsafe.AddByteOffset(ref byteRef, c3Offset)), + ref Unsafe.As(ref Unsafe.AddByteOffset(ref byteRef, c4Offset)), + ref Unsafe.As(ref Unsafe.AddByteOffset(ref byteRef, c5Offset)))) { + handler(new(slot, host)); + } + } + }, runner); + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public unsafe static void Filter( + this IEntityHost host, ComponentFilter filter, EntityHandler handler, TRunner runner) + where TRunner : IRunner + => host.Handle((filter, handler), + static (IEntityHost host, in (ComponentFilter, EntityHandler) fs, int from, int to) => { + var desc = host.Descriptor; + var slots = host.AllocatedSlots; + var (filter, handler) = fs; + + var c1Offset = desc.GetOffset(); + var c2Offset = desc.GetOffset(); + var c3Offset = desc.GetOffset(); + var c4Offset = desc.GetOffset(); + var c5Offset = desc.GetOffset(); + var c6Offset = desc.GetOffset(); + + for (int i = from; i != to; ++i) { + ref readonly var slot = ref slots[i]; + ref var byteRef = ref host.UnsafeGetByteRef(slot); + + if (filter( + ref Unsafe.As(ref Unsafe.AddByteOffset(ref byteRef, c1Offset)), + ref Unsafe.As(ref Unsafe.AddByteOffset(ref byteRef, c2Offset)), + ref Unsafe.As(ref Unsafe.AddByteOffset(ref byteRef, c3Offset)), + ref Unsafe.As(ref Unsafe.AddByteOffset(ref byteRef, c4Offset)), + ref Unsafe.As(ref Unsafe.AddByteOffset(ref byteRef, c5Offset)), + ref Unsafe.As(ref Unsafe.AddByteOffset(ref byteRef, c6Offset)))) { + handler(new(slot, host)); + } + } + }, runner); + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public unsafe static void Filter( + this IEntityHost host, in TData userData, DataComponentFilter filter, EntityHandler handler, TRunner runner) + where TRunner : IRunner + => host.Handle((filter, handler, userData), + static (IEntityHost host, in (DataComponentFilter, EntityHandler, TData) data, int from, int to) => { + var desc = host.Descriptor; + var slots = host.AllocatedSlots; + + var c1Offset = desc.GetOffset(); + + var filter = data.Item1; + var handler = data.Item2; + ref readonly var userData = ref data.Item3; + + for (int i = from; i != to; ++i) { + ref readonly var slot = ref slots[i]; + ref var byteRef = ref host.UnsafeGetByteRef(slot); + + if (filter(userData, ref Unsafe.As(ref Unsafe.AddByteOffset(ref byteRef, c1Offset)))) { + handler(userData, new(slot, host)); + } + } + }, runner); + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public unsafe static void Filter( + this IEntityHost host, in TData userData, DataComponentFilter filter, EntityHandler handler, TRunner runner) + where TRunner : IRunner + => host.Handle((filter, handler, userData), + static (IEntityHost host, in (DataComponentFilter, EntityHandler, TData) data, int from, int to) => { + var desc = host.Descriptor; + var slots = host.AllocatedSlots; + + var c1Offset = desc.GetOffset(); + var c2Offset = desc.GetOffset(); + + var filter = data.Item1; + var handler = data.Item2; + ref readonly var userData = ref data.Item3; + + for (int i = from; i != to; ++i) { + ref readonly var slot = ref slots[i]; + ref var byteRef = ref host.UnsafeGetByteRef(slot); + + if (filter(userData, + ref Unsafe.As(ref Unsafe.AddByteOffset(ref byteRef, c1Offset)), + ref Unsafe.As(ref Unsafe.AddByteOffset(ref byteRef, c2Offset)))) { + handler(userData, new(slot, host)); + } + } + }, runner); + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public unsafe static void Filter( + this IEntityHost host, in TData userData, DataComponentFilter filter, EntityHandler handler, TRunner runner) + where TRunner : IRunner + => host.Handle((filter, handler, userData), + static (IEntityHost host, in (DataComponentFilter, EntityHandler, TData) data, int from, int to) => { + var desc = host.Descriptor; + var slots = host.AllocatedSlots; + + var c1Offset = desc.GetOffset(); + var c2Offset = desc.GetOffset(); + var c3Offset = desc.GetOffset(); + + var filter = data.Item1; + var handler = data.Item2; + ref readonly var userData = ref data.Item3; + + for (int i = from; i != to; ++i) { + ref readonly var slot = ref slots[i]; + ref var byteRef = ref host.UnsafeGetByteRef(slot); + + if (filter(userData, + ref Unsafe.As(ref Unsafe.AddByteOffset(ref byteRef, c1Offset)), + ref Unsafe.As(ref Unsafe.AddByteOffset(ref byteRef, c2Offset)), + ref Unsafe.As(ref Unsafe.AddByteOffset(ref byteRef, c3Offset)))) { + handler(userData, new(slot, host)); + } + } + }, runner); + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public unsafe static void Filter( + this IEntityHost host, in TData userData, DataComponentFilter filter, EntityHandler handler, TRunner runner) + where TRunner : IRunner + => host.Handle((filter, handler, userData), + static (IEntityHost host, in (DataComponentFilter, EntityHandler, TData) data, int from, int to) => { + var desc = host.Descriptor; + var slots = host.AllocatedSlots; + + var c1Offset = desc.GetOffset(); + var c2Offset = desc.GetOffset(); + var c3Offset = desc.GetOffset(); + var c4Offset = desc.GetOffset(); + + var filter = data.Item1; + var handler = data.Item2; + ref readonly var userData = ref data.Item3; + + for (int i = from; i != to; ++i) { + ref readonly var slot = ref slots[i]; + ref var byteRef = ref host.UnsafeGetByteRef(slot); + + if (filter(userData, + ref Unsafe.As(ref Unsafe.AddByteOffset(ref byteRef, c1Offset)), + ref Unsafe.As(ref Unsafe.AddByteOffset(ref byteRef, c2Offset)), + ref Unsafe.As(ref Unsafe.AddByteOffset(ref byteRef, c3Offset)), + ref Unsafe.As(ref Unsafe.AddByteOffset(ref byteRef, c4Offset)))) { + handler(userData, new(slot, host)); + } + } + }, runner); + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public unsafe static void Filter( + this IEntityHost host, in TData userData, DataComponentFilter filter, EntityHandler handler, TRunner runner) + where TRunner : IRunner + => host.Handle((filter, handler, userData), + static (IEntityHost host, in (DataComponentFilter, EntityHandler, TData) data, int from, int to) => { + var desc = host.Descriptor; + var slots = host.AllocatedSlots; + + var c1Offset = desc.GetOffset(); + var c2Offset = desc.GetOffset(); + var c3Offset = desc.GetOffset(); + var c4Offset = desc.GetOffset(); + var c5Offset = desc.GetOffset(); + + var filter = data.Item1; + var handler = data.Item2; + ref readonly var userData = ref data.Item3; + + for (int i = from; i != to; ++i) { + ref readonly var slot = ref slots[i]; + ref var byteRef = ref host.UnsafeGetByteRef(slot); + + if (filter(userData, + ref Unsafe.As(ref Unsafe.AddByteOffset(ref byteRef, c1Offset)), + ref Unsafe.As(ref Unsafe.AddByteOffset(ref byteRef, c2Offset)), + ref Unsafe.As(ref Unsafe.AddByteOffset(ref byteRef, c3Offset)), + ref Unsafe.As(ref Unsafe.AddByteOffset(ref byteRef, c4Offset)), + ref Unsafe.As(ref Unsafe.AddByteOffset(ref byteRef, c5Offset)))) { + handler(userData, new(slot, host)); + } + } + }, runner); + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public unsafe static void Filter( + this IEntityHost host, in TData userData, DataComponentFilter filter, EntityHandler handler, TRunner runner) + where TRunner : IRunner + => host.Handle((filter, handler, userData), + static (IEntityHost host, in (DataComponentFilter, EntityHandler, TData) data, int from, int to) => { + var desc = host.Descriptor; + var slots = host.AllocatedSlots; + + var c1Offset = desc.GetOffset(); + var c2Offset = desc.GetOffset(); + var c3Offset = desc.GetOffset(); + var c4Offset = desc.GetOffset(); + var c5Offset = desc.GetOffset(); + var c6Offset = desc.GetOffset(); + + var filter = data.Item1; + var handler = data.Item2; + ref readonly var userData = ref data.Item3; + + for (int i = from; i != to; ++i) { + ref readonly var slot = ref slots[i]; + ref var byteRef = ref host.UnsafeGetByteRef(slot); + + if (filter(userData, + ref Unsafe.As(ref Unsafe.AddByteOffset(ref byteRef, c1Offset)), + ref Unsafe.As(ref Unsafe.AddByteOffset(ref byteRef, c2Offset)), + ref Unsafe.As(ref Unsafe.AddByteOffset(ref byteRef, c3Offset)), + ref Unsafe.As(ref Unsafe.AddByteOffset(ref byteRef, c4Offset)), + ref Unsafe.As(ref Unsafe.AddByteOffset(ref byteRef, c5Offset)), + ref Unsafe.As(ref Unsafe.AddByteOffset(ref byteRef, c6Offset)))) { + handler(userData, new(slot, host)); + } + } + }, runner); + + #region CurrentThreadRunner + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public unsafe static void Filter( + this IEntityHost host, ComponentFilter filter, EntityHandler handler) + => host.Filter(filter, handler, CurrentThreadRunner.Instance); + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public unsafe static void Filter( + this IEntityHost host, ComponentFilter filter, EntityHandler handler) + => host.Filter(filter, handler, CurrentThreadRunner.Instance); + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public unsafe static void Filter( + this IEntityHost host, ComponentFilter filter, EntityHandler handler) + => host.Filter(filter, handler, CurrentThreadRunner.Instance); + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public unsafe static void Filter( + this IEntityHost host, ComponentFilter filter, EntityHandler handler) + => host.Filter(filter, handler, CurrentThreadRunner.Instance); + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public unsafe static void Filter( + this IEntityHost host, ComponentFilter filter, EntityHandler handler) + => host.Filter(filter, handler, CurrentThreadRunner.Instance); + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public unsafe static void Filter( + this IEntityHost host, ComponentFilter filter, EntityHandler handler) + => host.Filter(filter, handler, CurrentThreadRunner.Instance); + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public unsafe static void Filter( + this IEntityHost host, in TData userData, DataComponentFilter filter, EntityHandler handler) + => host.Filter(userData, filter, handler, CurrentThreadRunner.Instance); + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public unsafe static void Filter( + this IEntityHost host, in TData userData, DataComponentFilter filter, EntityHandler handler) + => host.Filter(userData, filter, handler, CurrentThreadRunner.Instance); + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public unsafe static void Filter( + this IEntityHost host, in TData userData, DataComponentFilter filter, EntityHandler handler) + => host.Filter(userData, filter, handler, CurrentThreadRunner.Instance); + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public unsafe static void Filter( + this IEntityHost host, in TData userData, DataComponentFilter filter, EntityHandler handler) + => host.Filter(userData, filter, handler, CurrentThreadRunner.Instance); + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public unsafe static void Filter( + this IEntityHost host, in TData userData, DataComponentFilter filter, EntityHandler handler) + => host.Filter(userData, filter, handler, CurrentThreadRunner.Instance); + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public unsafe static void Filter( + this IEntityHost host, in TData userData, DataComponentFilter filter, EntityHandler handler) + => host.Filter(userData, filter, handler, CurrentThreadRunner.Instance); + + #endregion // ParallelRunner + + #region ParallelRunner + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public unsafe static void FilterOnParallel( + this IEntityHost host, ComponentFilter filter, EntityHandler handler) + => host.Filter(filter, handler, ParallelRunner.Default); + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public unsafe static void FilterOnParallel( + this IEntityHost host, ComponentFilter filter, EntityHandler handler) + => host.Filter(filter, handler, ParallelRunner.Default); + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public unsafe static void FilterOnParallel( + this IEntityHost host, ComponentFilter filter, EntityHandler handler) + => host.Filter(filter, handler, ParallelRunner.Default); + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public unsafe static void FilterOnParallel( + this IEntityHost host, ComponentFilter filter, EntityHandler handler) + => host.Filter(filter, handler, ParallelRunner.Default); + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public unsafe static void FilterOnParallel( + this IEntityHost host, ComponentFilter filter, EntityHandler handler) + => host.Filter(filter, handler, ParallelRunner.Default); + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public unsafe static void FilterOnParallel( + this IEntityHost host, ComponentFilter filter, EntityHandler handler) + => host.Filter(filter, handler, ParallelRunner.Default); + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public unsafe static void FilterOnParallel( + this IEntityHost host, in TData userData, DataComponentFilter filter, EntityHandler handler) + => host.Filter(userData, filter, handler, ParallelRunner.Default); + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public unsafe static void FilterOnParallel( + this IEntityHost host, in TData userData, DataComponentFilter filter, EntityHandler handler) + => host.Filter(userData, filter, handler, ParallelRunner.Default); + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public unsafe static void FilterOnParallel( + this IEntityHost host, in TData userData, DataComponentFilter filter, EntityHandler handler) + => host.Filter(userData, filter, handler, ParallelRunner.Default); + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public unsafe static void FilterOnParallel( + this IEntityHost host, in TData userData, DataComponentFilter filter, EntityHandler handler) + => host.Filter(userData, filter, handler, ParallelRunner.Default); + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public unsafe static void FilterOnParallel( + this IEntityHost host, in TData userData, DataComponentFilter filter, EntityHandler handler) + => host.Filter(userData, filter, handler, ParallelRunner.Default); + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public unsafe static void FilterOnParallel( + this IEntityHost host, in TData userData, DataComponentFilter filter, EntityHandler handler) + => host.Filter(userData, filter, handler, ParallelRunner.Default); + + #endregion // ParallelRunner + + #endregion // ComponentFilter } \ No newline at end of file diff --git a/Sia/Entities/Extensions/EntityQueryExtensions.ForEach.cs b/Sia/Entities/Extensions/EntityQueryExtensions.ForEach.cs index 448faf0..6a5fea9 100644 --- a/Sia/Entities/Extensions/EntityQueryExtensions.ForEach.cs +++ b/Sia/Entities/Extensions/EntityQueryExtensions.ForEach.cs @@ -517,4 +517,488 @@ public unsafe static void ForSliceOnParallel( #endregion // ParallelRunner #endregion // ComponentHandler + + #region ComponentFilter + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public unsafe static void Filter( + this IEntityQuery query, ComponentFilter filter, EntityHandler handler, TRunner runner) + where TRunner : IRunner + => query.Handle((filter, handler), + static (IEntityHost host, in (ComponentFilter, EntityHandler) fs, int from, int to) => { + var desc = host.Descriptor; + var slots = host.AllocatedSlots; + var (filter, handler) = fs; + + var c1Offset = desc.GetOffset(); + + for (int i = from; i != to; ++i) { + ref readonly var slot = ref slots[i]; + ref var byteRef = ref host.UnsafeGetByteRef(slot); + + if (filter(ref Unsafe.As(ref Unsafe.AddByteOffset(ref byteRef, c1Offset)))) { + handler(new(slot, host)); + } + } + }, runner); + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public unsafe static void Filter( + this IEntityQuery query, ComponentFilter filter, EntityHandler handler, TRunner runner) + where TRunner : IRunner + => query.Handle((filter, handler), + static (IEntityHost host, in (ComponentFilter, EntityHandler) fs, int from, int to) => { + var desc = host.Descriptor; + var slots = host.AllocatedSlots; + var (filter, handler) = fs; + + var c1Offset = desc.GetOffset(); + var c2Offset = desc.GetOffset(); + + for (int i = from; i != to; ++i) { + ref readonly var slot = ref slots[i]; + ref var byteRef = ref host.UnsafeGetByteRef(slot); + + if (filter( + ref Unsafe.As(ref Unsafe.AddByteOffset(ref byteRef, c1Offset)), + ref Unsafe.As(ref Unsafe.AddByteOffset(ref byteRef, c2Offset)))) { + handler(new(slot, host)); + } + } + }, runner); + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public unsafe static void Filter( + this IEntityQuery query, ComponentFilter filter, EntityHandler handler, TRunner runner) + where TRunner : IRunner + => query.Handle((filter, handler), + static (IEntityHost host, in (ComponentFilter, EntityHandler) fs, int from, int to) => { + var desc = host.Descriptor; + var slots = host.AllocatedSlots; + var (filter, handler) = fs; + + var c1Offset = desc.GetOffset(); + var c2Offset = desc.GetOffset(); + var c3Offset = desc.GetOffset(); + + for (int i = from; i != to; ++i) { + ref readonly var slot = ref slots[i]; + ref var byteRef = ref host.UnsafeGetByteRef(slot); + + if (filter( + ref Unsafe.As(ref Unsafe.AddByteOffset(ref byteRef, c1Offset)), + ref Unsafe.As(ref Unsafe.AddByteOffset(ref byteRef, c2Offset)), + ref Unsafe.As(ref Unsafe.AddByteOffset(ref byteRef, c3Offset)))) { + handler(new(slot, host)); + } + } + }, runner); + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public unsafe static void Filter( + this IEntityQuery query, ComponentFilter filter, EntityHandler handler, TRunner runner) + where TRunner : IRunner + => query.Handle((filter, handler), + static (IEntityHost host, in (ComponentFilter, EntityHandler) fs, int from, int to) => { + var desc = host.Descriptor; + var slots = host.AllocatedSlots; + var (filter, handler) = fs; + + var c1Offset = desc.GetOffset(); + var c2Offset = desc.GetOffset(); + var c3Offset = desc.GetOffset(); + var c4Offset = desc.GetOffset(); + + for (int i = from; i != to; ++i) { + ref readonly var slot = ref slots[i]; + ref var byteRef = ref host.UnsafeGetByteRef(slot); + + if (filter( + ref Unsafe.As(ref Unsafe.AddByteOffset(ref byteRef, c1Offset)), + ref Unsafe.As(ref Unsafe.AddByteOffset(ref byteRef, c2Offset)), + ref Unsafe.As(ref Unsafe.AddByteOffset(ref byteRef, c3Offset)), + ref Unsafe.As(ref Unsafe.AddByteOffset(ref byteRef, c4Offset)))) { + handler(new(slot, host)); + } + } + }, runner); + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public unsafe static void Filter( + this IEntityQuery query, ComponentFilter filter, EntityHandler handler, TRunner runner) + where TRunner : IRunner + => query.Handle((filter, handler), + static (IEntityHost host, in (ComponentFilter, EntityHandler) fs, int from, int to) => { + var desc = host.Descriptor; + var slots = host.AllocatedSlots; + var (filter, handler) = fs; + + var c1Offset = desc.GetOffset(); + var c2Offset = desc.GetOffset(); + var c3Offset = desc.GetOffset(); + var c4Offset = desc.GetOffset(); + var c5Offset = desc.GetOffset(); + + for (int i = from; i != to; ++i) { + ref readonly var slot = ref slots[i]; + ref var byteRef = ref host.UnsafeGetByteRef(slot); + + if (filter( + ref Unsafe.As(ref Unsafe.AddByteOffset(ref byteRef, c1Offset)), + ref Unsafe.As(ref Unsafe.AddByteOffset(ref byteRef, c2Offset)), + ref Unsafe.As(ref Unsafe.AddByteOffset(ref byteRef, c3Offset)), + ref Unsafe.As(ref Unsafe.AddByteOffset(ref byteRef, c4Offset)), + ref Unsafe.As(ref Unsafe.AddByteOffset(ref byteRef, c5Offset)))) { + handler(new(slot, host)); + } + } + }, runner); + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public unsafe static void Filter( + this IEntityQuery query, ComponentFilter filter, EntityHandler handler, TRunner runner) + where TRunner : IRunner + => query.Handle((filter, handler), + static (IEntityHost host, in (ComponentFilter, EntityHandler) fs, int from, int to) => { + var desc = host.Descriptor; + var slots = host.AllocatedSlots; + var (filter, handler) = fs; + + var c1Offset = desc.GetOffset(); + var c2Offset = desc.GetOffset(); + var c3Offset = desc.GetOffset(); + var c4Offset = desc.GetOffset(); + var c5Offset = desc.GetOffset(); + var c6Offset = desc.GetOffset(); + + for (int i = from; i != to; ++i) { + ref readonly var slot = ref slots[i]; + ref var byteRef = ref host.UnsafeGetByteRef(slot); + + if (filter( + ref Unsafe.As(ref Unsafe.AddByteOffset(ref byteRef, c1Offset)), + ref Unsafe.As(ref Unsafe.AddByteOffset(ref byteRef, c2Offset)), + ref Unsafe.As(ref Unsafe.AddByteOffset(ref byteRef, c3Offset)), + ref Unsafe.As(ref Unsafe.AddByteOffset(ref byteRef, c4Offset)), + ref Unsafe.As(ref Unsafe.AddByteOffset(ref byteRef, c5Offset)), + ref Unsafe.As(ref Unsafe.AddByteOffset(ref byteRef, c6Offset)))) { + handler(new(slot, host)); + } + } + }, runner); + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public unsafe static void Filter( + this IEntityQuery query, in TData userData, DataComponentFilter filter, EntityHandler handler, TRunner runner) + where TRunner : IRunner + => query.Handle((filter, handler, userData), + static (IEntityHost host, in (DataComponentFilter, EntityHandler, TData) data, int from, int to) => { + var desc = host.Descriptor; + var slots = host.AllocatedSlots; + + var c1Offset = desc.GetOffset(); + + var filter = data.Item1; + var handler = data.Item2; + ref readonly var userData = ref data.Item3; + + for (int i = from; i != to; ++i) { + ref readonly var slot = ref slots[i]; + ref var byteRef = ref host.UnsafeGetByteRef(slot); + + if (filter(userData, ref Unsafe.As(ref Unsafe.AddByteOffset(ref byteRef, c1Offset)))) { + handler(userData, new(slot, host)); + } + } + }, runner); + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public unsafe static void Filter( + this IEntityQuery query, in TData userData, DataComponentFilter filter, EntityHandler handler, TRunner runner) + where TRunner : IRunner + => query.Handle((filter, handler, userData), + static (IEntityHost host, in (DataComponentFilter, EntityHandler, TData) data, int from, int to) => { + var desc = host.Descriptor; + var slots = host.AllocatedSlots; + + var c1Offset = desc.GetOffset(); + var c2Offset = desc.GetOffset(); + + var filter = data.Item1; + var handler = data.Item2; + ref readonly var userData = ref data.Item3; + + for (int i = from; i != to; ++i) { + ref readonly var slot = ref slots[i]; + ref var byteRef = ref host.UnsafeGetByteRef(slot); + + if (filter(userData, + ref Unsafe.As(ref Unsafe.AddByteOffset(ref byteRef, c1Offset)), + ref Unsafe.As(ref Unsafe.AddByteOffset(ref byteRef, c2Offset)))) { + handler(userData, new(slot, host)); + } + } + }, runner); + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public unsafe static void Filter( + this IEntityQuery query, in TData userData, DataComponentFilter filter, EntityHandler handler, TRunner runner) + where TRunner : IRunner + => query.Handle((filter, handler, userData), + static (IEntityHost host, in (DataComponentFilter, EntityHandler, TData) data, int from, int to) => { + var desc = host.Descriptor; + var slots = host.AllocatedSlots; + + var c1Offset = desc.GetOffset(); + var c2Offset = desc.GetOffset(); + var c3Offset = desc.GetOffset(); + + var filter = data.Item1; + var handler = data.Item2; + ref readonly var userData = ref data.Item3; + + for (int i = from; i != to; ++i) { + ref readonly var slot = ref slots[i]; + ref var byteRef = ref host.UnsafeGetByteRef(slot); + + if (filter(userData, + ref Unsafe.As(ref Unsafe.AddByteOffset(ref byteRef, c1Offset)), + ref Unsafe.As(ref Unsafe.AddByteOffset(ref byteRef, c2Offset)), + ref Unsafe.As(ref Unsafe.AddByteOffset(ref byteRef, c3Offset)))) { + handler(userData, new(slot, host)); + } + } + }, runner); + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public unsafe static void Filter( + this IEntityQuery query, in TData userData, DataComponentFilter filter, EntityHandler handler, TRunner runner) + where TRunner : IRunner + => query.Handle((filter, handler, userData), + static (IEntityHost host, in (DataComponentFilter, EntityHandler, TData) data, int from, int to) => { + var desc = host.Descriptor; + var slots = host.AllocatedSlots; + + var c1Offset = desc.GetOffset(); + var c2Offset = desc.GetOffset(); + var c3Offset = desc.GetOffset(); + var c4Offset = desc.GetOffset(); + + var filter = data.Item1; + var handler = data.Item2; + ref readonly var userData = ref data.Item3; + + for (int i = from; i != to; ++i) { + ref readonly var slot = ref slots[i]; + ref var byteRef = ref host.UnsafeGetByteRef(slot); + + if (filter(userData, + ref Unsafe.As(ref Unsafe.AddByteOffset(ref byteRef, c1Offset)), + ref Unsafe.As(ref Unsafe.AddByteOffset(ref byteRef, c2Offset)), + ref Unsafe.As(ref Unsafe.AddByteOffset(ref byteRef, c3Offset)), + ref Unsafe.As(ref Unsafe.AddByteOffset(ref byteRef, c4Offset)))) { + handler(userData, new(slot, host)); + } + } + }, runner); + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public unsafe static void Filter( + this IEntityQuery query, in TData userData, DataComponentFilter filter, EntityHandler handler, TRunner runner) + where TRunner : IRunner + => query.Handle((filter, handler, userData), + static (IEntityHost host, in (DataComponentFilter, EntityHandler, TData) data, int from, int to) => { + var desc = host.Descriptor; + var slots = host.AllocatedSlots; + + var c1Offset = desc.GetOffset(); + var c2Offset = desc.GetOffset(); + var c3Offset = desc.GetOffset(); + var c4Offset = desc.GetOffset(); + var c5Offset = desc.GetOffset(); + + var filter = data.Item1; + var handler = data.Item2; + ref readonly var userData = ref data.Item3; + + for (int i = from; i != to; ++i) { + ref readonly var slot = ref slots[i]; + ref var byteRef = ref host.UnsafeGetByteRef(slot); + + if (filter(userData, + ref Unsafe.As(ref Unsafe.AddByteOffset(ref byteRef, c1Offset)), + ref Unsafe.As(ref Unsafe.AddByteOffset(ref byteRef, c2Offset)), + ref Unsafe.As(ref Unsafe.AddByteOffset(ref byteRef, c3Offset)), + ref Unsafe.As(ref Unsafe.AddByteOffset(ref byteRef, c4Offset)), + ref Unsafe.As(ref Unsafe.AddByteOffset(ref byteRef, c5Offset)))) { + handler(userData, new(slot, host)); + } + } + }, runner); + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public unsafe static void Filter( + this IEntityQuery query, in TData userData, DataComponentFilter filter, EntityHandler handler, TRunner runner) + where TRunner : IRunner + => query.Handle((filter, handler, userData), + static (IEntityHost host, in (DataComponentFilter, EntityHandler, TData) data, int from, int to) => { + var desc = host.Descriptor; + var slots = host.AllocatedSlots; + + var c1Offset = desc.GetOffset(); + var c2Offset = desc.GetOffset(); + var c3Offset = desc.GetOffset(); + var c4Offset = desc.GetOffset(); + var c5Offset = desc.GetOffset(); + var c6Offset = desc.GetOffset(); + + var filter = data.Item1; + var handler = data.Item2; + ref readonly var userData = ref data.Item3; + + for (int i = from; i != to; ++i) { + ref readonly var slot = ref slots[i]; + ref var byteRef = ref host.UnsafeGetByteRef(slot); + + if (filter(userData, + ref Unsafe.As(ref Unsafe.AddByteOffset(ref byteRef, c1Offset)), + ref Unsafe.As(ref Unsafe.AddByteOffset(ref byteRef, c2Offset)), + ref Unsafe.As(ref Unsafe.AddByteOffset(ref byteRef, c3Offset)), + ref Unsafe.As(ref Unsafe.AddByteOffset(ref byteRef, c4Offset)), + ref Unsafe.As(ref Unsafe.AddByteOffset(ref byteRef, c5Offset)), + ref Unsafe.As(ref Unsafe.AddByteOffset(ref byteRef, c6Offset)))) { + handler(userData, new(slot, host)); + } + } + }, runner); + + #region CurrentThreadRunner + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public unsafe static void Filter( + this IEntityQuery query, ComponentFilter filter, EntityHandler handler) + => query.Filter(filter, handler, CurrentThreadRunner.Instance); + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public unsafe static void Filter( + this IEntityQuery query, ComponentFilter filter, EntityHandler handler) + => query.Filter(filter, handler, CurrentThreadRunner.Instance); + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public unsafe static void Filter( + this IEntityQuery query, ComponentFilter filter, EntityHandler handler) + => query.Filter(filter, handler, CurrentThreadRunner.Instance); + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public unsafe static void Filter( + this IEntityQuery query, ComponentFilter filter, EntityHandler handler) + => query.Filter(filter, handler, CurrentThreadRunner.Instance); + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public unsafe static void Filter( + this IEntityQuery query, ComponentFilter filter, EntityHandler handler) + => query.Filter(filter, handler, CurrentThreadRunner.Instance); + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public unsafe static void Filter( + this IEntityQuery query, ComponentFilter filter, EntityHandler handler) + => query.Filter(filter, handler, CurrentThreadRunner.Instance); + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public unsafe static void Filter( + this IEntityQuery query, in TData userData, DataComponentFilter filter, EntityHandler handler) + => query.Filter(userData, filter, handler, CurrentThreadRunner.Instance); + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public unsafe static void Filter( + this IEntityQuery query, in TData userData, DataComponentFilter filter, EntityHandler handler) + => query.Filter(userData, filter, handler, CurrentThreadRunner.Instance); + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public unsafe static void Filter( + this IEntityQuery query, in TData userData, DataComponentFilter filter, EntityHandler handler) + => query.Filter(userData, filter, handler, CurrentThreadRunner.Instance); + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public unsafe static void Filter( + this IEntityQuery query, in TData userData, DataComponentFilter filter, EntityHandler handler) + => query.Filter(userData, filter, handler, CurrentThreadRunner.Instance); + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public unsafe static void Filter( + this IEntityQuery query, in TData userData, DataComponentFilter filter, EntityHandler handler) + => query.Filter(userData, filter, handler, CurrentThreadRunner.Instance); + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public unsafe static void Filter( + this IEntityQuery query, in TData userData, DataComponentFilter filter, EntityHandler handler) + => query.Filter(userData, filter, handler, CurrentThreadRunner.Instance); + + #endregion // ParallelRunner + + #region ParallelRunner + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public unsafe static void FilterOnParallel( + this IEntityQuery query, ComponentFilter filter, EntityHandler handler) + => query.Filter(filter, handler, ParallelRunner.Default); + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public unsafe static void FilterOnParallel( + this IEntityQuery query, ComponentFilter filter, EntityHandler handler) + => query.Filter(filter, handler, ParallelRunner.Default); + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public unsafe static void FilterOnParallel( + this IEntityQuery query, ComponentFilter filter, EntityHandler handler) + => query.Filter(filter, handler, ParallelRunner.Default); + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public unsafe static void FilterOnParallel( + this IEntityQuery query, ComponentFilter filter, EntityHandler handler) + => query.Filter(filter, handler, ParallelRunner.Default); + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public unsafe static void FilterOnParallel( + this IEntityQuery query, ComponentFilter filter, EntityHandler handler) + => query.Filter(filter, handler, ParallelRunner.Default); + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public unsafe static void FilterOnParallel( + this IEntityQuery query, ComponentFilter filter, EntityHandler handler) + => query.Filter(filter, handler, ParallelRunner.Default); + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public unsafe static void FilterOnParallel( + this IEntityQuery query, in TData userData, DataComponentFilter filter, EntityHandler handler) + => query.Filter(userData, filter, handler, ParallelRunner.Default); + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public unsafe static void FilterOnParallel( + this IEntityQuery query, in TData userData, DataComponentFilter filter, EntityHandler handler) + => query.Filter(userData, filter, handler, ParallelRunner.Default); + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public unsafe static void FilterOnParallel( + this IEntityQuery query, in TData userData, DataComponentFilter filter, EntityHandler handler) + => query.Filter(userData, filter, handler, ParallelRunner.Default); + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public unsafe static void FilterOnParallel( + this IEntityQuery query, in TData userData, DataComponentFilter filter, EntityHandler handler) + => query.Filter(userData, filter, handler, ParallelRunner.Default); + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public unsafe static void FilterOnParallel( + this IEntityQuery query, in TData userData, DataComponentFilter filter, EntityHandler handler) + => query.Filter(userData, filter, handler, ParallelRunner.Default); + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public unsafe static void FilterOnParallel( + this IEntityQuery query, in TData userData, DataComponentFilter filter, EntityHandler handler) + => query.Filter(userData, filter, handler, ParallelRunner.Default); + + #endregion // ParallelRunner + + #endregion // ComponentFilter } \ No newline at end of file