package com.hypixel.hytale.component.system.data; 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 it.unimi.dsi.fastutil.objects.ObjectArrayList; import java.util.List; import java.util.function.IntConsumer; import javax.annotation.Nonnull; import javax.annotation.Nullable; public abstract class EntityDataSystem extends ArchetypeDataSystem { public boolean isParallel() { return false; } @Override public void fetch( @Nonnull ArchetypeChunk archetypeChunk, @Nonnull Store store, @Nonnull CommandBuffer commandBuffer, Q query, List results ) { doFetch(this, archetypeChunk, store, commandBuffer, query, results); } public abstract void fetch(int var1, ArchetypeChunk var2, Store var3, CommandBuffer var4, Q var5, List var6); public static void doFetch( @Nonnull EntityDataSystem system, @Nonnull ArchetypeChunk archetypeChunk, @Nonnull Store store, @Nonnull CommandBuffer commandBuffer, Q query, List results ) { if (system.isParallel()) { int size = archetypeChunk.size(); if (size == 0) { return; } ParallelTask> task = store.getFetchTask(); ParallelRangeTask> systemTask = task.appendTask(); systemTask.init(0, size); int i = 0; for (int systemTaskSize = systemTask.size(); i < systemTaskSize; i++) { ((EntityDataSystem.SystemTaskData)systemTask.get(i)).init(system, archetypeChunk, store, commandBuffer.fork(), query); } } else { int index = 0; for (int archetypeChunkSize = archetypeChunk.size(); index < archetypeChunkSize; index++) { system.fetch(index, archetypeChunk, store, commandBuffer, query, results); } } } public static class SystemTaskData implements IntConsumer { private final List results = new ObjectArrayList(); @Nullable private EntityDataSystem system; @Nullable private ArchetypeChunk archetypeChunk; @Nullable private Store store; @Nullable private CommandBuffer commandBuffer; @Nullable private Q query; public void init( EntityDataSystem system, ArchetypeChunk archetypeChunk, Store store, CommandBuffer commandBuffer, Q query ) { this.system = system; this.archetypeChunk = archetypeChunk; this.store = store; this.commandBuffer = commandBuffer; this.query = query; } @Override public void accept(int index) { assert this.commandBuffer.setThread(); this.system.fetch(index, this.archetypeChunk, this.store, this.commandBuffer, this.query, this.results); } public void clear() { this.system = null; this.archetypeChunk = null; this.store = null; this.commandBuffer = null; this.query = null; this.results.clear(); } public static void invokeParallelTask( @Nonnull ParallelTask> parallelTask, @Nonnull CommandBuffer commandBuffer, @Nonnull List results ) { 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++) { EntityDataSystem.SystemTaskData taskData = systemTask.get(i); results.addAll(taskData.results); taskData.commandBuffer.mergeParallel(commandBuffer); taskData.clear(); } } } } } }