diff --git a/Sia/Entities/Extensions/EntityHostExtensions.ForEach.cs b/Sia/Entities/Extensions/EntityHostExtensions.ForEach.cs index a54ad7a..69be41d 100644 --- a/Sia/Entities/Extensions/EntityHostExtensions.ForEach.cs +++ b/Sia/Entities/Extensions/EntityHostExtensions.ForEach.cs @@ -8,7 +8,7 @@ public static partial class EntityHostExtensions [MethodImpl(MethodImplOptions.AggressiveInlining)] public static unsafe void ForEach( - this IEntityHost host, EntityHandler handler, TRunner runner) + this IEntityHost host, EntityHandler handler, TRunner runner, RunnerBarrier? barrier) where TRunner : IRunner => host.Handle(handler, static (IEntityHost host, in EntityHandler handler, int from, int to) => { @@ -16,11 +16,11 @@ public static unsafe void ForEach( for (int i = from; i != to; ++i) { handler(new(slosts[i], host)); } - }, runner); + }, runner, barrier); [MethodImpl(MethodImplOptions.AggressiveInlining)] public static unsafe void ForEach( - this IEntityHost host, in TData userData, EntityHandler handler, TRunner runner) + this IEntityHost host, in TData userData, EntityHandler handler, TRunner runner, RunnerBarrier? barrier) where TRunner : IRunner => host.Handle((userData, handler), static (IEntityHost host, in (TData, EntityHandler) entry, int from, int to) => { @@ -30,43 +30,43 @@ public static unsafe void ForEach( for (int i = from; i != to; ++i) { handler(data, new(slosts[i], host)); } - }, runner); + }, runner, barrier); [MethodImpl(MethodImplOptions.AggressiveInlining)] public static unsafe void ForEach( - this IEntityHost host, SimpleEntityHandler handler, TRunner runner) + this IEntityHost host, SimpleEntityHandler handler, TRunner runner, RunnerBarrier? barrier) where TRunner : IRunner => host.ForEach(handler, static (in SimpleEntityHandler handler, in EntityRef entity) - => handler(entity), runner); + => handler(entity), runner, barrier); [MethodImpl(MethodImplOptions.AggressiveInlining)] public static unsafe void ForEach( - this IEntityHost host, in TData userData, SimpleEntityHandler handler, TRunner runner) + this IEntityHost host, in TData userData, SimpleEntityHandler handler, TRunner runner, RunnerBarrier? barrier) where TRunner : IRunner => host.ForEach((handler, userData), static (in (SimpleEntityHandler, TData) data, in EntityRef entity) - => data.Item1(data.Item2, entity), runner); + => data.Item1(data.Item2, entity), runner, barrier); #region CurrentThreadRunner [MethodImpl(MethodImplOptions.AggressiveInlining)] public static unsafe void ForEach(this IEntityHost host, EntityHandler handler) - => host.ForEach(handler, CurrentThreadRunner.Instance); + => host.ForEach(handler, CurrentThreadRunner.Instance, barrier: null); [MethodImpl(MethodImplOptions.AggressiveInlining)] public static unsafe void ForEach( this IEntityHost host, in TData data, EntityHandler handler) - => host.ForEach(data, handler, CurrentThreadRunner.Instance); + => host.ForEach(data, handler, CurrentThreadRunner.Instance, barrier: null); [MethodImpl(MethodImplOptions.AggressiveInlining)] public static unsafe void ForEach(this IEntityHost host, SimpleEntityHandler handler) - => host.ForEach(handler, CurrentThreadRunner.Instance); + => host.ForEach(handler, CurrentThreadRunner.Instance, barrier: null); [MethodImpl(MethodImplOptions.AggressiveInlining)] public static unsafe void ForEach( this IEntityHost host, in TData data, SimpleEntityHandler handler) - => host.ForEach(data, handler, CurrentThreadRunner.Instance); + => host.ForEach(data, handler, CurrentThreadRunner.Instance, barrier: null); #endregion // CurrentThreadRunner @@ -74,21 +74,37 @@ public static unsafe void ForEach( [MethodImpl(MethodImplOptions.AggressiveInlining)] public static unsafe void ForEachOnParallel(this IEntityHost host, EntityHandler handler) - => host.ForEach(handler, ParallelRunner.Default); + { + var barrier = RunnerBarrier.Get(); + host.ForEach(handler, ParallelRunner.Default, barrier); + barrier.WaitAndReturn(); + } [MethodImpl(MethodImplOptions.AggressiveInlining)] public static unsafe void ForEachOnParallel( this IEntityHost host, in TData data, EntityHandler handler) - => host.ForEach(data, handler, ParallelRunner.Default); + { + var barrier = RunnerBarrier.Get(); + host.ForEach(data, handler, ParallelRunner.Default, barrier); + barrier.WaitAndReturn(); + } [MethodImpl(MethodImplOptions.AggressiveInlining)] public static unsafe void ForEachOnParallel(this IEntityHost host, SimpleEntityHandler handler) - => host.ForEach(handler, ParallelRunner.Default); + { + var barrier = RunnerBarrier.Get(); + host.ForEach(handler, ParallelRunner.Default, barrier); + barrier.WaitAndReturn(); + } [MethodImpl(MethodImplOptions.AggressiveInlining)] public static unsafe void ForEachOnParallel( this IEntityHost host, in TData data, SimpleEntityHandler handler) - => host.ForEach(data, handler, ParallelRunner.Default); + { + var barrier = RunnerBarrier.Get(); + host.ForEach(data, handler, ParallelRunner.Default, barrier); + barrier.WaitAndReturn(); + } #endregion // ParallelRunner @@ -98,7 +114,7 @@ public static unsafe void ForEachOnParallel( [MethodImpl(MethodImplOptions.AggressiveInlining)] public unsafe static void ForSlice( - this IEntityHost host, ComponentHandler handler, TRunner runner) + this IEntityHost host, ComponentHandler handler, TRunner runner, RunnerBarrier? barrier) where TRunner : IRunner => host.Handle(handler, static (IEntityHost host, in ComponentHandler handler, int from, int to) => { @@ -111,11 +127,11 @@ public unsafe static void ForSlice( ref var byteRef = ref host.UnsafeGetByteRef(slots[i]); handler(ref c1Offset.Get(ref byteRef)); } - }, runner); + }, runner, barrier); [MethodImpl(MethodImplOptions.AggressiveInlining)] public unsafe static void ForSlice( - this IEntityHost host, ComponentHandler handler, TRunner runner) + this IEntityHost host, ComponentHandler handler, TRunner runner, RunnerBarrier? barrier) where TRunner : IRunner => host.Handle(handler, static (IEntityHost host, in ComponentHandler handler, int from, int to) => { @@ -131,11 +147,11 @@ public unsafe static void ForSlice( ref c1Offset.Get(ref byteRef), ref c2Offset.Get(ref byteRef)); } - }, runner); + }, runner, barrier); [MethodImpl(MethodImplOptions.AggressiveInlining)] public unsafe static void ForSlice( - this IEntityHost host, ComponentHandler handler, TRunner runner) + this IEntityHost host, ComponentHandler handler, TRunner runner, RunnerBarrier? barrier) where TRunner : IRunner => host.Handle(handler, static (IEntityHost host, in ComponentHandler handler, int from, int to) => { @@ -153,11 +169,11 @@ ref c1Offset.Get(ref byteRef), ref c2Offset.Get(ref byteRef), ref c3Offset.Get(ref byteRef)); } - }, runner); + }, runner, barrier); [MethodImpl(MethodImplOptions.AggressiveInlining)] public unsafe static void ForSlice( - this IEntityHost host, ComponentHandler handler, TRunner runner) + this IEntityHost host, ComponentHandler handler, TRunner runner, RunnerBarrier? barrier) where TRunner : IRunner => host.Handle(handler, static (IEntityHost host, in ComponentHandler handler, int from, int to) => { @@ -177,11 +193,11 @@ ref c2Offset.Get(ref byteRef), ref c3Offset.Get(ref byteRef), ref c4Offset.Get(ref byteRef)); } - }, runner); + }, runner, barrier); [MethodImpl(MethodImplOptions.AggressiveInlining)] public unsafe static void ForSlice( - this IEntityHost host, ComponentHandler handler, TRunner runner) + this IEntityHost host, ComponentHandler handler, TRunner runner, RunnerBarrier? barrier) where TRunner : IRunner => host.Handle(handler, static (IEntityHost host, in ComponentHandler handler, int from, int to) => { @@ -203,11 +219,11 @@ ref c3Offset.Get(ref byteRef), ref c4Offset.Get(ref byteRef), ref c5Offset.Get(ref byteRef)); } - }, runner); + }, runner, barrier); [MethodImpl(MethodImplOptions.AggressiveInlining)] public unsafe static void ForSlice( - this IEntityHost host, ComponentHandler handler, TRunner runner) + this IEntityHost host, ComponentHandler handler, TRunner runner, RunnerBarrier? barrier) where TRunner : IRunner => host.Handle(handler, static (IEntityHost host, in ComponentHandler handler, int from, int to) => { @@ -231,11 +247,11 @@ ref c4Offset.Get(ref byteRef), ref c5Offset.Get(ref byteRef), ref c6Offset.Get(ref byteRef)); } - }, runner); + }, runner, barrier); [MethodImpl(MethodImplOptions.AggressiveInlining)] public unsafe static void ForSlice( - this IEntityHost host, in TData userData, DataComponentHandler handler, TRunner runner) + this IEntityHost host, in TData userData, DataComponentHandler handler, TRunner runner, RunnerBarrier? barrier) where TRunner : IRunner => host.Handle((handler, userData), static (IEntityHost host, in (DataComponentHandler, TData) data, int from, int to) => { @@ -251,11 +267,11 @@ public unsafe static void ForSlice( ref var byteRef = ref host.UnsafeGetByteRef(slots[i]); handler(userData, ref c1Offset.Get(ref byteRef)); } - }, runner); + }, runner, barrier); [MethodImpl(MethodImplOptions.AggressiveInlining)] public unsafe static void ForSlice( - this IEntityHost host, in TData userData, DataComponentHandler handler, TRunner runner) + this IEntityHost host, in TData userData, DataComponentHandler handler, TRunner runner, RunnerBarrier? barrier) where TRunner : IRunner => host.Handle((handler, userData), static (IEntityHost host, in (DataComponentHandler, TData) data, int from, int to) => { @@ -274,11 +290,11 @@ public unsafe static void ForSlice( ref c1Offset.Get(ref byteRef), ref c2Offset.Get(ref byteRef)); } - }, runner); + }, runner, barrier); [MethodImpl(MethodImplOptions.AggressiveInlining)] public unsafe static void ForSlice( - this IEntityHost host, in TData userData, DataComponentHandler handler, TRunner runner) + this IEntityHost host, in TData userData, DataComponentHandler handler, TRunner runner, RunnerBarrier? barrier) where TRunner : IRunner => host.Handle((handler, userData), static (IEntityHost host, in (DataComponentHandler, TData) data, int from, int to) => { @@ -299,11 +315,11 @@ ref c1Offset.Get(ref byteRef), ref c2Offset.Get(ref byteRef), ref c3Offset.Get(ref byteRef)); } - }, runner); + }, runner, barrier); [MethodImpl(MethodImplOptions.AggressiveInlining)] public unsafe static void ForSlice( - this IEntityHost host, in TData userData, DataComponentHandler handler, TRunner runner) + this IEntityHost host, in TData userData, DataComponentHandler handler, TRunner runner, RunnerBarrier? barrier) where TRunner : IRunner => host.Handle((handler, userData), static (IEntityHost host, in (DataComponentHandler, TData) data, int from, int to) => { @@ -326,11 +342,11 @@ ref c2Offset.Get(ref byteRef), ref c3Offset.Get(ref byteRef), ref c4Offset.Get(ref byteRef)); } - }, runner); + }, runner, barrier); [MethodImpl(MethodImplOptions.AggressiveInlining)] public unsafe static void ForSlice( - this IEntityHost host, in TData userData, DataComponentHandler handler, TRunner runner) + this IEntityHost host, in TData userData, DataComponentHandler handler, TRunner runner, RunnerBarrier? barrier) where TRunner : IRunner => host.Handle((handler, userData), static (IEntityHost host, in (DataComponentHandler, TData) data, int from, int to) => { @@ -355,11 +371,11 @@ ref c3Offset.Get(ref byteRef), ref c4Offset.Get(ref byteRef), ref c5Offset.Get(ref byteRef)); } - }, runner); + }, runner, barrier); [MethodImpl(MethodImplOptions.AggressiveInlining)] public unsafe static void ForSlice( - this IEntityHost host, in TData userData, DataComponentHandler handler, TRunner runner) + this IEntityHost host, in TData userData, DataComponentHandler handler, TRunner runner, RunnerBarrier? barrier) where TRunner : IRunner => host.Handle((handler, userData), static (IEntityHost host, in (DataComponentHandler, TData) data, int from, int to) => { @@ -386,69 +402,69 @@ ref c4Offset.Get(ref byteRef), ref c5Offset.Get(ref byteRef), ref c6Offset.Get(ref byteRef)); } - }, runner); + }, runner, barrier); #region CurrentThreadRunner [MethodImpl(MethodImplOptions.AggressiveInlining)] public unsafe static void ForSlice( this IEntityHost host, ComponentHandler handler) - => host.ForSlice(handler, CurrentThreadRunner.Instance); + => host.ForSlice(handler, CurrentThreadRunner.Instance, barrier: null); [MethodImpl(MethodImplOptions.AggressiveInlining)] public unsafe static void ForSlice( this IEntityHost host, ComponentHandler handler) - => host.ForSlice(handler, CurrentThreadRunner.Instance); + => host.ForSlice(handler, CurrentThreadRunner.Instance, barrier: null); [MethodImpl(MethodImplOptions.AggressiveInlining)] public unsafe static void ForSlice( this IEntityHost host, ComponentHandler handler) - => host.ForSlice(handler, CurrentThreadRunner.Instance); + => host.ForSlice(handler, CurrentThreadRunner.Instance, barrier: null); [MethodImpl(MethodImplOptions.AggressiveInlining)] public unsafe static void ForSlice( this IEntityHost host, ComponentHandler handler) - => host.ForSlice(handler, CurrentThreadRunner.Instance); + => host.ForSlice(handler, CurrentThreadRunner.Instance, barrier: null); [MethodImpl(MethodImplOptions.AggressiveInlining)] public unsafe static void ForSlice( this IEntityHost host, ComponentHandler handler) - => host.ForSlice(handler, CurrentThreadRunner.Instance); + => host.ForSlice(handler, CurrentThreadRunner.Instance, barrier: null); [MethodImpl(MethodImplOptions.AggressiveInlining)] public unsafe static void ForSlice( this IEntityHost host, ComponentHandler handler) - => host.ForSlice(handler, CurrentThreadRunner.Instance); + => host.ForSlice(handler, CurrentThreadRunner.Instance, barrier: null); [MethodImpl(MethodImplOptions.AggressiveInlining)] public unsafe static void ForSlice( this IEntityHost host, in TData userData, DataComponentHandler handler) - => host.ForSlice(userData, handler, CurrentThreadRunner.Instance); + => host.ForSlice(userData, handler, CurrentThreadRunner.Instance, barrier: null); [MethodImpl(MethodImplOptions.AggressiveInlining)] public unsafe static void ForSlice( this IEntityHost host, in TData userData, DataComponentHandler handler) - => host.ForSlice(userData, handler, CurrentThreadRunner.Instance); + => host.ForSlice(userData, handler, CurrentThreadRunner.Instance, barrier: null); [MethodImpl(MethodImplOptions.AggressiveInlining)] public unsafe static void ForSlice( this IEntityHost host, in TData userData, DataComponentHandler handler) - => host.ForSlice(userData, handler, CurrentThreadRunner.Instance); + => host.ForSlice(userData, handler, CurrentThreadRunner.Instance, barrier: null); [MethodImpl(MethodImplOptions.AggressiveInlining)] public unsafe static void ForSlice( this IEntityHost host, in TData userData, DataComponentHandler handler) - => host.ForSlice(userData, handler, CurrentThreadRunner.Instance); + => host.ForSlice(userData, handler, CurrentThreadRunner.Instance, barrier: null); [MethodImpl(MethodImplOptions.AggressiveInlining)] public unsafe static void ForSlice( this IEntityHost host, in TData userData, DataComponentHandler handler) - => host.ForSlice(userData, handler, CurrentThreadRunner.Instance); + => host.ForSlice(userData, handler, CurrentThreadRunner.Instance, barrier: null); [MethodImpl(MethodImplOptions.AggressiveInlining)] public unsafe static void ForSlice( this IEntityHost host, in TData userData, DataComponentHandler handler) - => host.ForSlice(userData, handler, CurrentThreadRunner.Instance); + => host.ForSlice(userData, handler, CurrentThreadRunner.Instance, barrier: null); #endregion // CurrentThreadRunner @@ -457,62 +473,110 @@ public unsafe static void ForSlice( [MethodImpl(MethodImplOptions.AggressiveInlining)] public unsafe static void ForSliceOnParallel( this IEntityHost host, ComponentHandler handler) - => host.ForSlice(handler, ParallelRunner.Default); + { + var barrier = RunnerBarrier.Get(); + host.ForSlice(handler, ParallelRunner.Default, barrier); + barrier.WaitAndReturn(); + } [MethodImpl(MethodImplOptions.AggressiveInlining)] public unsafe static void ForSliceOnParallel( this IEntityHost host, ComponentHandler handler) - => host.ForSlice(handler, ParallelRunner.Default); + { + var barrier = RunnerBarrier.Get(); + host.ForSlice(handler, ParallelRunner.Default, barrier); + barrier.WaitAndReturn(); + } [MethodImpl(MethodImplOptions.AggressiveInlining)] public unsafe static void ForSliceOnParallel( this IEntityHost host, ComponentHandler handler) - => host.ForSlice(handler, ParallelRunner.Default); + { + var barrier = RunnerBarrier.Get(); + host.ForSlice(handler, ParallelRunner.Default, barrier); + barrier.WaitAndReturn(); + } [MethodImpl(MethodImplOptions.AggressiveInlining)] public unsafe static void ForSliceOnParallel( this IEntityHost host, ComponentHandler handler) - => host.ForSlice(handler, ParallelRunner.Default); + { + var barrier = RunnerBarrier.Get(); + host.ForSlice(handler, ParallelRunner.Default, barrier); + barrier.WaitAndReturn(); + } [MethodImpl(MethodImplOptions.AggressiveInlining)] public unsafe static void ForSliceOnParallel( this IEntityHost host, ComponentHandler handler) - => host.ForSlice(handler, ParallelRunner.Default); + { + var barrier = RunnerBarrier.Get(); + host.ForSlice(handler, ParallelRunner.Default, barrier); + barrier.WaitAndReturn(); + } [MethodImpl(MethodImplOptions.AggressiveInlining)] public unsafe static void ForSliceOnParallel( this IEntityHost host, ComponentHandler handler) - => host.ForSlice(handler, ParallelRunner.Default); + { + var barrier = RunnerBarrier.Get(); + host.ForSlice(handler, ParallelRunner.Default, barrier); + barrier.WaitAndReturn(); + } [MethodImpl(MethodImplOptions.AggressiveInlining)] public unsafe static void ForSliceOnParallel( this IEntityHost host, in TData userData, DataComponentHandler handler) - => host.ForSlice(userData, handler, ParallelRunner.Default); + { + var barrier = RunnerBarrier.Get(); + host.ForSlice(userData, handler, ParallelRunner.Default, barrier); + barrier.WaitAndReturn(); + } [MethodImpl(MethodImplOptions.AggressiveInlining)] public unsafe static void ForSliceOnParallel( this IEntityHost host, in TData userData, DataComponentHandler handler) - => host.ForSlice(userData, handler, ParallelRunner.Default); + { + var barrier = RunnerBarrier.Get(); + host.ForSlice(userData, handler, ParallelRunner.Default, barrier); + barrier.WaitAndReturn(); + } [MethodImpl(MethodImplOptions.AggressiveInlining)] public unsafe static void ForSliceOnParallel( this IEntityHost host, in TData userData, DataComponentHandler handler) - => host.ForSlice(userData, handler, ParallelRunner.Default); + { + var barrier = RunnerBarrier.Get(); + host.ForSlice(userData, handler, ParallelRunner.Default, barrier); + barrier.WaitAndReturn(); + } [MethodImpl(MethodImplOptions.AggressiveInlining)] public unsafe static void ForSliceOnParallel( this IEntityHost host, in TData userData, DataComponentHandler handler) - => host.ForSlice(userData, handler, ParallelRunner.Default); + { + var barrier = RunnerBarrier.Get(); + host.ForSlice(userData, handler, ParallelRunner.Default, barrier); + barrier.WaitAndReturn(); + } [MethodImpl(MethodImplOptions.AggressiveInlining)] public unsafe static void ForSliceOnParallel( this IEntityHost host, in TData userData, DataComponentHandler handler) - => host.ForSlice(userData, handler, ParallelRunner.Default); + { + var barrier = RunnerBarrier.Get(); + host.ForSlice(userData, handler, ParallelRunner.Default, barrier); + barrier.WaitAndReturn(); + } [MethodImpl(MethodImplOptions.AggressiveInlining)] public unsafe static void ForSliceOnParallel( this IEntityHost host, in TData userData, DataComponentHandler handler) - => host.ForSlice(userData, handler, ParallelRunner.Default); + { + var barrier = RunnerBarrier.Get(); + host.ForSlice(userData, handler, ParallelRunner.Default, barrier); + barrier.WaitAndReturn(); + } #endregion // ParallelRunner @@ -522,7 +586,7 @@ public unsafe static void ForSliceOnParallel( [MethodImpl(MethodImplOptions.AggressiveInlining)] public unsafe static void Filter( - this IEntityHost host, ComponentFilter filter, EntityHandler handler, TRunner runner) + this IEntityHost host, ComponentFilter filter, EntityHandler handler, TRunner runner, RunnerBarrier? barrier) where TRunner : IRunner => host.Handle((filter, handler), static (IEntityHost host, in (ComponentFilter, EntityHandler) fs, int from, int to) => { @@ -540,11 +604,11 @@ public unsafe static void Filter( handler(new(slot, host)); } } - }, runner); + }, runner, barrier); [MethodImpl(MethodImplOptions.AggressiveInlining)] public unsafe static void Filter( - this IEntityHost host, ComponentFilter filter, EntityHandler handler, TRunner runner) + this IEntityHost host, ComponentFilter filter, EntityHandler handler, TRunner runner, RunnerBarrier? barrier) where TRunner : IRunner => host.Handle((filter, handler), static (IEntityHost host, in (ComponentFilter, EntityHandler) fs, int from, int to) => { @@ -565,11 +629,11 @@ ref c2Offset.Get(ref byteRef))) { handler(new(slot, host)); } } - }, runner); + }, runner, barrier); [MethodImpl(MethodImplOptions.AggressiveInlining)] public unsafe static void Filter( - this IEntityHost host, ComponentFilter filter, EntityHandler handler, TRunner runner) + this IEntityHost host, ComponentFilter filter, EntityHandler handler, TRunner runner, RunnerBarrier? barrier) where TRunner : IRunner => host.Handle((filter, handler), static (IEntityHost host, in (ComponentFilter, EntityHandler) fs, int from, int to) => { @@ -592,11 +656,11 @@ ref c3Offset.Get(ref byteRef))) { handler(new(slot, host)); } } - }, runner); + }, runner, barrier); [MethodImpl(MethodImplOptions.AggressiveInlining)] public unsafe static void Filter( - this IEntityHost host, ComponentFilter filter, EntityHandler handler, TRunner runner) + this IEntityHost host, ComponentFilter filter, EntityHandler handler, TRunner runner, RunnerBarrier? barrier) where TRunner : IRunner => host.Handle((filter, handler), static (IEntityHost host, in (ComponentFilter, EntityHandler) fs, int from, int to) => { @@ -621,11 +685,11 @@ ref c4Offset.Get(ref byteRef))) { handler(new(slot, host)); } } - }, runner); + }, runner, barrier); [MethodImpl(MethodImplOptions.AggressiveInlining)] public unsafe static void Filter( - this IEntityHost host, ComponentFilter filter, EntityHandler handler, TRunner runner) + this IEntityHost host, ComponentFilter filter, EntityHandler handler, TRunner runner, RunnerBarrier? barrier) where TRunner : IRunner => host.Handle((filter, handler), static (IEntityHost host, in (ComponentFilter, EntityHandler) fs, int from, int to) => { @@ -652,11 +716,11 @@ ref c5Offset.Get(ref byteRef))) { handler(new(slot, host)); } } - }, runner); + }, runner, barrier); [MethodImpl(MethodImplOptions.AggressiveInlining)] public unsafe static void Filter( - this IEntityHost host, ComponentFilter filter, EntityHandler handler, TRunner runner) + this IEntityHost host, ComponentFilter filter, EntityHandler handler, TRunner runner, RunnerBarrier? barrier) where TRunner : IRunner => host.Handle((filter, handler), static (IEntityHost host, in (ComponentFilter, EntityHandler) fs, int from, int to) => { @@ -685,11 +749,11 @@ ref c6Offset.Get(ref byteRef))) { handler(new(slot, host)); } } - }, runner); + }, runner, barrier); [MethodImpl(MethodImplOptions.AggressiveInlining)] public unsafe static void Filter( - this IEntityHost host, in TData userData, DataComponentFilter filter, EntityHandler handler, TRunner runner) + this IEntityHost host, in TData userData, DataComponentFilter filter, EntityHandler handler, TRunner runner, RunnerBarrier? barrier) where TRunner : IRunner => host.Handle((filter, handler, userData), static (IEntityHost host, in (DataComponentFilter, EntityHandler, TData) data, int from, int to) => { @@ -710,11 +774,11 @@ public unsafe static void Filter( handler(userData, new(slot, host)); } } - }, runner); + }, runner, barrier); [MethodImpl(MethodImplOptions.AggressiveInlining)] public unsafe static void Filter( - this IEntityHost host, in TData userData, DataComponentFilter filter, EntityHandler handler, TRunner runner) + this IEntityHost host, in TData userData, DataComponentFilter filter, EntityHandler handler, TRunner runner, RunnerBarrier? barrier) where TRunner : IRunner => host.Handle((filter, handler, userData), static (IEntityHost host, in (DataComponentFilter, EntityHandler, TData) data, int from, int to) => { @@ -738,11 +802,11 @@ ref c2Offset.Get(ref byteRef))) { handler(userData, new(slot, host)); } } - }, runner); + }, runner, barrier); [MethodImpl(MethodImplOptions.AggressiveInlining)] public unsafe static void Filter( - this IEntityHost host, in TData userData, DataComponentFilter filter, EntityHandler handler, TRunner runner) + this IEntityHost host, in TData userData, DataComponentFilter filter, EntityHandler handler, TRunner runner, RunnerBarrier? barrier) where TRunner : IRunner => host.Handle((filter, handler, userData), static (IEntityHost host, in (DataComponentFilter, EntityHandler, TData) data, int from, int to) => { @@ -768,11 +832,11 @@ ref c3Offset.Get(ref byteRef))) { handler(userData, new(slot, host)); } } - }, runner); + }, runner, barrier); [MethodImpl(MethodImplOptions.AggressiveInlining)] public unsafe static void Filter( - this IEntityHost host, in TData userData, DataComponentFilter filter, EntityHandler handler, TRunner runner) + this IEntityHost host, in TData userData, DataComponentFilter filter, EntityHandler handler, TRunner runner, RunnerBarrier? barrier) where TRunner : IRunner => host.Handle((filter, handler, userData), static (IEntityHost host, in (DataComponentFilter, EntityHandler, TData) data, int from, int to) => { @@ -800,11 +864,11 @@ ref c4Offset.Get(ref byteRef))) { handler(userData, new(slot, host)); } } - }, runner); + }, runner, barrier); [MethodImpl(MethodImplOptions.AggressiveInlining)] public unsafe static void Filter( - this IEntityHost host, in TData userData, DataComponentFilter filter, EntityHandler handler, TRunner runner) + this IEntityHost host, in TData userData, DataComponentFilter filter, EntityHandler handler, TRunner runner, RunnerBarrier? barrier) where TRunner : IRunner => host.Handle((filter, handler, userData), static (IEntityHost host, in (DataComponentFilter, EntityHandler, TData) data, int from, int to) => { @@ -834,11 +898,11 @@ ref c5Offset.Get(ref byteRef))) { handler(userData, new(slot, host)); } } - }, runner); + }, runner, barrier); [MethodImpl(MethodImplOptions.AggressiveInlining)] public unsafe static void Filter( - this IEntityHost host, in TData userData, DataComponentFilter filter, EntityHandler handler, TRunner runner) + this IEntityHost host, in TData userData, DataComponentFilter filter, EntityHandler handler, TRunner runner, RunnerBarrier? barrier) where TRunner : IRunner => host.Handle((filter, handler, userData), static (IEntityHost host, in (DataComponentFilter, EntityHandler, TData) data, int from, int to) => { @@ -870,133 +934,181 @@ ref c6Offset.Get(ref byteRef))) { handler(userData, new(slot, host)); } } - }, runner); + }, runner, barrier); #region CurrentThreadRunner [MethodImpl(MethodImplOptions.AggressiveInlining)] public unsafe static void Filter( this IEntityHost host, ComponentFilter filter, EntityHandler handler) - => host.Filter(filter, handler, CurrentThreadRunner.Instance); + => host.Filter(filter, handler, CurrentThreadRunner.Instance, barrier: null); [MethodImpl(MethodImplOptions.AggressiveInlining)] public unsafe static void Filter( this IEntityHost host, ComponentFilter filter, EntityHandler handler) - => host.Filter(filter, handler, CurrentThreadRunner.Instance); + => host.Filter(filter, handler, CurrentThreadRunner.Instance, barrier: null); [MethodImpl(MethodImplOptions.AggressiveInlining)] public unsafe static void Filter( this IEntityHost host, ComponentFilter filter, EntityHandler handler) - => host.Filter(filter, handler, CurrentThreadRunner.Instance); + => host.Filter(filter, handler, CurrentThreadRunner.Instance, barrier: null); [MethodImpl(MethodImplOptions.AggressiveInlining)] public unsafe static void Filter( this IEntityHost host, ComponentFilter filter, EntityHandler handler) - => host.Filter(filter, handler, CurrentThreadRunner.Instance); + => host.Filter(filter, handler, CurrentThreadRunner.Instance, barrier: null); [MethodImpl(MethodImplOptions.AggressiveInlining)] public unsafe static void Filter( this IEntityHost host, ComponentFilter filter, EntityHandler handler) - => host.Filter(filter, handler, CurrentThreadRunner.Instance); + => host.Filter(filter, handler, CurrentThreadRunner.Instance, barrier: null); [MethodImpl(MethodImplOptions.AggressiveInlining)] public unsafe static void Filter( this IEntityHost host, ComponentFilter filter, EntityHandler handler) - => host.Filter(filter, handler, CurrentThreadRunner.Instance); + => host.Filter(filter, handler, CurrentThreadRunner.Instance, barrier: null); [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); + => host.Filter(userData, filter, handler, CurrentThreadRunner.Instance, barrier: null); [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); + => host.Filter(userData, filter, handler, CurrentThreadRunner.Instance, barrier: null); [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); + => host.Filter(userData, filter, handler, CurrentThreadRunner.Instance, barrier: null); [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); + => host.Filter(userData, filter, handler, CurrentThreadRunner.Instance, barrier: null); [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); + => host.Filter(userData, filter, handler, CurrentThreadRunner.Instance, barrier: null); [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); + => host.Filter(userData, filter, handler, CurrentThreadRunner.Instance, barrier: null); - #endregion // ParallelRunner + #endregion // CurrentThreadRunner #region ParallelRunner [MethodImpl(MethodImplOptions.AggressiveInlining)] public unsafe static void FilterOnParallel( this IEntityHost host, ComponentFilter filter, EntityHandler handler) - => host.Filter(filter, handler, ParallelRunner.Default); + { + var barrier = RunnerBarrier.Get(); + host.Filter(filter, handler, ParallelRunner.Default, barrier); + barrier.WaitAndReturn(); + } [MethodImpl(MethodImplOptions.AggressiveInlining)] public unsafe static void FilterOnParallel( this IEntityHost host, ComponentFilter filter, EntityHandler handler) - => host.Filter(filter, handler, ParallelRunner.Default); + { + var barrier = RunnerBarrier.Get(); + host.Filter(filter, handler, ParallelRunner.Default, barrier); + barrier.WaitAndReturn(); + } [MethodImpl(MethodImplOptions.AggressiveInlining)] public unsafe static void FilterOnParallel( this IEntityHost host, ComponentFilter filter, EntityHandler handler) - => host.Filter(filter, handler, ParallelRunner.Default); + { + var barrier = RunnerBarrier.Get(); + host.Filter(filter, handler, ParallelRunner.Default, barrier); + barrier.WaitAndReturn(); + } [MethodImpl(MethodImplOptions.AggressiveInlining)] public unsafe static void FilterOnParallel( this IEntityHost host, ComponentFilter filter, EntityHandler handler) - => host.Filter(filter, handler, ParallelRunner.Default); + { + var barrier = RunnerBarrier.Get(); + host.Filter(filter, handler, ParallelRunner.Default, barrier); + barrier.WaitAndReturn(); + } [MethodImpl(MethodImplOptions.AggressiveInlining)] public unsafe static void FilterOnParallel( this IEntityHost host, ComponentFilter filter, EntityHandler handler) - => host.Filter(filter, handler, ParallelRunner.Default); + { + var barrier = RunnerBarrier.Get(); + host.Filter(filter, handler, ParallelRunner.Default, barrier); + barrier.WaitAndReturn(); + } [MethodImpl(MethodImplOptions.AggressiveInlining)] public unsafe static void FilterOnParallel( this IEntityHost host, ComponentFilter filter, EntityHandler handler) - => host.Filter(filter, handler, ParallelRunner.Default); + { + var barrier = RunnerBarrier.Get(); + host.Filter(filter, handler, ParallelRunner.Default, barrier); + barrier.WaitAndReturn(); + } [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); + { + var barrier = RunnerBarrier.Get(); + host.Filter(userData, filter, handler, ParallelRunner.Default, barrier); + barrier.WaitAndReturn(); + } [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); + { + var barrier = RunnerBarrier.Get(); + host.Filter(userData, filter, handler, ParallelRunner.Default, barrier); + barrier.WaitAndReturn(); + } [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); + { + var barrier = RunnerBarrier.Get(); + host.Filter(userData, filter, handler, ParallelRunner.Default, barrier); + barrier.WaitAndReturn(); + } [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); + { + var barrier = RunnerBarrier.Get(); + host.Filter(userData, filter, handler, ParallelRunner.Default, barrier); + barrier.WaitAndReturn(); + } [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); + { + var barrier = RunnerBarrier.Get(); + host.Filter(userData, filter, handler, ParallelRunner.Default, barrier); + barrier.WaitAndReturn(); + } [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); + { + var barrier = RunnerBarrier.Get(); + host.Filter(userData, filter, handler, ParallelRunner.Default, barrier); + barrier.WaitAndReturn(); + } #endregion // ParallelRunner diff --git a/Sia/Entities/Extensions/EntityHostExtensions.Handle.cs b/Sia/Entities/Extensions/EntityHostExtensions.Handle.cs index 3e8a2d7..3ca1497 100644 --- a/Sia/Entities/Extensions/EntityHostExtensions.Handle.cs +++ b/Sia/Entities/Extensions/EntityHostExtensions.Handle.cs @@ -11,7 +11,7 @@ private readonly record struct HandleData( [MethodImpl(MethodImplOptions.AggressiveInlining)] public static unsafe void Handle( - this IEntityHost host, EntityHostRangeHandler handler, TRunner runner, RunnerBarrier barrier) + this IEntityHost host, EntityHostRangeHandler handler, TRunner runner, RunnerBarrier? barrier) where TRunner : IRunner { var count = host.Count; @@ -24,20 +24,10 @@ public static unsafe void Handle( barrier); } - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static unsafe void Handle( - this IEntityHost host, EntityHostRangeHandler handler, TRunner runner) - where TRunner : IRunner - { - var barrier = RunnerBarrier.Get(); - host.Handle(handler, runner, barrier); - barrier.WaitAndReturn(); - } - [MethodImpl(MethodImplOptions.AggressiveInlining)] public static unsafe void Handle( this IEntityHost host, in TData userData, EntityHostRangeHandler handler, - TRunner runner, RunnerBarrier barrier) + TRunner runner, RunnerBarrier? barrier) where TRunner : IRunner { var count = host.Count; @@ -50,23 +40,39 @@ public static unsafe void Handle( barrier); } + #region CurrentThreadRunner + [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static unsafe void Handle( - this IEntityHost host, in TData userData, EntityHostRangeHandler handler, TRunner runner) - where TRunner : IRunner - { - var barrier = RunnerBarrier.Get(); - host.Handle(userData, handler, runner, barrier); - barrier.WaitAndReturn(); - } + public static unsafe void Handle( + this IEntityHost host, EntityHostRangeHandler handler) + => host.Handle(handler, CurrentThreadRunner.Instance, barrier: null); + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static unsafe void Handle( + this IEntityHost host, in TData data, EntityHostRangeHandler handler) + => host.Handle(data, handler, CurrentThreadRunner.Instance, barrier: null); + + #endregion // CurrentThreadRunner + + #region ParallelRunner [MethodImpl(MethodImplOptions.AggressiveInlining)] public static unsafe void HandleOnParallel( this IEntityHost host, EntityHostRangeHandler handler) - => host.Handle(handler, ParallelRunner.Default); + { + var barrier = RunnerBarrier.Get(); + host.Handle(handler, ParallelRunner.Default, barrier); + barrier.WaitAndReturn(); + } [MethodImpl(MethodImplOptions.AggressiveInlining)] public static unsafe void HandleOnParallel( this IEntityHost host, in TData data, EntityHostRangeHandler handler) - => host.Handle(data, handler, ParallelRunner.Default); + { + var barrier = RunnerBarrier.Get(); + host.Handle(data, handler, ParallelRunner.Default, barrier); + barrier.WaitAndReturn(); + } + + #endregion // ParallelRunner } \ No newline at end of file diff --git a/Sia/Entities/Extensions/EntityHostExtensions.Record.cs b/Sia/Entities/Extensions/EntityHostExtensions.Record.cs index 3a50c0a..fc084ec 100644 --- a/Sia/Entities/Extensions/EntityHostExtensions.Record.cs +++ b/Sia/Entities/Extensions/EntityHostExtensions.Record.cs @@ -9,7 +9,7 @@ public static partial class EntityHostExtensions #region EntityRecorder public unsafe static void Record( - this IEntityHost host, Span span, EntityRecorder recorder, TRunner runner) + this IEntityHost host, Span span, EntityRecorder recorder, TRunner runner, RunnerBarrier? barrier) where TRunner : IRunner { GuardSpanLength(span, host.Count); @@ -33,12 +33,12 @@ public unsafe static void Record( recorder(new(slots[i], host), out *(pointer + Interlocked.Increment(ref index))); } - }, runner); + }, runner, barrier); } } public unsafe static void Record( - this IEntityHost host, Span span, in TData userData, EntityRecorder recorder, TRunner runner) + this IEntityHost host, Span span, in TData userData, EntityRecorder recorder, TRunner runner, RunnerBarrier? barrier) where TRunner : IRunner { GuardSpanLength(span, host.Count); @@ -63,7 +63,7 @@ public unsafe static void Record( recorder(userData, new(slots[i], host), out *(pointer + Interlocked.Increment(ref index))); } - }, runner); + }, runner, barrier); } } @@ -71,23 +71,23 @@ private static void IdEntityRecorder(in EntityRef entity, out EntityRef result) => result = entity; public unsafe static void Record( - this IEntityHost host, Span span, TRunner runner) + this IEntityHost host, Span span, TRunner runner, RunnerBarrier? barrier) where TRunner : IRunner - => host.Record(span, IdEntityRecorder, runner); + => host.Record(span, IdEntityRecorder, runner, barrier); #region CurrentThreadRunner public unsafe static void Record( this IEntityHost host, Span span, EntityRecorder recorder) - => host.Record(span, recorder, CurrentThreadRunner.Instance); + => host.Record(span, recorder, CurrentThreadRunner.Instance, barrier: null); public unsafe static void Record( this IEntityHost host, Span span, in TData userData, EntityRecorder recorder) - => host.Record(span, userData, recorder, CurrentThreadRunner.Instance); + => host.Record(span, userData, recorder, CurrentThreadRunner.Instance, barrier: null); public unsafe static void Record( this IEntityHost host, Span span) - => host.Record(span, IdEntityRecorder, CurrentThreadRunner.Instance); + => host.Record(span, IdEntityRecorder, CurrentThreadRunner.Instance, barrier: null); #endregion // CurrentThreadRunner @@ -95,15 +95,27 @@ public unsafe static void Record( public unsafe static void RecordOnParallel( this IEntityHost host, Span span, EntityRecorder recorder) - => host.Record(span, recorder, ParallelRunner.Default); + { + var barrier = RunnerBarrier.Get(); + host.Record(span, recorder, ParallelRunner.Default, barrier); + barrier.WaitAndReturn(); + } public unsafe static void RecordOnParallel( this IEntityHost host, Span span, in TData userData, EntityRecorder recorder) - => host.Record(span, userData, recorder, ParallelRunner.Default); + { + var barrier = RunnerBarrier.Get(); + host.Record(span, userData, recorder, ParallelRunner.Default, barrier); + barrier.WaitAndReturn(); + } public unsafe static void RecordOnParallel( this IEntityHost host, Span span) - => host.Record(span, IdEntityRecorder, ParallelRunner.Default); + { + var barrier = RunnerBarrier.Get(); + host.Record(span, IdEntityRecorder, ParallelRunner.Default, barrier); + barrier.WaitAndReturn(); + } #endregion // ParallelRunner @@ -112,7 +124,7 @@ public unsafe static void RecordOnParallel( #region ComponentRecorder public unsafe static void RecordSlices( - this IEntityHost host, Span span, ComponentRecorder recorder, TRunner runner) + this IEntityHost host, Span span, ComponentRecorder recorder, TRunner runner, RunnerBarrier? barrier) where TRunner : IRunner { GuardSpanLength(span, host.Count); @@ -129,12 +141,12 @@ public unsafe static void RecordSlices( static (in CompRecordData data, ref C1 c1) => { data.Recorder(ref c1, out *(data.Pointer + Interlocked.Increment(ref *data.Index))); - }, runner); + }, runner, barrier); } } public unsafe static void RecordSlices( - this IEntityHost host, Span span, ComponentRecorder recorder, TRunner runner) + this IEntityHost host, Span span, ComponentRecorder recorder, TRunner runner, RunnerBarrier? barrier) where TRunner : IRunner { GuardSpanLength(span, host.Count); @@ -151,12 +163,12 @@ public unsafe static void RecordSlices( static (in CompRecordData data, ref C1 c1, ref C2 c2) => { data.Recorder(ref c1, ref c2, out *(data.Pointer + Interlocked.Increment(ref *data.Index))); - }, runner); + }, runner, barrier); } } public unsafe static void RecordSlices( - this IEntityHost host, Span span, ComponentRecorder recorder, TRunner runner) + this IEntityHost host, Span span, ComponentRecorder recorder, TRunner runner, RunnerBarrier? barrier) where TRunner : IRunner { GuardSpanLength(span, host.Count); @@ -173,12 +185,12 @@ public unsafe static void RecordSlices( static (in CompRecordData data, ref C1 c1, ref C2 c2, ref C3 c3) => { data.Recorder(ref c1, ref c2, ref c3, out *(data.Pointer + Interlocked.Increment(ref *data.Index))); - }, runner); + }, runner, barrier); } } public unsafe static void RecordSlices( - this IEntityHost host, Span span, ComponentRecorder recorder, TRunner runner) + this IEntityHost host, Span span, ComponentRecorder recorder, TRunner runner, RunnerBarrier? barrier) where TRunner : IRunner { GuardSpanLength(span, host.Count); @@ -195,12 +207,12 @@ public unsafe static void RecordSlices( static (in CompRecordData data, ref C1 c1, ref C2 c2, ref C3 c3, ref C4 c4) => { data.Recorder(ref c1, ref c2, ref c3, ref c4, out *(data.Pointer + Interlocked.Increment(ref *data.Index))); - }, runner); + }, runner, barrier); } } public unsafe static void RecordSlices( - this IEntityHost host, Span span, ComponentRecorder recorder, TRunner runner) + this IEntityHost host, Span span, ComponentRecorder recorder, TRunner runner, RunnerBarrier? barrier) where TRunner : IRunner { GuardSpanLength(span, host.Count); @@ -217,12 +229,12 @@ public unsafe static void RecordSlices( static (in CompRecordData data, ref C1 c1, ref C2 c2, ref C3 c3, ref C4 c4, ref C5 c5) => { data.Recorder(ref c1, ref c2, ref c3, ref c4, ref c5, out *(data.Pointer + Interlocked.Increment(ref *data.Index))); - }, runner); + }, runner, barrier); } } public unsafe static void RecordSlices( - this IEntityHost host, Span span, ComponentRecorder recorder, TRunner runner) + this IEntityHost host, Span span, ComponentRecorder recorder, TRunner runner, RunnerBarrier? barrier) where TRunner : IRunner { GuardSpanLength(span, host.Count); @@ -239,12 +251,12 @@ public unsafe static void RecordSlices static (in CompRecordData data, ref C1 c1, ref C2 c2, ref C3 c3, ref C4 c4, ref C5 c5, ref C6 c6) => { data.Recorder(ref c1, ref c2, ref c3, ref c4, ref c5, ref c6, out *(data.Pointer + Interlocked.Increment(ref *data.Index))); - }, runner); + }, runner, barrier); } } public unsafe static void RecordSlices( - this IEntityHost host, Span span, in TData userData, DataComponentRecorder recorder, TRunner runner) + this IEntityHost host, Span span, in TData userData, DataComponentRecorder recorder, TRunner runner, RunnerBarrier? barrier) where TRunner : IRunner { GuardSpanLength(span, host.Count); @@ -263,12 +275,12 @@ public unsafe static void RecordSlices( data.Recorder(data.UserData, ref c1, out *(data.Pointer + Interlocked.Increment(ref *data.Index))); - }, runner); + }, runner, barrier); } } public unsafe static void RecordSlices( - this IEntityHost host, Span span, in TData userData, DataComponentRecorder recorder, TRunner runner) + this IEntityHost host, Span span, in TData userData, DataComponentRecorder recorder, TRunner runner, RunnerBarrier? barrier) where TRunner : IRunner { GuardSpanLength(span, host.Count); @@ -287,12 +299,12 @@ public unsafe static void RecordSlices( data.Recorder(data.UserData, ref c1, ref c2, out *(data.Pointer + Interlocked.Increment(ref *data.Index))); - }, runner); + }, runner, barrier); } } public unsafe static void RecordSlices( - this IEntityHost host, Span span, in TData userData, DataComponentRecorder recorder, TRunner runner) + this IEntityHost host, Span span, in TData userData, DataComponentRecorder recorder, TRunner runner, RunnerBarrier? barrier) where TRunner : IRunner { GuardSpanLength(span, host.Count); @@ -311,12 +323,12 @@ public unsafe static void RecordSlices( data.Recorder(data.UserData, ref c1, ref c2, ref c3, out *(data.Pointer + Interlocked.Increment(ref *data.Index))); - }, runner); + }, runner, barrier); } } public unsafe static void RecordSlices( - this IEntityHost host, Span span, in TData userData, DataComponentRecorder recorder, TRunner runner) + this IEntityHost host, Span span, in TData userData, DataComponentRecorder recorder, TRunner runner, RunnerBarrier? barrier) where TRunner : IRunner { GuardSpanLength(span, host.Count); @@ -335,12 +347,12 @@ public unsafe static void RecordSlices( data.Recorder(data.UserData, ref c1, ref c2, ref c3, ref c4, out *(data.Pointer + Interlocked.Increment(ref *data.Index))); - }, runner); + }, runner, barrier); } } public unsafe static void RecordSlices( - this IEntityHost host, Span span, in TData userData, DataComponentRecorder recorder, TRunner runner) + this IEntityHost host, Span span, in TData userData, DataComponentRecorder recorder, TRunner runner, RunnerBarrier? barrier) where TRunner : IRunner { GuardSpanLength(span, host.Count); @@ -359,12 +371,12 @@ public unsafe static void RecordSlices( - this IEntityHost host, Span span, in TData userData, DataComponentRecorder recorder, TRunner runner) + this IEntityHost host, Span span, in TData userData, DataComponentRecorder recorder, TRunner runner, RunnerBarrier? barrier) where TRunner : IRunner { GuardSpanLength(span, host.Count); @@ -383,7 +395,7 @@ public unsafe static void RecordSlices( this IEntityHost host, Span span, ComponentRecorder recorder) - => host.RecordSlices(span, recorder, CurrentThreadRunner.Instance); + => host.RecordSlices(span, recorder, CurrentThreadRunner.Instance, barrier: null); public unsafe static void RecordSlices( this IEntityHost host, Span span, ComponentRecorder recorder) - => host.RecordSlices(span, recorder, CurrentThreadRunner.Instance); + => host.RecordSlices(span, recorder, CurrentThreadRunner.Instance, barrier: null); public unsafe static void RecordSlices( this IEntityHost host, Span span, ComponentRecorder recorder) - => host.RecordSlices(span, recorder, CurrentThreadRunner.Instance); + => host.RecordSlices(span, recorder, CurrentThreadRunner.Instance, barrier: null); public unsafe static void RecordSlices( this IEntityHost host, Span span, ComponentRecorder recorder) - => host.RecordSlices(span, recorder, CurrentThreadRunner.Instance); + => host.RecordSlices(span, recorder, CurrentThreadRunner.Instance, barrier: null); public unsafe static void RecordSlices( this IEntityHost host, Span span, ComponentRecorder recorder) - => host.RecordSlices(span, recorder, CurrentThreadRunner.Instance); + => host.RecordSlices(span, recorder, CurrentThreadRunner.Instance, barrier: null); public unsafe static void RecordSlices( this IEntityHost host, Span span, ComponentRecorder recorder) - => host.RecordSlices(span, recorder, CurrentThreadRunner.Instance); + => host.RecordSlices(span, recorder, CurrentThreadRunner.Instance, barrier: null); public unsafe static void RecordSlices( this IEntityHost host, Span span, in TData userData, DataComponentRecorder recorder) - => host.RecordSlices(span, userData, recorder, CurrentThreadRunner.Instance); + => host.RecordSlices(span, userData, recorder, CurrentThreadRunner.Instance, barrier: null); public unsafe static void RecordSlices( this IEntityHost host, Span span, in TData userData, DataComponentRecorder recorder) - => host.RecordSlices(span, userData, recorder, CurrentThreadRunner.Instance); + => host.RecordSlices(span, userData, recorder, CurrentThreadRunner.Instance, barrier: null); public unsafe static void RecordSlices( this IEntityHost host, Span span, in TData userData, DataComponentRecorder recorder) - => host.RecordSlices(span, userData, recorder, CurrentThreadRunner.Instance); + => host.RecordSlices(span, userData, recorder, CurrentThreadRunner.Instance, barrier: null); public unsafe static void RecordSlices( this IEntityHost host, Span span, in TData userData, DataComponentRecorder recorder) - => host.RecordSlices(span, userData, recorder, CurrentThreadRunner.Instance); + => host.RecordSlices(span, userData, recorder, CurrentThreadRunner.Instance, barrier: null); public unsafe static void RecordSlices( this IEntityHost host, Span span, in TData userData, DataComponentRecorder recorder) - => host.RecordSlices(span, userData, recorder, CurrentThreadRunner.Instance); + => host.RecordSlices(span, userData, recorder, CurrentThreadRunner.Instance, barrier: null); public unsafe static void RecordSlices( this IEntityHost host, Span span, in TData userData, DataComponentRecorder recorder) - => host.RecordSlices(span, userData, recorder, CurrentThreadRunner.Instance); + => host.RecordSlices(span, userData, recorder, CurrentThreadRunner.Instance, barrier: null); #endregion // CurrentThreadRunner @@ -443,51 +455,99 @@ public unsafe static void RecordSlices( public unsafe static void RecordSlicesOnParallel( this IEntityHost host, Span span, ComponentRecorder recorder) - => host.RecordSlices(span, recorder, ParallelRunner.Default); + { + var barrier = RunnerBarrier.Get(); + host.RecordSlices(span, recorder, ParallelRunner.Default, barrier); + barrier.WaitAndReturn(); + } public unsafe static void RecordSlicesOnParallel( this IEntityHost host, Span span, ComponentRecorder recorder) - => host.RecordSlices(span, recorder, ParallelRunner.Default); + { + var barrier = RunnerBarrier.Get(); + host.RecordSlices(span, recorder, ParallelRunner.Default, barrier); + barrier.WaitAndReturn(); + } public unsafe static void RecordSlicesOnParallel( this IEntityHost host, Span span, ComponentRecorder recorder) - => host.RecordSlices(span, recorder, ParallelRunner.Default); + { + var barrier = RunnerBarrier.Get(); + host.RecordSlices(span, recorder, ParallelRunner.Default, barrier); + barrier.WaitAndReturn(); + } public unsafe static void RecordSlicesOnParallel( this IEntityHost host, Span span, ComponentRecorder recorder) - => host.RecordSlices(span, recorder, ParallelRunner.Default); + { + var barrier = RunnerBarrier.Get(); + host.RecordSlices(span, recorder, ParallelRunner.Default, barrier); + barrier.WaitAndReturn(); + } public unsafe static void RecordSlicesOnParallel( this IEntityHost host, Span span, ComponentRecorder recorder) - => host.RecordSlices(span, recorder, ParallelRunner.Default); + { + var barrier = RunnerBarrier.Get(); + host.RecordSlices(span, recorder, ParallelRunner.Default, barrier); + barrier.WaitAndReturn(); + } public unsafe static void RecordSlicesOnParallel( this IEntityHost host, Span span, ComponentRecorder recorder) - => host.RecordSlices(span, recorder, ParallelRunner.Default); + { + var barrier = RunnerBarrier.Get(); + host.RecordSlices(span, recorder, ParallelRunner.Default, barrier); + barrier.WaitAndReturn(); + } public unsafe static void RecordSlicesOnParallel( this IEntityHost host, Span span, in TData userData, DataComponentRecorder recorder) - => host.RecordSlices(span, userData, recorder, ParallelRunner.Default); + { + var barrier = RunnerBarrier.Get(); + host.RecordSlices(span, userData, recorder, ParallelRunner.Default, barrier); + barrier.WaitAndReturn(); + } public unsafe static void RecordSlicesOnParallel( this IEntityHost host, Span span, in TData userData, DataComponentRecorder recorder) - => host.RecordSlices(span, userData, recorder, ParallelRunner.Default); + { + var barrier = RunnerBarrier.Get(); + host.RecordSlices(span, userData, recorder, ParallelRunner.Default, barrier); + barrier.WaitAndReturn(); + } public unsafe static void RecordSlicesOnParallel( this IEntityHost host, Span span, in TData userData, DataComponentRecorder recorder) - => host.RecordSlices(span, userData, recorder, ParallelRunner.Default); + { + var barrier = RunnerBarrier.Get(); + host.RecordSlices(span, userData, recorder, ParallelRunner.Default, barrier); + barrier.WaitAndReturn(); + } public unsafe static void RecordSlicesOnParallel( this IEntityHost host, Span span, in TData userData, DataComponentRecorder recorder) - => host.RecordSlices(span, userData, recorder, ParallelRunner.Default); + { + var barrier = RunnerBarrier.Get(); + host.RecordSlices(span, userData, recorder, ParallelRunner.Default, barrier); + barrier.WaitAndReturn(); + } public unsafe static void RecordSlicesOnParallel( this IEntityHost host, Span span, in TData userData, DataComponentRecorder recorder) - => host.RecordSlices(span, userData, recorder, ParallelRunner.Default); + { + var barrier = RunnerBarrier.Get(); + host.RecordSlices(span, userData, recorder, ParallelRunner.Default, barrier); + barrier.WaitAndReturn(); + } public unsafe static void RecordSlicesOnParallel( this IEntityHost host, Span span, in TData userData, DataComponentRecorder recorder) - => host.RecordSlices(span, userData, recorder, ParallelRunner.Default); + { + var barrier = RunnerBarrier.Get(); + host.RecordSlices(span, userData, recorder, ParallelRunner.Default, barrier); + barrier.WaitAndReturn(); + } #endregion // ParallelRunner #endregion // ComponentRecorder diff --git a/Sia/Entities/Extensions/EntityQueryExtensions.ForEach.cs b/Sia/Entities/Extensions/EntityQueryExtensions.ForEach.cs index 0060f4c..d4afef7 100644 --- a/Sia/Entities/Extensions/EntityQueryExtensions.ForEach.cs +++ b/Sia/Entities/Extensions/EntityQueryExtensions.ForEach.cs @@ -8,7 +8,7 @@ public static partial class EntityQueryExtensions [MethodImpl(MethodImplOptions.AggressiveInlining)] public static unsafe void ForEach( - this IEntityQuery query, EntityHandler handler, TRunner runner) + this IEntityQuery query, EntityHandler handler, TRunner runner, RunnerBarrier? barrier) where TRunner : IRunner => query.Handle(handler, static (IEntityHost host, in EntityHandler handler, int from, int to) => { @@ -16,11 +16,11 @@ public static unsafe void ForEach( for (int i = from; i != to; ++i) { handler(new(slosts[i], host)); } - }, runner); + }, runner, barrier); [MethodImpl(MethodImplOptions.AggressiveInlining)] public static unsafe void ForEach( - this IEntityQuery query, in TData userData, EntityHandler handler, TRunner runner) + this IEntityQuery query, in TData userData, EntityHandler handler, TRunner runner, RunnerBarrier? barrier) where TRunner : IRunner => query.Handle((userData, handler), static (IEntityHost host, in (TData, EntityHandler) entry, int from, int to) => { @@ -30,43 +30,43 @@ public static unsafe void ForEach( for (int i = from; i != to; ++i) { handler(data, new(slosts[i], host)); } - }, runner); + }, runner, barrier); [MethodImpl(MethodImplOptions.AggressiveInlining)] public static unsafe void ForEach( - this IEntityQuery query, SimpleEntityHandler handler, TRunner runner) + this IEntityQuery query, SimpleEntityHandler handler, TRunner runner, RunnerBarrier? barrier) where TRunner : IRunner => query.ForEach(handler, static (in SimpleEntityHandler handler, in EntityRef entity) - => handler(entity), runner); + => handler(entity), runner, barrier); [MethodImpl(MethodImplOptions.AggressiveInlining)] public static unsafe void ForEach( - this IEntityQuery query, in TData userData, SimpleEntityHandler handler, TRunner runner) + this IEntityQuery query, in TData userData, SimpleEntityHandler handler, TRunner runner, RunnerBarrier? barrier) where TRunner : IRunner => query.ForEach((handler, userData), static (in (SimpleEntityHandler, TData) data, in EntityRef entity) - => data.Item1(data.Item2, entity), runner); + => data.Item1(data.Item2, entity), runner, barrier); #region CurrentThreadRunner [MethodImpl(MethodImplOptions.AggressiveInlining)] public static unsafe void ForEach(this IEntityQuery query, EntityHandler handler) - => query.ForEach(handler, CurrentThreadRunner.Instance); + => query.ForEach(handler, CurrentThreadRunner.Instance, barrier: null); [MethodImpl(MethodImplOptions.AggressiveInlining)] public static unsafe void ForEach( this IEntityQuery query, in TData data, EntityHandler handler) - => query.ForEach(data, handler, CurrentThreadRunner.Instance); + => query.ForEach(data, handler, CurrentThreadRunner.Instance, barrier: null); [MethodImpl(MethodImplOptions.AggressiveInlining)] public static unsafe void ForEach(this IEntityQuery query, SimpleEntityHandler handler) - => query.ForEach(handler, CurrentThreadRunner.Instance); + => query.ForEach(handler, CurrentThreadRunner.Instance, barrier: null); [MethodImpl(MethodImplOptions.AggressiveInlining)] public static unsafe void ForEach( this IEntityQuery query, in TData data, SimpleEntityHandler handler) - => query.ForEach(data, handler, CurrentThreadRunner.Instance); + => query.ForEach(data, handler, CurrentThreadRunner.Instance, barrier: null); #endregion // CurrentThreadRunner @@ -74,21 +74,37 @@ public static unsafe void ForEach( [MethodImpl(MethodImplOptions.AggressiveInlining)] public static unsafe void ForEachOnParallel(this IEntityQuery query, EntityHandler handler) - => query.ForEach(handler, ParallelRunner.Default); + { + var barrier = RunnerBarrier.Get(); + query.ForEach(handler, ParallelRunner.Default, barrier); + barrier.WaitAndReturn(); + } [MethodImpl(MethodImplOptions.AggressiveInlining)] public static unsafe void ForEachOnParallel( this IEntityQuery query, in TData data, EntityHandler handler) - => query.ForEach(data, handler, ParallelRunner.Default); + { + var barrier = RunnerBarrier.Get(); + query.ForEach(data, handler, ParallelRunner.Default, barrier); + barrier.WaitAndReturn(); + } [MethodImpl(MethodImplOptions.AggressiveInlining)] public static unsafe void ForEachOnParallel(this IEntityQuery query, SimpleEntityHandler handler) - => query.ForEach(handler, ParallelRunner.Default); + { + var barrier = RunnerBarrier.Get(); + query.ForEach(handler, ParallelRunner.Default, barrier); + barrier.WaitAndReturn(); + } [MethodImpl(MethodImplOptions.AggressiveInlining)] public static unsafe void ForEachOnParallel( this IEntityQuery query, in TData data, SimpleEntityHandler handler) - => query.ForEach(data, handler, ParallelRunner.Default); + { + var barrier = RunnerBarrier.Get(); + query.ForEach(data, handler, ParallelRunner.Default, barrier); + barrier.WaitAndReturn(); + } #endregion // ParallelRunner @@ -98,7 +114,7 @@ public static unsafe void ForEachOnParallel( [MethodImpl(MethodImplOptions.AggressiveInlining)] public unsafe static void ForSlice( - this IEntityQuery query, ComponentHandler handler, TRunner runner) + this IEntityQuery query, ComponentHandler handler, TRunner runner, RunnerBarrier? barrier) where TRunner : IRunner => query.Handle(handler, static (IEntityHost host, in ComponentHandler handler, int from, int to) => { @@ -111,11 +127,11 @@ public unsafe static void ForSlice( ref var byteRef = ref host.UnsafeGetByteRef(slots[i]); handler(ref c1Offset.Get(ref byteRef)); } - }, runner); + }, runner, barrier); [MethodImpl(MethodImplOptions.AggressiveInlining)] public unsafe static void ForSlice( - this IEntityQuery query, ComponentHandler handler, TRunner runner) + this IEntityQuery query, ComponentHandler handler, TRunner runner, RunnerBarrier? barrier) where TRunner : IRunner => query.Handle(handler, static (IEntityHost host, in ComponentHandler handler, int from, int to) => { @@ -131,11 +147,11 @@ public unsafe static void ForSlice( ref c1Offset.Get(ref byteRef), ref c2Offset.Get(ref byteRef)); } - }, runner); + }, runner, barrier); [MethodImpl(MethodImplOptions.AggressiveInlining)] public unsafe static void ForSlice( - this IEntityQuery query, ComponentHandler handler, TRunner runner) + this IEntityQuery query, ComponentHandler handler, TRunner runner, RunnerBarrier? barrier) where TRunner : IRunner => query.Handle(handler, static (IEntityHost host, in ComponentHandler handler, int from, int to) => { @@ -153,11 +169,11 @@ ref c1Offset.Get(ref byteRef), ref c2Offset.Get(ref byteRef), ref c3Offset.Get(ref byteRef)); } - }, runner); + }, runner, barrier); [MethodImpl(MethodImplOptions.AggressiveInlining)] public unsafe static void ForSlice( - this IEntityQuery query, ComponentHandler handler, TRunner runner) + this IEntityQuery query, ComponentHandler handler, TRunner runner, RunnerBarrier? barrier) where TRunner : IRunner => query.Handle(handler, static (IEntityHost host, in ComponentHandler handler, int from, int to) => { @@ -177,11 +193,11 @@ ref c2Offset.Get(ref byteRef), ref c3Offset.Get(ref byteRef), ref c4Offset.Get(ref byteRef)); } - }, runner); + }, runner, barrier); [MethodImpl(MethodImplOptions.AggressiveInlining)] public unsafe static void ForSlice( - this IEntityQuery query, ComponentHandler handler, TRunner runner) + this IEntityQuery query, ComponentHandler handler, TRunner runner, RunnerBarrier? barrier) where TRunner : IRunner => query.Handle(handler, static (IEntityHost host, in ComponentHandler handler, int from, int to) => { @@ -203,11 +219,11 @@ ref c3Offset.Get(ref byteRef), ref c4Offset.Get(ref byteRef), ref c5Offset.Get(ref byteRef)); } - }, runner); + }, runner, barrier); [MethodImpl(MethodImplOptions.AggressiveInlining)] public unsafe static void ForSlice( - this IEntityQuery query, ComponentHandler handler, TRunner runner) + this IEntityQuery query, ComponentHandler handler, TRunner runner, RunnerBarrier? barrier) where TRunner : IRunner => query.Handle(handler, static (IEntityHost host, in ComponentHandler handler, int from, int to) => { @@ -231,11 +247,11 @@ ref c4Offset.Get(ref byteRef), ref c5Offset.Get(ref byteRef), ref c6Offset.Get(ref byteRef)); } - }, runner); + }, runner, barrier); [MethodImpl(MethodImplOptions.AggressiveInlining)] public unsafe static void ForSlice( - this IEntityQuery query, in TData userData, DataComponentHandler handler, TRunner runner) + this IEntityQuery query, in TData userData, DataComponentHandler handler, TRunner runner, RunnerBarrier? barrier) where TRunner : IRunner => query.Handle((handler, userData), static (IEntityHost host, in (DataComponentHandler, TData) data, int from, int to) => { @@ -251,11 +267,11 @@ public unsafe static void ForSlice( ref var byteRef = ref host.UnsafeGetByteRef(slots[i]); handler(userData, ref c1Offset.Get(ref byteRef)); } - }, runner); + }, runner, barrier); [MethodImpl(MethodImplOptions.AggressiveInlining)] public unsafe static void ForSlice( - this IEntityQuery query, in TData userData, DataComponentHandler handler, TRunner runner) + this IEntityQuery query, in TData userData, DataComponentHandler handler, TRunner runner, RunnerBarrier? barrier) where TRunner : IRunner => query.Handle((handler, userData), static (IEntityHost host, in (DataComponentHandler, TData) data, int from, int to) => { @@ -274,11 +290,11 @@ public unsafe static void ForSlice( ref c1Offset.Get(ref byteRef), ref c2Offset.Get(ref byteRef)); } - }, runner); + }, runner, barrier); [MethodImpl(MethodImplOptions.AggressiveInlining)] public unsafe static void ForSlice( - this IEntityQuery query, in TData userData, DataComponentHandler handler, TRunner runner) + this IEntityQuery query, in TData userData, DataComponentHandler handler, TRunner runner, RunnerBarrier? barrier) where TRunner : IRunner => query.Handle((handler, userData), static (IEntityHost host, in (DataComponentHandler, TData) data, int from, int to) => { @@ -299,11 +315,11 @@ ref c1Offset.Get(ref byteRef), ref c2Offset.Get(ref byteRef), ref c3Offset.Get(ref byteRef)); } - }, runner); + }, runner, barrier); [MethodImpl(MethodImplOptions.AggressiveInlining)] public unsafe static void ForSlice( - this IEntityQuery query, in TData userData, DataComponentHandler handler, TRunner runner) + this IEntityQuery query, in TData userData, DataComponentHandler handler, TRunner runner, RunnerBarrier? barrier) where TRunner : IRunner => query.Handle((handler, userData), static (IEntityHost host, in (DataComponentHandler, TData) data, int from, int to) => { @@ -326,11 +342,11 @@ ref c2Offset.Get(ref byteRef), ref c3Offset.Get(ref byteRef), ref c4Offset.Get(ref byteRef)); } - }, runner); + }, runner, barrier); [MethodImpl(MethodImplOptions.AggressiveInlining)] public unsafe static void ForSlice( - this IEntityQuery query, in TData userData, DataComponentHandler handler, TRunner runner) + this IEntityQuery query, in TData userData, DataComponentHandler handler, TRunner runner, RunnerBarrier? barrier) where TRunner : IRunner => query.Handle((handler, userData), static (IEntityHost host, in (DataComponentHandler, TData) data, int from, int to) => { @@ -355,11 +371,11 @@ ref c3Offset.Get(ref byteRef), ref c4Offset.Get(ref byteRef), ref c5Offset.Get(ref byteRef)); } - }, runner); + }, runner, barrier); [MethodImpl(MethodImplOptions.AggressiveInlining)] public unsafe static void ForSlice( - this IEntityQuery query, in TData userData, DataComponentHandler handler, TRunner runner) + this IEntityQuery query, in TData userData, DataComponentHandler handler, TRunner runner, RunnerBarrier? barrier) where TRunner : IRunner => query.Handle((handler, userData), static (IEntityHost host, in (DataComponentHandler, TData) data, int from, int to) => { @@ -386,133 +402,181 @@ ref c4Offset.Get(ref byteRef), ref c5Offset.Get(ref byteRef), ref c6Offset.Get(ref byteRef)); } - }, runner); + }, runner, barrier); #region CurrentThreadRunner [MethodImpl(MethodImplOptions.AggressiveInlining)] public unsafe static void ForSlice( this IEntityQuery query, ComponentHandler handler) - => query.ForSlice(handler, CurrentThreadRunner.Instance); + => query.ForSlice(handler, CurrentThreadRunner.Instance, barrier: null); [MethodImpl(MethodImplOptions.AggressiveInlining)] public unsafe static void ForSlice( this IEntityQuery query, ComponentHandler handler) - => query.ForSlice(handler, CurrentThreadRunner.Instance); + => query.ForSlice(handler, CurrentThreadRunner.Instance, barrier: null); [MethodImpl(MethodImplOptions.AggressiveInlining)] public unsafe static void ForSlice( this IEntityQuery query, ComponentHandler handler) - => query.ForSlice(handler, CurrentThreadRunner.Instance); + => query.ForSlice(handler, CurrentThreadRunner.Instance, barrier: null); [MethodImpl(MethodImplOptions.AggressiveInlining)] public unsafe static void ForSlice( this IEntityQuery query, ComponentHandler handler) - => query.ForSlice(handler, CurrentThreadRunner.Instance); + => query.ForSlice(handler, CurrentThreadRunner.Instance, barrier: null); [MethodImpl(MethodImplOptions.AggressiveInlining)] public unsafe static void ForSlice( this IEntityQuery query, ComponentHandler handler) - => query.ForSlice(handler, CurrentThreadRunner.Instance); + => query.ForSlice(handler, CurrentThreadRunner.Instance, barrier: null); [MethodImpl(MethodImplOptions.AggressiveInlining)] public unsafe static void ForSlice( this IEntityQuery query, ComponentHandler handler) - => query.ForSlice(handler, CurrentThreadRunner.Instance); + => query.ForSlice(handler, CurrentThreadRunner.Instance, barrier: null); [MethodImpl(MethodImplOptions.AggressiveInlining)] public unsafe static void ForSlice( this IEntityQuery query, in TData userData, DataComponentHandler handler) - => query.ForSlice(userData, handler, CurrentThreadRunner.Instance); + => query.ForSlice(userData, handler, CurrentThreadRunner.Instance, barrier: null); [MethodImpl(MethodImplOptions.AggressiveInlining)] public unsafe static void ForSlice( this IEntityQuery query, in TData userData, DataComponentHandler handler) - => query.ForSlice(userData, handler, CurrentThreadRunner.Instance); + => query.ForSlice(userData, handler, CurrentThreadRunner.Instance, barrier: null); [MethodImpl(MethodImplOptions.AggressiveInlining)] public unsafe static void ForSlice( this IEntityQuery query, in TData userData, DataComponentHandler handler) - => query.ForSlice(userData, handler, CurrentThreadRunner.Instance); + => query.ForSlice(userData, handler, CurrentThreadRunner.Instance, barrier: null); [MethodImpl(MethodImplOptions.AggressiveInlining)] public unsafe static void ForSlice( this IEntityQuery query, in TData userData, DataComponentHandler handler) - => query.ForSlice(userData, handler, CurrentThreadRunner.Instance); + => query.ForSlice(userData, handler, CurrentThreadRunner.Instance, barrier: null); [MethodImpl(MethodImplOptions.AggressiveInlining)] public unsafe static void ForSlice( this IEntityQuery query, in TData userData, DataComponentHandler handler) - => query.ForSlice(userData, handler, CurrentThreadRunner.Instance); + => query.ForSlice(userData, handler, CurrentThreadRunner.Instance, barrier: null); [MethodImpl(MethodImplOptions.AggressiveInlining)] public unsafe static void ForSlice( this IEntityQuery query, in TData userData, DataComponentHandler handler) - => query.ForSlice(userData, handler, CurrentThreadRunner.Instance); + => query.ForSlice(userData, handler, CurrentThreadRunner.Instance, barrier: null); - #endregion // ParallelRunner + #endregion // CurrentThreadRunner #region ParallelRunner [MethodImpl(MethodImplOptions.AggressiveInlining)] public unsafe static void ForSliceOnParallel( this IEntityQuery query, ComponentHandler handler) - => query.ForSlice(handler, ParallelRunner.Default); + { + var barrier = RunnerBarrier.Get(); + query.ForSlice(handler, ParallelRunner.Default, barrier); + barrier.WaitAndReturn(); + } [MethodImpl(MethodImplOptions.AggressiveInlining)] public unsafe static void ForSliceOnParallel( this IEntityQuery query, ComponentHandler handler) - => query.ForSlice(handler, ParallelRunner.Default); + { + var barrier = RunnerBarrier.Get(); + query.ForSlice(handler, ParallelRunner.Default, barrier); + barrier.WaitAndReturn(); + } [MethodImpl(MethodImplOptions.AggressiveInlining)] public unsafe static void ForSliceOnParallel( this IEntityQuery query, ComponentHandler handler) - => query.ForSlice(handler, ParallelRunner.Default); + { + var barrier = RunnerBarrier.Get(); + query.ForSlice(handler, ParallelRunner.Default, barrier); + barrier.WaitAndReturn(); + } [MethodImpl(MethodImplOptions.AggressiveInlining)] public unsafe static void ForSliceOnParallel( this IEntityQuery query, ComponentHandler handler) - => query.ForSlice(handler, ParallelRunner.Default); + { + var barrier = RunnerBarrier.Get(); + query.ForSlice(handler, ParallelRunner.Default, barrier); + barrier.WaitAndReturn(); + } [MethodImpl(MethodImplOptions.AggressiveInlining)] public unsafe static void ForSliceOnParallel( this IEntityQuery query, ComponentHandler handler) - => query.ForSlice(handler, ParallelRunner.Default); + { + var barrier = RunnerBarrier.Get(); + query.ForSlice(handler, ParallelRunner.Default, barrier); + barrier.WaitAndReturn(); + } [MethodImpl(MethodImplOptions.AggressiveInlining)] public unsafe static void ForSliceOnParallel( this IEntityQuery query, ComponentHandler handler) - => query.ForSlice(handler, ParallelRunner.Default); + { + var barrier = RunnerBarrier.Get(); + query.ForSlice(handler, ParallelRunner.Default, barrier); + barrier.WaitAndReturn(); + } [MethodImpl(MethodImplOptions.AggressiveInlining)] public unsafe static void ForSliceOnParallel( this IEntityQuery query, in TData userData, DataComponentHandler handler) - => query.ForSlice(userData, handler, ParallelRunner.Default); + { + var barrier = RunnerBarrier.Get(); + query.ForSlice(userData, handler, ParallelRunner.Default, barrier); + barrier.WaitAndReturn(); + } [MethodImpl(MethodImplOptions.AggressiveInlining)] public unsafe static void ForSliceOnParallel( this IEntityQuery query, in TData userData, DataComponentHandler handler) - => query.ForSlice(userData, handler, ParallelRunner.Default); + { + var barrier = RunnerBarrier.Get(); + query.ForSlice(userData, handler, ParallelRunner.Default, barrier); + barrier.WaitAndReturn(); + } [MethodImpl(MethodImplOptions.AggressiveInlining)] public unsafe static void ForSliceOnParallel( this IEntityQuery query, in TData userData, DataComponentHandler handler) - => query.ForSlice(userData, handler, ParallelRunner.Default); + { + var barrier = RunnerBarrier.Get(); + query.ForSlice(userData, handler, ParallelRunner.Default, barrier); + barrier.WaitAndReturn(); + } [MethodImpl(MethodImplOptions.AggressiveInlining)] public unsafe static void ForSliceOnParallel( this IEntityQuery query, in TData userData, DataComponentHandler handler) - => query.ForSlice(userData, handler, ParallelRunner.Default); + { + var barrier = RunnerBarrier.Get(); + query.ForSlice(userData, handler, ParallelRunner.Default, barrier); + barrier.WaitAndReturn(); + } [MethodImpl(MethodImplOptions.AggressiveInlining)] public unsafe static void ForSliceOnParallel( this IEntityQuery query, in TData userData, DataComponentHandler handler) - => query.ForSlice(userData, handler, ParallelRunner.Default); + { + var barrier = RunnerBarrier.Get(); + query.ForSlice(userData, handler, ParallelRunner.Default, barrier); + barrier.WaitAndReturn(); + } [MethodImpl(MethodImplOptions.AggressiveInlining)] public unsafe static void ForSliceOnParallel( this IEntityQuery query, in TData userData, DataComponentHandler handler) - => query.ForSlice(userData, handler, ParallelRunner.Default); + { + var barrier = RunnerBarrier.Get(); + query.ForSlice(userData, handler, ParallelRunner.Default, barrier); + barrier.WaitAndReturn(); + } #endregion // ParallelRunner @@ -522,7 +586,7 @@ public unsafe static void ForSliceOnParallel( [MethodImpl(MethodImplOptions.AggressiveInlining)] public unsafe static void Filter( - this IEntityQuery query, ComponentFilter filter, EntityHandler handler, TRunner runner) + this IEntityQuery query, ComponentFilter filter, EntityHandler handler, TRunner runner, RunnerBarrier? barrier) where TRunner : IRunner => query.Handle((filter, handler), static (IEntityHost host, in (ComponentFilter, EntityHandler) fs, int from, int to) => { @@ -540,11 +604,11 @@ public unsafe static void Filter( handler(new(slot, host)); } } - }, runner); + }, runner, barrier); [MethodImpl(MethodImplOptions.AggressiveInlining)] public unsafe static void Filter( - this IEntityQuery query, ComponentFilter filter, EntityHandler handler, TRunner runner) + this IEntityQuery query, ComponentFilter filter, EntityHandler handler, TRunner runner, RunnerBarrier? barrier) where TRunner : IRunner => query.Handle((filter, handler), static (IEntityHost host, in (ComponentFilter, EntityHandler) fs, int from, int to) => { @@ -565,11 +629,11 @@ ref c2Offset.Get(ref byteRef))) { handler(new(slot, host)); } } - }, runner); + }, runner, barrier); [MethodImpl(MethodImplOptions.AggressiveInlining)] public unsafe static void Filter( - this IEntityQuery query, ComponentFilter filter, EntityHandler handler, TRunner runner) + this IEntityQuery query, ComponentFilter filter, EntityHandler handler, TRunner runner, RunnerBarrier? barrier) where TRunner : IRunner => query.Handle((filter, handler), static (IEntityHost host, in (ComponentFilter, EntityHandler) fs, int from, int to) => { @@ -592,11 +656,11 @@ ref c3Offset.Get(ref byteRef))) { handler(new(slot, host)); } } - }, runner); + }, runner, barrier); [MethodImpl(MethodImplOptions.AggressiveInlining)] public unsafe static void Filter( - this IEntityQuery query, ComponentFilter filter, EntityHandler handler, TRunner runner) + this IEntityQuery query, ComponentFilter filter, EntityHandler handler, TRunner runner, RunnerBarrier? barrier) where TRunner : IRunner => query.Handle((filter, handler), static (IEntityHost host, in (ComponentFilter, EntityHandler) fs, int from, int to) => { @@ -621,11 +685,11 @@ ref c4Offset.Get(ref byteRef))) { handler(new(slot, host)); } } - }, runner); + }, runner, barrier); [MethodImpl(MethodImplOptions.AggressiveInlining)] public unsafe static void Filter( - this IEntityQuery query, ComponentFilter filter, EntityHandler handler, TRunner runner) + this IEntityQuery query, ComponentFilter filter, EntityHandler handler, TRunner runner, RunnerBarrier? barrier) where TRunner : IRunner => query.Handle((filter, handler), static (IEntityHost host, in (ComponentFilter, EntityHandler) fs, int from, int to) => { @@ -652,11 +716,11 @@ ref c5Offset.Get(ref byteRef))) { handler(new(slot, host)); } } - }, runner); + }, runner, barrier); [MethodImpl(MethodImplOptions.AggressiveInlining)] public unsafe static void Filter( - this IEntityQuery query, ComponentFilter filter, EntityHandler handler, TRunner runner) + this IEntityQuery query, ComponentFilter filter, EntityHandler handler, TRunner runner, RunnerBarrier? barrier) where TRunner : IRunner => query.Handle((filter, handler), static (IEntityHost host, in (ComponentFilter, EntityHandler) fs, int from, int to) => { @@ -685,11 +749,11 @@ ref c6Offset.Get(ref byteRef))) { handler(new(slot, host)); } } - }, runner); + }, runner, barrier); [MethodImpl(MethodImplOptions.AggressiveInlining)] public unsafe static void Filter( - this IEntityQuery query, in TData userData, DataComponentFilter filter, EntityHandler handler, TRunner runner) + this IEntityQuery query, in TData userData, DataComponentFilter filter, EntityHandler handler, TRunner runner, RunnerBarrier? barrier) where TRunner : IRunner => query.Handle((filter, handler, userData), static (IEntityHost host, in (DataComponentFilter, EntityHandler, TData) data, int from, int to) => { @@ -710,11 +774,11 @@ public unsafe static void Filter( handler(userData, new(slot, host)); } } - }, runner); + }, runner, barrier); [MethodImpl(MethodImplOptions.AggressiveInlining)] public unsafe static void Filter( - this IEntityQuery query, in TData userData, DataComponentFilter filter, EntityHandler handler, TRunner runner) + this IEntityQuery query, in TData userData, DataComponentFilter filter, EntityHandler handler, TRunner runner, RunnerBarrier? barrier) where TRunner : IRunner => query.Handle((filter, handler, userData), static (IEntityHost host, in (DataComponentFilter, EntityHandler, TData) data, int from, int to) => { @@ -738,11 +802,11 @@ ref c2Offset.Get(ref byteRef))) { handler(userData, new(slot, host)); } } - }, runner); + }, runner, barrier); [MethodImpl(MethodImplOptions.AggressiveInlining)] public unsafe static void Filter( - this IEntityQuery query, in TData userData, DataComponentFilter filter, EntityHandler handler, TRunner runner) + this IEntityQuery query, in TData userData, DataComponentFilter filter, EntityHandler handler, TRunner runner, RunnerBarrier? barrier) where TRunner : IRunner => query.Handle((filter, handler, userData), static (IEntityHost host, in (DataComponentFilter, EntityHandler, TData) data, int from, int to) => { @@ -768,11 +832,11 @@ ref c3Offset.Get(ref byteRef))) { handler(userData, new(slot, host)); } } - }, runner); + }, runner, barrier); [MethodImpl(MethodImplOptions.AggressiveInlining)] public unsafe static void Filter( - this IEntityQuery query, in TData userData, DataComponentFilter filter, EntityHandler handler, TRunner runner) + this IEntityQuery query, in TData userData, DataComponentFilter filter, EntityHandler handler, TRunner runner, RunnerBarrier? barrier) where TRunner : IRunner => query.Handle((filter, handler, userData), static (IEntityHost host, in (DataComponentFilter, EntityHandler, TData) data, int from, int to) => { @@ -800,11 +864,11 @@ ref c4Offset.Get(ref byteRef))) { handler(userData, new(slot, host)); } } - }, runner); + }, runner, barrier); [MethodImpl(MethodImplOptions.AggressiveInlining)] public unsafe static void Filter( - this IEntityQuery query, in TData userData, DataComponentFilter filter, EntityHandler handler, TRunner runner) + this IEntityQuery query, in TData userData, DataComponentFilter filter, EntityHandler handler, TRunner runner, RunnerBarrier? barrier) where TRunner : IRunner => query.Handle((filter, handler, userData), static (IEntityHost host, in (DataComponentFilter, EntityHandler, TData) data, int from, int to) => { @@ -834,11 +898,11 @@ ref c5Offset.Get(ref byteRef))) { handler(userData, new(slot, host)); } } - }, runner); + }, runner, barrier); [MethodImpl(MethodImplOptions.AggressiveInlining)] public unsafe static void Filter( - this IEntityQuery query, in TData userData, DataComponentFilter filter, EntityHandler handler, TRunner runner) + this IEntityQuery query, in TData userData, DataComponentFilter filter, EntityHandler handler, TRunner runner, RunnerBarrier? barrier) where TRunner : IRunner => query.Handle((filter, handler, userData), static (IEntityHost host, in (DataComponentFilter, EntityHandler, TData) data, int from, int to) => { @@ -870,133 +934,181 @@ ref c6Offset.Get(ref byteRef))) { handler(userData, new(slot, host)); } } - }, runner); + }, runner, barrier); #region CurrentThreadRunner [MethodImpl(MethodImplOptions.AggressiveInlining)] public unsafe static void Filter( this IEntityQuery query, ComponentFilter filter, EntityHandler handler) - => query.Filter(filter, handler, CurrentThreadRunner.Instance); + => query.Filter(filter, handler, CurrentThreadRunner.Instance, barrier: null); [MethodImpl(MethodImplOptions.AggressiveInlining)] public unsafe static void Filter( this IEntityQuery query, ComponentFilter filter, EntityHandler handler) - => query.Filter(filter, handler, CurrentThreadRunner.Instance); + => query.Filter(filter, handler, CurrentThreadRunner.Instance, barrier: null); [MethodImpl(MethodImplOptions.AggressiveInlining)] public unsafe static void Filter( this IEntityQuery query, ComponentFilter filter, EntityHandler handler) - => query.Filter(filter, handler, CurrentThreadRunner.Instance); + => query.Filter(filter, handler, CurrentThreadRunner.Instance, barrier: null); [MethodImpl(MethodImplOptions.AggressiveInlining)] public unsafe static void Filter( this IEntityQuery query, ComponentFilter filter, EntityHandler handler) - => query.Filter(filter, handler, CurrentThreadRunner.Instance); + => query.Filter(filter, handler, CurrentThreadRunner.Instance, barrier: null); [MethodImpl(MethodImplOptions.AggressiveInlining)] public unsafe static void Filter( this IEntityQuery query, ComponentFilter filter, EntityHandler handler) - => query.Filter(filter, handler, CurrentThreadRunner.Instance); + => query.Filter(filter, handler, CurrentThreadRunner.Instance, barrier: null); [MethodImpl(MethodImplOptions.AggressiveInlining)] public unsafe static void Filter( this IEntityQuery query, ComponentFilter filter, EntityHandler handler) - => query.Filter(filter, handler, CurrentThreadRunner.Instance); + => query.Filter(filter, handler, CurrentThreadRunner.Instance, barrier: null); [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); + => query.Filter(userData, filter, handler, CurrentThreadRunner.Instance, barrier: null); [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); + => query.Filter(userData, filter, handler, CurrentThreadRunner.Instance, barrier: null); [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); + => query.Filter(userData, filter, handler, CurrentThreadRunner.Instance, barrier: null); [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); + => query.Filter(userData, filter, handler, CurrentThreadRunner.Instance, barrier: null); [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); + => query.Filter(userData, filter, handler, CurrentThreadRunner.Instance, barrier: null); [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); + => query.Filter(userData, filter, handler, CurrentThreadRunner.Instance, barrier: null); - #endregion // ParallelRunner + #endregion // CurrentThreadRunner #region ParallelRunner [MethodImpl(MethodImplOptions.AggressiveInlining)] public unsafe static void FilterOnParallel( this IEntityQuery query, ComponentFilter filter, EntityHandler handler) - => query.Filter(filter, handler, ParallelRunner.Default); + { + var barrier = RunnerBarrier.Get(); + query.Filter(filter, handler, ParallelRunner.Default, barrier); + barrier.WaitAndReturn(); + } [MethodImpl(MethodImplOptions.AggressiveInlining)] public unsafe static void FilterOnParallel( this IEntityQuery query, ComponentFilter filter, EntityHandler handler) - => query.Filter(filter, handler, ParallelRunner.Default); + { + var barrier = RunnerBarrier.Get(); + query.Filter(filter, handler, ParallelRunner.Default, barrier); + barrier.WaitAndReturn(); + } [MethodImpl(MethodImplOptions.AggressiveInlining)] public unsafe static void FilterOnParallel( this IEntityQuery query, ComponentFilter filter, EntityHandler handler) - => query.Filter(filter, handler, ParallelRunner.Default); + { + var barrier = RunnerBarrier.Get(); + query.Filter(filter, handler, ParallelRunner.Default, barrier); + barrier.WaitAndReturn(); + } [MethodImpl(MethodImplOptions.AggressiveInlining)] public unsafe static void FilterOnParallel( this IEntityQuery query, ComponentFilter filter, EntityHandler handler) - => query.Filter(filter, handler, ParallelRunner.Default); + { + var barrier = RunnerBarrier.Get(); + query.Filter(filter, handler, ParallelRunner.Default, barrier); + barrier.WaitAndReturn(); + } [MethodImpl(MethodImplOptions.AggressiveInlining)] public unsafe static void FilterOnParallel( this IEntityQuery query, ComponentFilter filter, EntityHandler handler) - => query.Filter(filter, handler, ParallelRunner.Default); + { + var barrier = RunnerBarrier.Get(); + query.Filter(filter, handler, ParallelRunner.Default, barrier); + barrier.WaitAndReturn(); + } [MethodImpl(MethodImplOptions.AggressiveInlining)] public unsafe static void FilterOnParallel( this IEntityQuery query, ComponentFilter filter, EntityHandler handler) - => query.Filter(filter, handler, ParallelRunner.Default); + { + var barrier = RunnerBarrier.Get(); + query.Filter(filter, handler, ParallelRunner.Default, barrier); + barrier.WaitAndReturn(); + } [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); + { + var barrier = RunnerBarrier.Get(); + query.Filter(userData, filter, handler, ParallelRunner.Default, barrier); + barrier.WaitAndReturn(); + } [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); + { + var barrier = RunnerBarrier.Get(); + query.Filter(userData, filter, handler, ParallelRunner.Default, barrier); + barrier.WaitAndReturn(); + } [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); + { + var barrier = RunnerBarrier.Get(); + query.Filter(userData, filter, handler, ParallelRunner.Default, barrier); + barrier.WaitAndReturn(); + } [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); + { + var barrier = RunnerBarrier.Get(); + query.Filter(userData, filter, handler, ParallelRunner.Default, barrier); + barrier.WaitAndReturn(); + } [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); + { + var barrier = RunnerBarrier.Get(); + query.Filter(userData, filter, handler, ParallelRunner.Default, barrier); + barrier.WaitAndReturn(); + } [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); + { + var barrier = RunnerBarrier.Get(); + query.Filter(userData, filter, handler, ParallelRunner.Default, barrier); + barrier.WaitAndReturn(); + } #endregion // ParallelRunner diff --git a/Sia/Entities/Extensions/EntityQueryExtensions.Handle.cs b/Sia/Entities/Extensions/EntityQueryExtensions.Handle.cs index 6ef3c4b..63a164e 100644 --- a/Sia/Entities/Extensions/EntityQueryExtensions.Handle.cs +++ b/Sia/Entities/Extensions/EntityQueryExtensions.Handle.cs @@ -30,7 +30,7 @@ private static (IEntityHost Host, int HostIndex, int SlotIndex) FindHost( [MethodImpl(MethodImplOptions.AggressiveInlining)] public static unsafe void Handle( - this IEntityQuery query, EntityHostRangeHandler handler, TRunner runner, RunnerBarrier barrier) + this IEntityQuery query, EntityHostRangeHandler handler, TRunner runner, RunnerBarrier? barrier) where TRunner : IRunner { var count = query.Count; @@ -66,20 +66,10 @@ static void Action(in HandleData data, (int, int) range) runner.Run(count, new HandleData(query, handler), Action, barrier); } - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static unsafe void Handle( - this IEntityQuery query, EntityHostRangeHandler handler, TRunner runner) - where TRunner : IRunner - { - var barrier = RunnerBarrier.Get(); - query.Handle(handler, runner, barrier); - barrier.WaitAndReturn(); - } - [MethodImpl(MethodImplOptions.AggressiveInlining)] public static unsafe void Handle( this IEntityQuery query, in TData userData, EntityHostRangeHandler handler, - TRunner runner, RunnerBarrier barrier) + TRunner runner, RunnerBarrier? barrier) where TRunner : IRunner { var count = query.Count; @@ -125,27 +115,17 @@ static void Action(in HandleData data, (int, int) range) runner.Run(count, data, Action, barrier); } - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static unsafe void Handle( - this IEntityQuery query, in TData userData, EntityHostRangeHandler handler, TRunner runner) - where TRunner : IRunner - { - var barrier = RunnerBarrier.Get(); - query.Handle(userData, handler, runner, barrier); - barrier.WaitAndReturn(); - } - #region CurrentThreadRunner [MethodImpl(MethodImplOptions.AggressiveInlining)] public static unsafe void Handle( this IEntityQuery query, EntityHostRangeHandler handler) - => query.Handle(handler, CurrentThreadRunner.Instance); + => query.Handle(handler, CurrentThreadRunner.Instance, barrier: null); [MethodImpl(MethodImplOptions.AggressiveInlining)] public static unsafe void Handle( this IEntityQuery query, in TData data, EntityHostRangeHandler handler) - => query.Handle(data, handler, CurrentThreadRunner.Instance); + => query.Handle(data, handler, CurrentThreadRunner.Instance, barrier: null); #endregion // CurrentThreadRunner @@ -154,12 +134,20 @@ public static unsafe void Handle( [MethodImpl(MethodImplOptions.AggressiveInlining)] public static unsafe void HandleOnParallel( this IEntityQuery query, EntityHostRangeHandler handler) - => query.Handle(handler, ParallelRunner.Default); + { + var barrier = RunnerBarrier.Get(); + query.Handle(handler, ParallelRunner.Default, barrier); + barrier.WaitAndReturn(); + } [MethodImpl(MethodImplOptions.AggressiveInlining)] public static unsafe void HandleOnParallel( this IEntityQuery query, in TData data, EntityHostRangeHandler handler) - => query.Handle(data, handler, ParallelRunner.Default); + { + var barrier = RunnerBarrier.Get(); + query.Handle(data, handler, ParallelRunner.Default, barrier); + barrier.WaitAndReturn(); + } #endregion // ParallelRunner } \ No newline at end of file diff --git a/Sia/Entities/Extensions/EntityQueryExtensions.Record.cs b/Sia/Entities/Extensions/EntityQueryExtensions.Record.cs index 8480f77..74b6dc5 100644 --- a/Sia/Entities/Extensions/EntityQueryExtensions.Record.cs +++ b/Sia/Entities/Extensions/EntityQueryExtensions.Record.cs @@ -9,9 +9,10 @@ public static partial class EntityQueryExtensions #region EntityRecorder public unsafe static void Record( - this IEntityQuery query, Span span, EntityRecorder recorder, TRunner runner) + this IEntityQuery query, Span span, EntityRecorder recorder, TRunner runner, RunnerBarrier? barrier) where TRunner : IRunner { + GuardSpanLength(span, query.Count); int index = -1; fixed (TResult* pointer = span) { @@ -32,14 +33,15 @@ public unsafe static void Record( recorder(new(slots[i], host), out *(pointer + Interlocked.Increment(ref index))); } - }, runner); + }, runner, barrier); } } public unsafe static void Record( - this IEntityQuery query, Span span, in TData userData, EntityRecorder recorder, TRunner runner) + this IEntityQuery query, Span span, in TData userData, EntityRecorder recorder, TRunner runner, RunnerBarrier? barrier) where TRunner : IRunner { + GuardSpanLength(span, query.Count); int index = -1; fixed (TResult* pointer = span) { @@ -61,7 +63,7 @@ public unsafe static void Record( recorder(userData, new(slots[i], host), out *(pointer + Interlocked.Increment(ref index))); } - }, runner); + }, runner, barrier); } } @@ -69,23 +71,23 @@ private static void IdEntityRecorder(in EntityRef entity, out EntityRef result) => result = entity; public unsafe static void Record( - this IEntityQuery query, Span span, TRunner runner) + this IEntityQuery query, Span span, TRunner runner, RunnerBarrier? barrier) where TRunner : IRunner - => query.Record(span, IdEntityRecorder, runner); + => query.Record(span, IdEntityRecorder, runner, barrier); #region CurrentThreadRunner public unsafe static void Record( this IEntityQuery query, Span span, EntityRecorder recorder) - => query.Record(span, recorder, CurrentThreadRunner.Instance); + => query.Record(span, recorder, CurrentThreadRunner.Instance, barrier: null); public unsafe static void Record( this IEntityQuery query, Span span, in TData userData, EntityRecorder recorder) - => query.Record(span, userData, recorder, CurrentThreadRunner.Instance); + => query.Record(span, userData, recorder, CurrentThreadRunner.Instance, barrier: null); public unsafe static void Record( this IEntityQuery query, Span span) - => query.Record(span, IdEntityRecorder, CurrentThreadRunner.Instance); + => query.Record(span, IdEntityRecorder, CurrentThreadRunner.Instance, barrier: null); #endregion // CurrentThreadRunner @@ -93,15 +95,27 @@ public unsafe static void Record( public unsafe static void RecordOnParallel( this IEntityQuery query, Span span, EntityRecorder recorder) - => query.Record(span, recorder, ParallelRunner.Default); + { + var barrier = RunnerBarrier.Get(); + query.Record(span, recorder, ParallelRunner.Default, barrier); + barrier.WaitAndReturn(); + } public unsafe static void RecordOnParallel( this IEntityQuery query, Span span, in TData userData, EntityRecorder recorder) - => query.Record(span, userData, recorder, ParallelRunner.Default); + { + var barrier = RunnerBarrier.Get(); + query.Record(span, userData, recorder, ParallelRunner.Default, barrier); + barrier.WaitAndReturn(); + } public unsafe static void RecordOnParallel( this IEntityQuery query, Span span) - => query.Record(span, IdEntityRecorder, ParallelRunner.Default); + { + var barrier = RunnerBarrier.Get(); + query.Record(span, IdEntityRecorder, ParallelRunner.Default, barrier); + barrier.WaitAndReturn(); + } #endregion // ParallelRunner @@ -110,9 +124,10 @@ public unsafe static void RecordOnParallel( #region ComponentRecorder public unsafe static void RecordSlices( - this IEntityQuery query, Span span, ComponentRecorder recorder, TRunner runner) + this IEntityQuery query, Span span, ComponentRecorder recorder, TRunner runner, RunnerBarrier? barrier) where TRunner : IRunner { + GuardSpanLength(span, query.Count); int index = -1; fixed (TResult* pointer = span) { @@ -126,14 +141,15 @@ public unsafe static void RecordSlices( static (in CompRecordData data, ref C1 c1) => { data.Recorder(ref c1, out *(data.Pointer + Interlocked.Increment(ref *data.Index))); - }, runner); + }, runner, barrier); } } public unsafe static void RecordSlices( - this IEntityQuery query, Span span, ComponentRecorder recorder, TRunner runner) + this IEntityQuery query, Span span, ComponentRecorder recorder, TRunner runner, RunnerBarrier? barrier) where TRunner : IRunner { + GuardSpanLength(span, query.Count); int index = -1; fixed (TResult* pointer = span) { @@ -147,14 +163,15 @@ public unsafe static void RecordSlices( static (in CompRecordData data, ref C1 c1, ref C2 c2) => { data.Recorder(ref c1, ref c2, out *(data.Pointer + Interlocked.Increment(ref *data.Index))); - }, runner); + }, runner, barrier); } } public unsafe static void RecordSlices( - this IEntityQuery query, Span span, ComponentRecorder recorder, TRunner runner) + this IEntityQuery query, Span span, ComponentRecorder recorder, TRunner runner, RunnerBarrier? barrier) where TRunner : IRunner { + GuardSpanLength(span, query.Count); int index = -1; fixed (TResult* pointer = span) { @@ -168,14 +185,15 @@ public unsafe static void RecordSlices( static (in CompRecordData data, ref C1 c1, ref C2 c2, ref C3 c3) => { data.Recorder(ref c1, ref c2, ref c3, out *(data.Pointer + Interlocked.Increment(ref *data.Index))); - }, runner); + }, runner, barrier); } } public unsafe static void RecordSlices( - this IEntityQuery query, Span span, ComponentRecorder recorder, TRunner runner) + this IEntityQuery query, Span span, ComponentRecorder recorder, TRunner runner, RunnerBarrier? barrier) where TRunner : IRunner { + GuardSpanLength(span, query.Count); int index = -1; fixed (TResult* pointer = span) { @@ -189,14 +207,15 @@ public unsafe static void RecordSlices( static (in CompRecordData data, ref C1 c1, ref C2 c2, ref C3 c3, ref C4 c4) => { data.Recorder(ref c1, ref c2, ref c3, ref c4, out *(data.Pointer + Interlocked.Increment(ref *data.Index))); - }, runner); + }, runner, barrier); } } public unsafe static void RecordSlices( - this IEntityQuery query, Span span, ComponentRecorder recorder, TRunner runner) + this IEntityQuery query, Span span, ComponentRecorder recorder, TRunner runner, RunnerBarrier? barrier) where TRunner : IRunner { + GuardSpanLength(span, query.Count); int index = -1; fixed (TResult* pointer = span) { @@ -210,14 +229,15 @@ public unsafe static void RecordSlices( static (in CompRecordData data, ref C1 c1, ref C2 c2, ref C3 c3, ref C4 c4, ref C5 c5) => { data.Recorder(ref c1, ref c2, ref c3, ref c4, ref c5, out *(data.Pointer + Interlocked.Increment(ref *data.Index))); - }, runner); + }, runner, barrier); } } public unsafe static void RecordSlices( - this IEntityQuery query, Span span, ComponentRecorder recorder, TRunner runner) + this IEntityQuery query, Span span, ComponentRecorder recorder, TRunner runner, RunnerBarrier? barrier) where TRunner : IRunner { + GuardSpanLength(span, query.Count); int index = -1; fixed (TResult* pointer = span) { @@ -231,14 +251,15 @@ public unsafe static void RecordSlices static (in CompRecordData data, ref C1 c1, ref C2 c2, ref C3 c3, ref C4 c4, ref C5 c5, ref C6 c6) => { data.Recorder(ref c1, ref c2, ref c3, ref c4, ref c5, ref c6, out *(data.Pointer + Interlocked.Increment(ref *data.Index))); - }, runner); + }, runner, barrier); } } public unsafe static void RecordSlices( - this IEntityQuery query, Span span, in TData userData, DataComponentRecorder recorder, TRunner runner) + this IEntityQuery query, Span span, in TData userData, DataComponentRecorder recorder, TRunner runner, RunnerBarrier? barrier) where TRunner : IRunner { + GuardSpanLength(span, query.Count); int index = -1; fixed (TResult* pointer = span) { @@ -254,14 +275,15 @@ public unsafe static void RecordSlices( data.Recorder(data.UserData, ref c1, out *(data.Pointer + Interlocked.Increment(ref *data.Index))); - }, runner); + }, runner, barrier); } } public unsafe static void RecordSlices( - this IEntityQuery query, Span span, in TData userData, DataComponentRecorder recorder, TRunner runner) + this IEntityQuery query, Span span, in TData userData, DataComponentRecorder recorder, TRunner runner, RunnerBarrier? barrier) where TRunner : IRunner { + GuardSpanLength(span, query.Count); int index = -1; fixed (TResult* pointer = span) { @@ -277,14 +299,15 @@ public unsafe static void RecordSlices( data.Recorder(data.UserData, ref c1, ref c2, out *(data.Pointer + Interlocked.Increment(ref *data.Index))); - }, runner); + }, runner, barrier); } } public unsafe static void RecordSlices( - this IEntityQuery query, Span span, in TData userData, DataComponentRecorder recorder, TRunner runner) + this IEntityQuery query, Span span, in TData userData, DataComponentRecorder recorder, TRunner runner, RunnerBarrier? barrier) where TRunner : IRunner { + GuardSpanLength(span, query.Count); int index = -1; fixed (TResult* pointer = span) { @@ -300,14 +323,15 @@ public unsafe static void RecordSlices( data.Recorder(data.UserData, ref c1, ref c2, ref c3, out *(data.Pointer + Interlocked.Increment(ref *data.Index))); - }, runner); + }, runner, barrier); } } public unsafe static void RecordSlices( - this IEntityQuery query, Span span, in TData userData, DataComponentRecorder recorder, TRunner runner) + this IEntityQuery query, Span span, in TData userData, DataComponentRecorder recorder, TRunner runner, RunnerBarrier? barrier) where TRunner : IRunner { + GuardSpanLength(span, query.Count); int index = -1; fixed (TResult* pointer = span) { @@ -323,14 +347,15 @@ public unsafe static void RecordSlices( data.Recorder(data.UserData, ref c1, ref c2, ref c3, ref c4, out *(data.Pointer + Interlocked.Increment(ref *data.Index))); - }, runner); + }, runner, barrier); } } public unsafe static void RecordSlices( - this IEntityQuery query, Span span, in TData userData, DataComponentRecorder recorder, TRunner runner) + this IEntityQuery query, Span span, in TData userData, DataComponentRecorder recorder, TRunner runner, RunnerBarrier? barrier) where TRunner : IRunner { + GuardSpanLength(span, query.Count); int index = -1; fixed (TResult* pointer = span) { @@ -346,14 +371,15 @@ public unsafe static void RecordSlices( - this IEntityQuery query, Span span, in TData userData, DataComponentRecorder recorder, TRunner runner) + this IEntityQuery query, Span span, in TData userData, DataComponentRecorder recorder, TRunner runner, RunnerBarrier? barrier) where TRunner : IRunner { + GuardSpanLength(span, query.Count); int index = -1; fixed (TResult* pointer = span) { @@ -369,7 +395,7 @@ public unsafe static void RecordSlices( this IEntityQuery query, Span span, ComponentRecorder recorder) - => query.RecordSlices(span, recorder, CurrentThreadRunner.Instance); + => query.RecordSlices(span, recorder, CurrentThreadRunner.Instance, barrier: null); public unsafe static void RecordSlices( this IEntityQuery query, Span span, ComponentRecorder recorder) - => query.RecordSlices(span, recorder, CurrentThreadRunner.Instance); + => query.RecordSlices(span, recorder, CurrentThreadRunner.Instance, barrier: null); public unsafe static void RecordSlices( this IEntityQuery query, Span span, ComponentRecorder recorder) - => query.RecordSlices(span, recorder, CurrentThreadRunner.Instance); + => query.RecordSlices(span, recorder, CurrentThreadRunner.Instance, barrier: null); public unsafe static void RecordSlices( this IEntityQuery query, Span span, ComponentRecorder recorder) - => query.RecordSlices(span, recorder, CurrentThreadRunner.Instance); + => query.RecordSlices(span, recorder, CurrentThreadRunner.Instance, barrier: null); public unsafe static void RecordSlices( this IEntityQuery query, Span span, ComponentRecorder recorder) - => query.RecordSlices(span, recorder, CurrentThreadRunner.Instance); + => query.RecordSlices(span, recorder, CurrentThreadRunner.Instance, barrier: null); public unsafe static void RecordSlices( this IEntityQuery query, Span span, ComponentRecorder recorder) - => query.RecordSlices(span, recorder, CurrentThreadRunner.Instance); + => query.RecordSlices(span, recorder, CurrentThreadRunner.Instance, barrier: null); public unsafe static void RecordSlices( this IEntityQuery query, Span span, in TData userData, DataComponentRecorder recorder) - => query.RecordSlices(span, userData, recorder, CurrentThreadRunner.Instance); + => query.RecordSlices(span, userData, recorder, CurrentThreadRunner.Instance, barrier: null); public unsafe static void RecordSlices( this IEntityQuery query, Span span, in TData userData, DataComponentRecorder recorder) - => query.RecordSlices(span, userData, recorder, CurrentThreadRunner.Instance); + => query.RecordSlices(span, userData, recorder, CurrentThreadRunner.Instance, barrier: null); public unsafe static void RecordSlices( this IEntityQuery query, Span span, in TData userData, DataComponentRecorder recorder) - => query.RecordSlices(span, userData, recorder, CurrentThreadRunner.Instance); + => query.RecordSlices(span, userData, recorder, CurrentThreadRunner.Instance, barrier: null); public unsafe static void RecordSlices( this IEntityQuery query, Span span, in TData userData, DataComponentRecorder recorder) - => query.RecordSlices(span, userData, recorder, CurrentThreadRunner.Instance); + => query.RecordSlices(span, userData, recorder, CurrentThreadRunner.Instance, barrier: null); public unsafe static void RecordSlices( this IEntityQuery query, Span span, in TData userData, DataComponentRecorder recorder) - => query.RecordSlices(span, userData, recorder, CurrentThreadRunner.Instance); + => query.RecordSlices(span, userData, recorder, CurrentThreadRunner.Instance, barrier: null); public unsafe static void RecordSlices( this IEntityQuery query, Span span, in TData userData, DataComponentRecorder recorder) - => query.RecordSlices(span, userData, recorder, CurrentThreadRunner.Instance); + => query.RecordSlices(span, userData, recorder, CurrentThreadRunner.Instance, barrier: null); #endregion // CurrentThreadRunner @@ -429,51 +455,99 @@ public unsafe static void RecordSlices( public unsafe static void RecordSlicesOnParallel( this IEntityQuery query, Span span, ComponentRecorder recorder) - => query.RecordSlices(span, recorder, ParallelRunner.Default); + { + var barrier = RunnerBarrier.Get(); + query.RecordSlices(span, recorder, ParallelRunner.Default, barrier); + barrier.WaitAndReturn(); + } public unsafe static void RecordSlicesOnParallel( this IEntityQuery query, Span span, ComponentRecorder recorder) - => query.RecordSlices(span, recorder, ParallelRunner.Default); + { + var barrier = RunnerBarrier.Get(); + query.RecordSlices(span, recorder, ParallelRunner.Default, barrier); + barrier.WaitAndReturn(); + } public unsafe static void RecordSlicesOnParallel( this IEntityQuery query, Span span, ComponentRecorder recorder) - => query.RecordSlices(span, recorder, ParallelRunner.Default); + { + var barrier = RunnerBarrier.Get(); + query.RecordSlices(span, recorder, ParallelRunner.Default, barrier); + barrier.WaitAndReturn(); + } public unsafe static void RecordSlicesOnParallel( this IEntityQuery query, Span span, ComponentRecorder recorder) - => query.RecordSlices(span, recorder, ParallelRunner.Default); + { + var barrier = RunnerBarrier.Get(); + query.RecordSlices(span, recorder, ParallelRunner.Default, barrier); + barrier.WaitAndReturn(); + } public unsafe static void RecordSlicesOnParallel( this IEntityQuery query, Span span, ComponentRecorder recorder) - => query.RecordSlices(span, recorder, ParallelRunner.Default); + { + var barrier = RunnerBarrier.Get(); + query.RecordSlices(span, recorder, ParallelRunner.Default, barrier); + barrier.WaitAndReturn(); + } public unsafe static void RecordSlicesOnParallel( this IEntityQuery query, Span span, ComponentRecorder recorder) - => query.RecordSlices(span, recorder, ParallelRunner.Default); + { + var barrier = RunnerBarrier.Get(); + query.RecordSlices(span, recorder, ParallelRunner.Default, barrier); + barrier.WaitAndReturn(); + } public unsafe static void RecordSlicesOnParallel( this IEntityQuery query, Span span, in TData userData, DataComponentRecorder recorder) - => query.RecordSlices(span, userData, recorder, ParallelRunner.Default); + { + var barrier = RunnerBarrier.Get(); + query.RecordSlices(span, userData, recorder, ParallelRunner.Default, barrier); + barrier.WaitAndReturn(); + } public unsafe static void RecordSlicesOnParallel( this IEntityQuery query, Span span, in TData userData, DataComponentRecorder recorder) - => query.RecordSlices(span, userData, recorder, ParallelRunner.Default); + { + var barrier = RunnerBarrier.Get(); + query.RecordSlices(span, userData, recorder, ParallelRunner.Default, barrier); + barrier.WaitAndReturn(); + } public unsafe static void RecordSlicesOnParallel( this IEntityQuery query, Span span, in TData userData, DataComponentRecorder recorder) - => query.RecordSlices(span, userData, recorder, ParallelRunner.Default); + { + var barrier = RunnerBarrier.Get(); + query.RecordSlices(span, userData, recorder, ParallelRunner.Default, barrier); + barrier.WaitAndReturn(); + } public unsafe static void RecordSlicesOnParallel( this IEntityQuery query, Span span, in TData userData, DataComponentRecorder recorder) - => query.RecordSlices(span, userData, recorder, ParallelRunner.Default); + { + var barrier = RunnerBarrier.Get(); + query.RecordSlices(span, userData, recorder, ParallelRunner.Default, barrier); + barrier.WaitAndReturn(); + } public unsafe static void RecordSlicesOnParallel( this IEntityQuery query, Span span, in TData userData, DataComponentRecorder recorder) - => query.RecordSlices(span, userData, recorder, ParallelRunner.Default); + { + var barrier = RunnerBarrier.Get(); + query.RecordSlices(span, userData, recorder, ParallelRunner.Default, barrier); + barrier.WaitAndReturn(); + } public unsafe static void RecordSlicesOnParallel( this IEntityQuery query, Span span, in TData userData, DataComponentRecorder recorder) - => query.RecordSlices(span, userData, recorder, ParallelRunner.Default); + { + var barrier = RunnerBarrier.Get(); + query.RecordSlices(span, userData, recorder, ParallelRunner.Default, barrier); + barrier.WaitAndReturn(); + } #endregion // ParallelRunner #endregion // ComponentRecorder diff --git a/Sia/Systems/ParallelSystemBase.cs b/Sia/Systems/ParallelSystemBase.cs index eb54917..f3de54b 100644 --- a/Sia/Systems/ParallelSystemBase.cs +++ b/Sia/Systems/ParallelSystemBase.cs @@ -9,7 +9,11 @@ public abstract class ParallelSystemBase( public IRunner Runner { get; } = runner ?? ParallelRunner.Default; public override void Execute(World world, Scheduler scheduler, IEntityQuery query) - => query.ForSlice(HandleSlice, Runner); + { + var barrier = RunnerBarrier.Get(); + query.ForSlice(HandleSlice, Runner, barrier); + barrier.WaitAndReturn(); + } protected abstract void HandleSlice(ref C1 c1); } @@ -23,7 +27,11 @@ public abstract class ParallelSystemBase( public IRunner Runner { get; } = runner ?? ParallelRunner.Default; public override void Execute(World world, Scheduler scheduler, IEntityQuery query) - => query.ForSlice(OnExecute, Runner); + { + var barrier = RunnerBarrier.Get(); + query.ForSlice(OnExecute, Runner, barrier); + barrier.WaitAndReturn(); + } protected abstract void OnExecute(ref C1 c1, ref C2 c2); } @@ -37,7 +45,11 @@ public abstract class ParallelSystemBase( public IRunner Runner { get; } = runner ?? ParallelRunner.Default; public override void Execute(World world, Scheduler scheduler, IEntityQuery query) - => query.ForSlice(OnExecute, Runner); + { + var barrier = RunnerBarrier.Get(); + query.ForSlice(OnExecute, Runner, barrier); + barrier.WaitAndReturn(); + } protected abstract void OnExecute(ref C1 c1, ref C2 c2, ref C3 c3); } @@ -51,7 +63,11 @@ public abstract class ParallelSystemBase( public IRunner Runner { get; } = runner ?? ParallelRunner.Default; public override void Execute(World world, Scheduler scheduler, IEntityQuery query) - => query.ForSlice(OnExecute, Runner); + { + var barrier = RunnerBarrier.Get(); + query.ForSlice(OnExecute, Runner, barrier); + barrier.WaitAndReturn(); + } protected abstract void OnExecute(ref C1 c1, ref C2 c2, ref C3 c3, ref C4 c4); } @@ -65,7 +81,11 @@ public abstract class ParallelSystemBase( public IRunner Runner { get; } = runner ?? ParallelRunner.Default; public override void Execute(World world, Scheduler scheduler, IEntityQuery query) - => query.ForSlice(OnExecute, Runner); + { + var barrier = RunnerBarrier.Get(); + query.ForSlice(OnExecute, Runner, barrier); + barrier.WaitAndReturn(); + } protected abstract void OnExecute(ref C1 c1, ref C2 c2, ref C3 c3, ref C4 c4, ref C5 c5); } @@ -79,7 +99,11 @@ public abstract class ParallelSystemBase( public IRunner Runner { get; } = runner ?? ParallelRunner.Default; public override void Execute(World world, Scheduler scheduler, IEntityQuery query) - => query.ForSlice(OnExecute, Runner); + { + var barrier = RunnerBarrier.Get(); + query.ForSlice(OnExecute, Runner, barrier); + barrier.WaitAndReturn(); + } protected abstract void OnExecute(ref C1 c1, ref C2 c2, ref C3 c3, ref C4 c4, ref C5 c5, ref C6 c6); } \ No newline at end of file