Amazing pregenerator!

This commit is contained in:
Daniel Mills 2021-01-01 22:54:03 -05:00
parent dfaf361bf2
commit fcf8a80b0a

View File

@ -27,6 +27,7 @@ import java.nio.file.Files;
import java.nio.file.Path; import java.nio.file.Path;
import java.nio.file.Paths; import java.nio.file.Paths;
import java.util.Comparator; import java.util.Comparator;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.atomic.AtomicBoolean; import java.util.concurrent.atomic.AtomicBoolean;
import java.util.concurrent.atomic.AtomicInteger; import java.util.concurrent.atomic.AtomicInteger;
import java.util.concurrent.atomic.AtomicLong; import java.util.concurrent.atomic.AtomicLong;
@ -37,13 +38,13 @@ import java.util.concurrent.locks.ReentrantLock;
public class Pregenerator implements Listener public class Pregenerator implements Listener
{ {
private static Pregenerator instance; private static Pregenerator instance;
private static final Color COLOR_MCA_PREPARE = Color.DARK_GRAY; private static final Color COLOR_MCA_PREPARE = Color.decode("#16211d");
private static final Color COLOR_MCA_GENERATE = Color.MAGENTA; private static final Color COLOR_MCA_GENERATE = Color.decode("#34c0eb");
private static final Color COLOR_MCA_GENERATE_SLOW = Color.YELLOW; private static final Color COLOR_MCA_GENERATE_SLOW = Color.decode("#34c0eb");
private static final Color COLOR_MCA_GENERATED = Color.GREEN; private static final Color COLOR_MCA_GENERATE_SLOW_ASYNC = Color.decode("#34c0eb");
private static final Color COLOR_MCA_SEALED = Color.GREEN; private static final Color COLOR_MCA_GENERATED = Color.decode("#34eb83");
private static final Color COLOR_MCA_SEALING = Color.GREEN.darker().darker(); private static final Color COLOR_MCA_SEALED = Color.decode("#34eb83");
private static final Color COLOR_MCA_DEFERRED = Color.YELLOW.darker().darker(); private static final Color COLOR_MCA_DEFERRED = Color.decode("#211617");
private final World world; private final World world;
private final DirectWorldWriter directWriter; private final DirectWorldWriter directWriter;
private final AtomicBoolean active; private final AtomicBoolean active;
@ -66,12 +67,18 @@ public class Pregenerator implements Listener
private final AtomicInteger vcaz; private final AtomicInteger vcaz;
private final long elapsed; private final long elapsed;
public Pregenerator(World world, int blockSize, int xoffset, int zoffset) public Pregenerator(World world, int blockSize, Runnable onComplete)
{
this(world, blockSize);
this.onComplete.add(onComplete);
}
public Pregenerator(World world, int blockSize)
{ {
instance(); instance();
elapsed = M.ms(); elapsed = M.ms();
memoryMetric = new AtomicReference<>("..."); memoryMetric = new AtomicReference<>("...");
method = new AtomicReference<>("IDLE"); method = new AtomicReference<>("STARTUP");
memory = new AtomicLong(0); memory = new AtomicLong(0);
this.world = world; this.world = world;
vmcax = new AtomicInteger(); vmcax = new AtomicInteger();
@ -92,24 +99,28 @@ public class Pregenerator implements Listener
onComplete = new KList<>(); onComplete = new KList<>();
max = new ChunkPosition(0,0); max = new ChunkPosition(0,0);
min = new ChunkPosition(0,0); min = new ChunkPosition(0,0);
KList<Runnable> draw = new KList<>();
new Spiraler(mcaSize, mcaSize, (xx,zz) -> { new Spiraler(mcaSize, mcaSize, (xx,zz) -> {
min.setX(Math.min(xx << 5, min.getX())); min.setX(Math.min(xx << 5, min.getX()));
min.setZ(Math.min(zz << 5, min.getZ())); min.setZ(Math.min(zz << 5, min.getZ()));
max.setX(Math.max((xx << 5) + 31, max.getX())); max.setX(Math.max((xx << 5) + 31, max.getX()));
max.setZ(Math.max((zz << 5) + 31, max.getZ())); max.setZ(Math.max((zz << 5) + 31, max.getZ()));
totalChunks.getAndAdd(1024); totalChunks.getAndAdd(1024);
draw.add(() -> drawMCA(xx, zz, COLOR_MCA_PREPARE));
}).drain(); }).drain();
gui = IrisSettings.get().isLocalPregenGui() && IrisSettings.get().isUseServerLaunchedGuis() ? MCAPregenGui.createAndShowGUI(this) : null; gui = IrisSettings.get().getGui().isLocalPregenGui() && IrisSettings.get().getGui().isUseServerLaunchedGuis() ? MCAPregenGui.createAndShowGUI(this) : null;
flushWorld();
KList<ChunkPosition> order = computeChunkOrder(); KList<ChunkPosition> order = computeChunkOrder();
Consumer3<Integer, Integer, Consumer2<Integer, Integer>> mcaIteration = Consumer3<Integer, Integer, Consumer2<Integer, Integer>> mcaIteration =
(ox, oz, r) -> order.forEach((i) (ox, oz, r) -> order.forEach((i)
-> r.accept(i.getX() + ox, i.getZ() + oz)); -> r.accept(i.getX() + ox, i.getZ() + oz));
draw.forEach(Runnable::run);
Spiraler spiraler = new Spiraler(mcaSize, mcaSize, (xx,zz) -> { Spiraler spiraler = new Spiraler(mcaSize, mcaSize, (xx,zz) -> {
vmcax.set(xx); vmcax.set(xx);
vmcaz.set(zz); vmcaz.set(zz);
flushWorld(); flushWorld();
drawMCA(xx, zz, COLOR_MCA_PREPARE); drawMCA(xx, zz, COLOR_MCA_PREPARE);
if(generateMCARegion(xx, zz, burst, access, mcaIteration)) if(access != null && generateMCARegion(xx, zz, burst, access, mcaIteration))
{ {
flushWorld(); flushWorld();
} }
@ -117,9 +128,15 @@ public class Pregenerator implements Listener
else else
{ {
drawMCA(xx, zz, COLOR_MCA_DEFERRED); drawMCA(xx, zz, COLOR_MCA_DEFERRED);
mcaDefer.add(new ChunkPosition(xx, zz));
} }
}); });
new Thread(() -> { new Thread(() -> {
flushWorld();
J.sleep(2000);
flushWorld();
while(running.get() && spiraler.hasNext()) while(running.get() && spiraler.hasNext())
{ {
if(active.get()) if(active.get())
@ -135,8 +152,7 @@ public class Pregenerator implements Listener
ChunkPosition p = mcaDefer.popLast(); ChunkPosition p = mcaDefer.popLast();
vmcax.set(p.getX()); vmcax.set(p.getX());
vmcaz.set(p.getZ()); vmcaz.set(p.getZ());
generateDeferedMCARegion(p.getX(), p.getZ(), burst, access, mcaIteration); generateDeferedMCARegion(p.getX(), p.getZ(), burst, mcaIteration);
drawMCA(p.getX(), p.getZ(), COLOR_MCA_SEALING);
flushWorld(); flushWorld();
drawMCA(p.getX(), p.getZ(), COLOR_MCA_SEALED); drawMCA(p.getX(), p.getZ(), COLOR_MCA_SEALED);
} }
@ -200,10 +216,11 @@ public class Pregenerator implements Listener
})); }));
e.complete(); e.complete();
directWriter.flush(); directWriter.flush();
try { if(!install(mcg, mca))
Files.move(fileToMovePath, targetPath); {
} catch (IOException ef) { drawMCA(x, z, COLOR_MCA_DEFERRED);
ef.printStackTrace(); generated.set(generated.get() - 1024);
mcaDefer.add(new ChunkPosition(x, z));
} }
} }
@ -217,22 +234,48 @@ public class Pregenerator implements Listener
return true; return true;
} }
private void generateDeferedMCARegion(int x, int z, MultiBurst burst, IrisAccess access, Consumer3<Integer, Integer, Consumer2<Integer, Integer>> mcaIteration) { private boolean install(File from, File to) {
try
{
Files.move(from.toPath(), to.toPath());
return true;
}
catch(Throwable ignored)
{
}
try {
IO.copyFile(from, to);
from.delete();
return true;
} catch (IOException ignored) {
}
return false;
}
private void generateDeferedMCARegion(int x, int z, MultiBurst burst, Consumer3<Integer, Integer, Consumer2<Integer, Integer>> mcaIteration) {
BurstExecutor e = burst.burst(1024); BurstExecutor e = burst.burst(1024);
int mcaox = x << 5; int mcaox = x << 5;
int mcaoz = z << 5; int mcaoz = z << 5;
if(PaperLib.isPaper()) if(PaperLib.isPaper())
{ {
method.set("PaperAsync (Slow)"); method.set("PaperAsync (Slow)");
mcaIteration.accept(mcaox, mcaoz, (ii, jj) -> e.queue(() -> { mcaIteration.accept(mcaox, mcaoz, (ii, jj) -> {
draw(ii, jj, COLOR_MCA_GENERATE_SLOW); draw(ii, jj, COLOR_MCA_GENERATE_SLOW);
access.generatePaper(world, ii, jj); CompletableFuture<Chunk> cc = PaperLib.getChunkAtAsync(world, ii, jj);
draw(ii, jj, COLOR_MCA_GENERATED); draw(ii, jj, COLOR_MCA_GENERATE_SLOW_ASYNC);
generated.getAndIncrement(); e.queue(() -> {
vcax.set(ii); cc.join();
vcaz.set(jj); draw(ii, jj, COLOR_MCA_GENERATED);
})); generated.getAndIncrement();
vcax.set(ii);
vcaz.set(jj);
});
});
e.complete(); e.complete();
} }
@ -474,7 +517,7 @@ public class Pregenerator implements Listener
g.drawString("Press P to Pause", 20, hh += h); g.drawString("Press P to Pause", 20, hh += h);
} }
J.sleep((long) (IrisSettings.get().isMaximumPregenGuiFPS() ? 4 : 250)); J.sleep((long) (IrisSettings.get().getGui().isMaximumPregenGuiFPS() ? 4 : 250));
repaint(); repaint();
} }
@ -557,7 +600,7 @@ public class Pregenerator implements Listener
{ {
if(e.getKeyCode() == KeyEvent.VK_P) if(e.getKeyCode() == KeyEvent.VK_P)
{ {
PregenJob.pauseResume(); Pregenerator.pauseResume();
} }
} }