package com.hypixel.hytale.builtin.hytalegenerator.datastructures.voxelspace;
import com.hypixel.hytale.builtin.hytalegenerator.LoggerUtil;
import com.hypixel.hytale.common.util.ExceptionUtil;
import java.util.LinkedList;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ExecutionException;
import javax.annotation.Nonnull;
public class VoxelSpaceUtil {
public VoxelSpaceUtil() {
}
public static <V> void parallelCopy(@Nonnull VoxelSpace<V> source, @Nonnull VoxelSpace<V> destination, int concurrency) {
if (concurrency < 1) {
throw new IllegalArgumentException("negative concurrency");
} else {
int minX = source.minX();
int minY = source.minY();
int minZ = source.minZ();
int sizeX = source.sizeX();
int sizeY = source.sizeY();
int sizeZ = source.sizeZ();
LinkedList<CompletableFuture<Void>> tasks = new LinkedList();
int bSize = source.sizeX() * source.sizeY() * source.sizeZ() / concurrency;
for(int b = 0; b < concurrency; ++b) {
tasks.add(CompletableFuture.runAsync(() -> {
for(int i = b * bSize; i < (b + 1) * bSize; ++i) {
int x = i % sizeX + minX;
int y = i / sizeX % sizeY + minY;
int z = i / (sizeX * sizeY) % sizeZ + minZ;
if (source.isInsideSpace(x, y, z) && destination.isInsideSpace(x, y, z)) {
destination.set(source.getContent(x, y, z), x, y, z);
}
}
}).handle((r, ex) -> {
if (ex == null) {
return r;
} else {
LoggerUtil.logException("a VoxelSpace async process", ex, LoggerUtil.getLogger());
return null;
}
}));
}
try {
while(!tasks.isEmpty()) {
((CompletableFuture)tasks.removeFirst()).get();
}
} catch (ExecutionException | InterruptedException e) {
Thread.currentThread().interrupt();
String msg = "Exception thrown by HytaleGenerator while attempting an asynchronous copy of a VoxelSpace:\n";
msg = msg + ExceptionUtil.toStringWithStack(e);
LoggerUtil.getLogger().severe(msg);
}
}
}
private static class BatchTransfer<T> implements Runnable {
private final VoxelSpace<T> source;
private final VoxelSpace<T> destination;
private final int minX;
private final int minY;
private final int minZ;
private final int maxX;
private final int maxY;
private final int maxZ;
private BatchTransfer(VoxelSpace<T> source, VoxelSpace<T> destination, int minX, int minY, int minZ, int maxX, int maxY, int maxZ) {
this.source = source;
this.destination = destination;
this.minX = minX;
this.minY = minY;
this.minZ = minZ;
this.maxX = maxX;
this.maxY = maxY;
this.maxZ = maxZ;
}
public void run() {
try {
for(int x = this.minX; x < this.maxX; ++x) {
for(int y = this.minY; y < this.maxY; ++y) {
for(int z = this.minZ; z < this.maxZ; ++z) {
if (this.destination.isInsideSpace(x, y, z)) {
this.destination.set(this.source.getContent(x, y, z), x, y, z);
}
}
}
}
} catch (Exception e) {
String msg = "Exception thrown by HytaleGenerator while attempting a BatchTransfer operation:\n";
msg = msg + ExceptionUtil.toStringWithStack(e);
LoggerUtil.getLogger().severe(msg);
}
}
}
}