diff --git a/src/EcsGroupExtensions.cs b/src/EcsGroupExtensions.cs new file mode 100644 index 0000000..33bad9d --- /dev/null +++ b/src/EcsGroupExtensions.cs @@ -0,0 +1,14 @@ +namespace DCFApixels.DragonECS +{ + public static class EcsGroupExtensions + { + public static void IterateParallel(this EcsGroup self, ThreadWorkerHandler worker, int minSpanSize) + { + IterateParallel(self, worker, minSpanSize); + } + public static void IterateParallel(this EcsReadonlyGroup self, ThreadWorkerHandler worker, int minSpanSize) + { + ThreadRunner.Run(worker, self, minSpanSize); + } + } +} diff --git a/src/ThreadRunner.cs b/src/ThreadRunner.cs index 8185208..964e0cb 100644 --- a/src/ThreadRunner.cs +++ b/src/ThreadRunner.cs @@ -1,101 +1,101 @@ -using DCFApixels.DragonECS; - -internal static class ThreadRunner +namespace DCFApixels.DragonECS { - private readonly static int _maxThreadsCount; - private static ThreadReacord[] _threads; - - private static ThreadWorkerHandler _worker; - private static int[] _entities = new int[64]; - - private static void ThreadProc(object obj) + internal static class ThreadRunner { - ref ThreadReacord record = ref _threads[(int)obj]; - try - { - while (Thread.CurrentThread.IsAlive) - { - record.runWork.WaitOne(); - record.runWork.Reset(); - _worker.Invoke(new ReadOnlySpan(_entities, record.start, record.size)); + private readonly static int _maxThreadsCount; + private static ThreadReacord[] _threads; - record.doneWork.Set(); + private static ThreadWorkerHandler _worker; + private static int[] _entities = new int[64]; + + private static void ThreadProc(object obj) + { + ref ThreadReacord record = ref _threads[(int)obj]; + try + { + while (Thread.CurrentThread.IsAlive) + { + record.runWork.WaitOne(); + record.runWork.Reset(); + _worker.Invoke(new ReadOnlySpan(_entities, record.start, record.size)); + + record.doneWork.Set(); + } } + catch { } } - catch { } - } - static ThreadRunner() - { - _maxThreadsCount = Environment.ProcessorCount; - _threads = new ThreadReacord[_maxThreadsCount]; - - for (int i = 0; i < _maxThreadsCount; i++) + static ThreadRunner() { - _threads[i] = new ThreadReacord() + _maxThreadsCount = Environment.ProcessorCount; + _threads = new ThreadReacord[_maxThreadsCount]; + + for (int i = 0; i < _maxThreadsCount; i++) { - thread = new Thread(ThreadProc) { IsBackground = true }, - runWork = new ManualResetEvent(false), - doneWork = new ManualResetEvent(true), - }; - _threads[i].thread.Start(i); + _threads[i] = new ThreadReacord() + { + thread = new Thread(ThreadProc) { IsBackground = true }, + runWork = new ManualResetEvent(false), + doneWork = new ManualResetEvent(true), + }; + _threads[i].thread.Start(i); + } + _worker = delegate { }; } - _worker = delegate { }; - } - public static void Run(ThreadWorkerHandler worker, EcsReadonlyGroup entities, int minSpanSize) - { - _worker = worker; - int entitiesCount = entities.Bake(ref _entities); - - int threadsCount = entitiesCount / minSpanSize; - //if (entitiesCount % minSpanSize > 0) - // threadsCount++; - if (threadsCount > _maxThreadsCount) - threadsCount = _maxThreadsCount; - - if (threadsCount > 1) + public static void Run(ThreadWorkerHandler worker, EcsReadonlyGroup entities, int minSpanSize) { - int spanSize = entitiesCount / (threadsCount - 1); + _worker = worker; + int entitiesCount = entities.Bake(ref _entities); + + int threadsCount = entitiesCount / minSpanSize; + //if (entitiesCount % minSpanSize > 0) + // threadsCount++; + if (threadsCount > _maxThreadsCount) + threadsCount = _maxThreadsCount; + + if (threadsCount > 1) + { + int spanSize = entitiesCount / (threadsCount - 1); + for (int i = 0; i < threadsCount; i++) + { + ref var thread = ref _threads[i]; + thread.start = i * spanSize; + thread.size = spanSize; + } + _threads[^1].size = entities.Count % (threadsCount - 1); + } + else + { + threadsCount = 1; + ref var thread = ref _threads[0]; + thread.start = 0; + thread.size = entitiesCount; + } + for (int i = 0; i < threadsCount; i++) { ref var thread = ref _threads[i]; - thread.start = i * spanSize; - thread.size = spanSize; + thread.runWork.Reset(); + thread.runWork.Set(); } - _threads[^1].size = entities.Count % (threadsCount - 1); - } - else - { - threadsCount = 1; - ref var thread = ref _threads[0]; - thread.start = 0; - thread.size = entitiesCount; + for (int i = 0; i < threadsCount; i++) + { + _threads[i].doneWork.WaitOne(); + } + + _worker = null; } - for (int i = 0; i < threadsCount; i++) + private struct ThreadReacord { - ref var thread = ref _threads[i]; - thread.runWork.Reset(); - thread.runWork.Set(); - } - for (int i = 0; i < threadsCount; i++) - { - _threads[i].doneWork.WaitOne(); - } + public Thread thread; + public ManualResetEvent runWork; + public ManualResetEvent doneWork; - _worker = null; + public int start; + public int size; + } } - public delegate void ThreadWorkerHandler(ReadOnlySpan entities); - - private struct ThreadReacord - { - public Thread thread; - public ManualResetEvent runWork; - public ManualResetEvent doneWork; - - public int start; - public int size; - } } \ No newline at end of file