package com.hypixel.hytale.component.system.tick; import com.hypixel.hytale.component.ArchetypeChunk; import com.hypixel.hytale.component.CommandBuffer; import com.hypixel.hytale.component.Store; import com.hypixel.hytale.component.task.ParallelRangeTask; import com.hypixel.hytale.component.task.ParallelTask; import java.util.function.IntConsumer; import javax.annotation.Nonnull; import javax.annotation.Nullable; public abstract class EntityTickingSystem extends ArchetypeTickingSystem { protected static boolean maybeUseParallel(int archetypeChunkSize, int taskCount) { return false; } protected static boolean useParallel(int archetypeChunkSize, int taskCount) { return taskCount > 0 || archetypeChunkSize > ParallelRangeTask.PARALLELISM; } public boolean isParallel(int archetypeChunkSize, int taskCount) { return false; } @Override public void tick(float dt, @Nonnull ArchetypeChunk archetypeChunk, @Nonnull Store store, @Nonnull CommandBuffer commandBuffer) { doTick(this, dt, archetypeChunk, store, commandBuffer); } public abstract void tick(float var1, int var2, @Nonnull ArchetypeChunk var3, @Nonnull Store var4, @Nonnull CommandBuffer var5); public static void doTick( @Nonnull EntityTickingSystem system, float dt, @Nonnull ArchetypeChunk archetypeChunk, @Nonnull Store store, @Nonnull CommandBuffer commandBuffer ) { int archetypeChunkSize = archetypeChunk.size(); if (archetypeChunkSize != 0) { ParallelTask> task = store.getParallelTask(); if (system.isParallel(archetypeChunkSize, task.size())) { ParallelRangeTask> systemTask = task.appendTask(); systemTask.init(0, archetypeChunkSize); int i = 0; for (int systemTaskSize = systemTask.size(); i < systemTaskSize; i++) { systemTask.get(i).init(system, dt, archetypeChunk, store, commandBuffer.fork()); } } else { for (int index = 0; index < archetypeChunkSize; index++) { system.tick(dt, index, archetypeChunk, store, commandBuffer); } } } } public static class SystemTaskData implements IntConsumer { @Nullable private EntityTickingSystem system; private float dt; @Nullable private ArchetypeChunk archetypeChunk; @Nullable private Store store; @Nullable private CommandBuffer commandBuffer; public void init( EntityTickingSystem system, float dt, ArchetypeChunk archetypeChunk, Store store, CommandBuffer commandBuffer ) { this.system = system; this.dt = dt; this.archetypeChunk = archetypeChunk; this.store = store; this.commandBuffer = commandBuffer; } @Override public void accept(int index) { assert this.commandBuffer.setThread(); this.system.tick(this.dt, index, this.archetypeChunk, this.store, this.commandBuffer); } public void clear() { this.system = null; this.archetypeChunk = null; this.store = null; this.commandBuffer = null; } public static void invokeParallelTask( @Nonnull ParallelTask> parallelTask, @Nonnull CommandBuffer commandBuffer ) { int parallelTaskSize = parallelTask.size(); if (parallelTaskSize > 0) { parallelTask.doInvoke(); for (int x = 0; x < parallelTaskSize; x++) { ParallelRangeTask> systemTask = parallelTask.get(x); int i = 0; for (int systemTaskSize = systemTask.size(); i < systemTaskSize; i++) { EntityTickingSystem.SystemTaskData taskData = systemTask.get(i); taskData.commandBuffer.mergeParallel(commandBuffer); taskData.clear(); } } } } } }