From 6cfd055becbde4aff9032bdf8054c8367e00d1af Mon Sep 17 00:00:00 2001 From: Daniel Mills Date: Mon, 19 Jul 2021 04:21:22 -0400 Subject: [PATCH 01/27] Pos utils --- .../com/volmit/iris/util/math/Position2.java | 24 +++++++++++++++++++ 1 file changed, 24 insertions(+) diff --git a/src/main/java/com/volmit/iris/util/math/Position2.java b/src/main/java/com/volmit/iris/util/math/Position2.java index 94be84e6e..4b1704145 100644 --- a/src/main/java/com/volmit/iris/util/math/Position2.java +++ b/src/main/java/com/volmit/iris/util/math/Position2.java @@ -52,6 +52,26 @@ public class Position2 { return result; } + public Position2 topLeftChunkOfRegion() + { + return new Position2((x >> 5) << 5, (z >> 5) << 5); + } + + public Position2 bottomRightChunkOfRegion() + { + return new Position2((((x >> 5)+1) << 5) - 1, (((z >> 5)+1) << 5) - 1); + } + + public Position2 topRightChunkOfRegion() + { + return new Position2((((x >> 5)+1) << 5) - 1, (z >> 5) << 5); + } + + public Position2 bottomLeftChunkOfRegion() + { + return new Position2((x >> 5) << 5, (((z >> 5)+1) << 5) - 1); + } + @Override public boolean equals(Object obj) { if (this == obj) { @@ -66,4 +86,8 @@ public class Position2 { public double distance(Position2 center) { return Math.pow(center.getX() - x, 2) + Math.pow(center.getZ() - z, 2); } + + public Position2 add(int x, int z) { + return new Position2(this.x + x, this.z + z); + } } From def4e193596507611955a35dd2b5a1bdb7e1bd82 Mon Sep 17 00:00:00 2001 From: Daniel Mills Date: Mon, 19 Jul 2021 04:21:33 -0400 Subject: [PATCH 02/27] Tweaks to headless gens --- .../com/volmit/iris/engine/headless/HeadlessGenerator.java | 6 ++++++ .../java/com/volmit/iris/engine/headless/HeadlessWorld.java | 6 ++++++ 2 files changed, 12 insertions(+) diff --git a/src/main/java/com/volmit/iris/engine/headless/HeadlessGenerator.java b/src/main/java/com/volmit/iris/engine/headless/HeadlessGenerator.java index 68a2dcbc9..95b4e7251 100644 --- a/src/main/java/com/volmit/iris/engine/headless/HeadlessGenerator.java +++ b/src/main/java/com/volmit/iris/engine/headless/HeadlessGenerator.java @@ -18,6 +18,7 @@ package com.volmit.iris.engine.headless; +import com.volmit.iris.core.pregenerator.PregenListener; import com.volmit.iris.engine.data.mca.NBTWorld; import com.volmit.iris.engine.framework.EngineCompositeGenerator; import com.volmit.iris.engine.parallel.MultiBurst; @@ -51,6 +52,11 @@ public class HeadlessGenerator { generator.directWriteMCA(world.getWorld(), x, z, writer, burst); } + public void generateRegion(int x, int z, PregenListener listener) + { + generator.directWriteMCA(world.getWorld(), x, z, writer, burst, listener); + } + public File generateRegionToFile(int x, int z) { generateRegionToFile(x, z); diff --git a/src/main/java/com/volmit/iris/engine/headless/HeadlessWorld.java b/src/main/java/com/volmit/iris/engine/headless/HeadlessWorld.java index c0c09565a..4397274f9 100644 --- a/src/main/java/com/volmit/iris/engine/headless/HeadlessWorld.java +++ b/src/main/java/com/volmit/iris/engine/headless/HeadlessWorld.java @@ -20,7 +20,9 @@ package com.volmit.iris.engine.headless; import com.volmit.iris.Iris; import com.volmit.iris.core.IrisDataManager; +import com.volmit.iris.engine.IrisWorlds; import com.volmit.iris.engine.framework.EngineCompositeGenerator; +import com.volmit.iris.engine.framework.IrisAccess; import com.volmit.iris.engine.object.IrisDimension; import com.volmit.iris.engine.object.common.IrisWorld; import com.volmit.iris.util.plugin.VolmitSender; @@ -73,6 +75,10 @@ public class HeadlessWorld { .createWorld(); } + public static HeadlessWorld from(World world) { + return new HeadlessWorld(world.getName(), IrisWorlds.access(world).getTarget().getDimension(), world.getSeed()); + } + public static HeadlessWorld from(String name, String dimension, long seed) { return new HeadlessWorld(name, IrisDataManager.loadAnyDimension(dimension), seed); From 6d79d3d1f812af0c5365e1910e18ad58c8caa11d Mon Sep 17 00:00:00 2001 From: Daniel Mills Date: Mon, 19 Jul 2021 04:21:49 -0400 Subject: [PATCH 03/27] Support pregen listeners in iris comp gen --- .../PregenListener.java} | 19 +++++++++++++++++-- .../framework/EngineCompositeGenerator.java | 18 +++++++++++++++++- .../iris/engine/framework/IrisAccess.java | 3 +++ 3 files changed, 37 insertions(+), 3 deletions(-) rename src/main/java/com/volmit/iris/core/{gui/PregeneratorGUI.java => pregenerator/PregenListener.java} (59%) diff --git a/src/main/java/com/volmit/iris/core/gui/PregeneratorGUI.java b/src/main/java/com/volmit/iris/core/pregenerator/PregenListener.java similarity index 59% rename from src/main/java/com/volmit/iris/core/gui/PregeneratorGUI.java rename to src/main/java/com/volmit/iris/core/pregenerator/PregenListener.java index 0aada2f15..5faec9d13 100644 --- a/src/main/java/com/volmit/iris/core/gui/PregeneratorGUI.java +++ b/src/main/java/com/volmit/iris/core/pregenerator/PregenListener.java @@ -16,7 +16,22 @@ * along with this program. If not, see . */ -package com.volmit.iris.core.gui; +package com.volmit.iris.core.pregenerator; -public class PregeneratorGUI { +public interface PregenListener { + void onTick(double chunksPerSecond, double chunksPerMinute, double regionsPerMinute, double percent, int generated, int totalChunks, int chunksRemaining, long eta, long elapsed, String method); + + void onChunkGenerating(int x, int z); + + void onChunkGenerated(int x, int z); + + void onRegionGenerated(int x, int z); + + void onRegionGenerating(int x, int z); + + void onRegionSkipped(int x, int z); + + void onClose(); + + void onSaving(); } diff --git a/src/main/java/com/volmit/iris/engine/framework/EngineCompositeGenerator.java b/src/main/java/com/volmit/iris/engine/framework/EngineCompositeGenerator.java index f16276dcb..bf3067f66 100644 --- a/src/main/java/com/volmit/iris/engine/framework/EngineCompositeGenerator.java +++ b/src/main/java/com/volmit/iris/engine/framework/EngineCompositeGenerator.java @@ -23,6 +23,7 @@ import com.volmit.iris.core.IrisDataManager; import com.volmit.iris.core.IrisSettings; import com.volmit.iris.core.nms.BiomeBaseInjector; import com.volmit.iris.core.nms.INMS; +import com.volmit.iris.core.pregenerator.PregenListener; import com.volmit.iris.engine.IrisEngineCompound; import com.volmit.iris.engine.IrisWorlds; import com.volmit.iris.engine.cache.Cache; @@ -460,6 +461,11 @@ public class EngineCompositeGenerator extends ChunkGenerator implements IrisAcce @Override public void directWriteMCA(IrisWorld w, int x, int z, NBTWorld writer, MultiBurst burst) { + directWriteMCA(w, x, z, writer, burst, null); + } + + @Override + public void directWriteMCA(IrisWorld w, int x, int z, NBTWorld writer, MultiBurst burst, PregenListener l) { BurstExecutor e = burst.burst(1024); int mcaox = x << 5; int mcaoz = z << 5; @@ -468,7 +474,17 @@ public class EngineCompositeGenerator extends ChunkGenerator implements IrisAcce int ii = i; for (int j = 0; j < 32; j++) { int jj = j; - e.queue(() -> directWriteChunk(w, ii + mcaox, jj + mcaoz, writer)); + e.queue(() -> { + if(l != null) + { + l.onChunkGenerating(ii + mcaox, jj + mcaoz); + } + directWriteChunk(w, ii + mcaox, jj + mcaoz, writer); + if(l != null) + { + l.onChunkGenerated(ii + mcaox, jj + mcaoz); + } + }); } } diff --git a/src/main/java/com/volmit/iris/engine/framework/IrisAccess.java b/src/main/java/com/volmit/iris/engine/framework/IrisAccess.java index 8c6e692f7..1f8919b50 100644 --- a/src/main/java/com/volmit/iris/engine/framework/IrisAccess.java +++ b/src/main/java/com/volmit/iris/engine/framework/IrisAccess.java @@ -20,6 +20,7 @@ package com.volmit.iris.engine.framework; import com.volmit.iris.Iris; import com.volmit.iris.core.IrisDataManager; +import com.volmit.iris.core.pregenerator.PregenListener; import com.volmit.iris.engine.IrisComplex; import com.volmit.iris.engine.data.DataProvider; import com.volmit.iris.engine.data.mca.NBTWorld; @@ -47,6 +48,8 @@ public interface IrisAccess extends Hotloadable, DataProvider { void directWriteMCA(IrisWorld w, int x, int z, NBTWorld writer, MultiBurst burst); + void directWriteMCA(IrisWorld w, int x, int z, NBTWorld writer, MultiBurst burst, PregenListener listener); + void directWriteChunk(IrisWorld w, int x, int z, NBTWorld writer); int getGenerated(); From 98240e910e5506995d679c14d31f5830bdd8162d Mon Sep 17 00:00:00 2001 From: Daniel Mills Date: Mon, 19 Jul 2021 04:21:54 -0400 Subject: [PATCH 04/27] Pregen tasks --- .../iris/core/pregenerator/PregenTask.java | 56 +++++++++++++++++++ 1 file changed, 56 insertions(+) create mode 100644 src/main/java/com/volmit/iris/core/pregenerator/PregenTask.java diff --git a/src/main/java/com/volmit/iris/core/pregenerator/PregenTask.java b/src/main/java/com/volmit/iris/core/pregenerator/PregenTask.java new file mode 100644 index 000000000..ca3b26bf1 --- /dev/null +++ b/src/main/java/com/volmit/iris/core/pregenerator/PregenTask.java @@ -0,0 +1,56 @@ +/* + * Iris is a World Generator for Minecraft Bukkit Servers + * Copyright (c) 2021 Arcane Arts (Volmit Software) + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +package com.volmit.iris.core.pregenerator; + +import com.volmit.iris.util.math.Position2; +import com.volmit.iris.util.math.Spiraled; +import com.volmit.iris.util.math.Spiraler; +import lombok.Builder; +import lombok.Data; + +@Builder +@Data +public class PregenTask { + @Builder.Default + private Position2 center = new Position2(0,0); + + @Builder.Default + private int radius = 1; + + public void iterateRegions(Spiraled s) + { + new Spiraler(radius * 2, radius * 2, s) + .setOffset(center.getX(), center.getZ()).drain(); + } + + public void iterateRegion(int x, int z, Spiraled s) + { + new Spiraler(33, 33, (xx, zz) -> { + if (xx < 0 || xx > 31 || zz < 0 || zz > 31) { + s.on(xx+(x<<5), zz+(z<<5)); + } + }).setOffset(15, 15).drain(); + } + + public void iterateAllChunks(Spiraled s) + { + new Spiraler(radius * 2, radius * 2, (x, z) -> iterateRegion(x, z, s)) + .setOffset(center.getX(), center.getZ()).drain(); + } +} From 309f97b44307f03a91681485c309f77ad8647b85 Mon Sep 17 00:00:00 2001 From: Daniel Mills Date: Mon, 19 Jul 2021 04:22:03 -0400 Subject: [PATCH 05/27] Pregen method api --- .../core/pregenerator/PregeneratorMethod.java | 72 +++++++++++++++++++ 1 file changed, 72 insertions(+) create mode 100644 src/main/java/com/volmit/iris/core/pregenerator/PregeneratorMethod.java diff --git a/src/main/java/com/volmit/iris/core/pregenerator/PregeneratorMethod.java b/src/main/java/com/volmit/iris/core/pregenerator/PregeneratorMethod.java new file mode 100644 index 000000000..9bad0e05a --- /dev/null +++ b/src/main/java/com/volmit/iris/core/pregenerator/PregeneratorMethod.java @@ -0,0 +1,72 @@ +/* + * Iris is a World Generator for Minecraft Bukkit Servers + * Copyright (c) 2021 Arcane Arts (Volmit Software) + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +package com.volmit.iris.core.pregenerator; + +/** + * Represents something that is capable of generating in chunks or regions, or both + */ +public interface PregeneratorMethod { + /** + * This is called before any generate methods are called. Setup your generator here + */ + void init(); + + /** + * This is called after the pregenerator is done. Save your work and stop threads + */ + void close(); + + /** + * This is called every X amount of chunks or regions. Save work, + * but no need to save all of it. At the end, close() will still be called. + */ + void save(); + + /** + * Return true if regions can be generated + * @return true if they can be + * @param x the x region + * @param z the z region + */ + boolean supportsRegions(int x, int z); + + /** + * Return the name of the method being used + * @return the name + * @param x the x region + * @param z the z region + */ + String getMethod(int x, int z); + + /** + * Called to generate a region. Execute sync, if multicore internally, wait + * for the task to complete + * @param x the x + * @param z the z + * @param listener signal chunks generating & generated. Parallel capable. + */ + void generateRegion(int x, int z, PregenListener listener); + + /** + * Called to generate a chunk. You can go async so long as save will wait on the threads to finish + * @param x the x + * @param z the z + */ + void generateChunk(int x, int z); +} From e4da11727af3d61cd570c0ad4b31b59dd16b4c5b Mon Sep 17 00:00:00 2001 From: Daniel Mills Date: Mon, 19 Jul 2021 04:22:14 -0400 Subject: [PATCH 06/27] Pregen methods impl --- .../methods/DummyPregenMethod.java | 59 +++++++++ .../methods/HeadlessPregenMethod.java | 70 +++++++++++ .../methods/HybridPregenMethod.java | 87 +++++++++++++ .../methods/MedievalPregenMethod.java | 80 ++++++++++++ .../methods/PaperAsyncPregenMethod.java | 119 ++++++++++++++++++ .../methods/PaperOrMedievalPregenMethod.java | 68 ++++++++++ 6 files changed, 483 insertions(+) create mode 100644 src/main/java/com/volmit/iris/core/pregenerator/methods/DummyPregenMethod.java create mode 100644 src/main/java/com/volmit/iris/core/pregenerator/methods/HeadlessPregenMethod.java create mode 100644 src/main/java/com/volmit/iris/core/pregenerator/methods/HybridPregenMethod.java create mode 100644 src/main/java/com/volmit/iris/core/pregenerator/methods/MedievalPregenMethod.java create mode 100644 src/main/java/com/volmit/iris/core/pregenerator/methods/PaperAsyncPregenMethod.java create mode 100644 src/main/java/com/volmit/iris/core/pregenerator/methods/PaperOrMedievalPregenMethod.java diff --git a/src/main/java/com/volmit/iris/core/pregenerator/methods/DummyPregenMethod.java b/src/main/java/com/volmit/iris/core/pregenerator/methods/DummyPregenMethod.java new file mode 100644 index 000000000..08c108431 --- /dev/null +++ b/src/main/java/com/volmit/iris/core/pregenerator/methods/DummyPregenMethod.java @@ -0,0 +1,59 @@ +/* + * Iris is a World Generator for Minecraft Bukkit Servers + * Copyright (c) 2021 Arcane Arts (Volmit Software) + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +package com.volmit.iris.core.pregenerator.methods; + +import com.volmit.iris.core.pregenerator.PregenListener; +import com.volmit.iris.core.pregenerator.PregeneratorMethod; + +public class DummyPregenMethod implements PregeneratorMethod { + @Override + public void init() { + + } + + @Override + public void close() { + + } + + @Override + public String getMethod(int x, int z) { + return "Dummy"; + } + + @Override + public void save() { + + } + + @Override + public boolean supportsRegions(int x, int z) { + return false; + } + + @Override + public void generateRegion(int x, int z, PregenListener listener) { + + } + + @Override + public void generateChunk(int x, int z) { + + } +} diff --git a/src/main/java/com/volmit/iris/core/pregenerator/methods/HeadlessPregenMethod.java b/src/main/java/com/volmit/iris/core/pregenerator/methods/HeadlessPregenMethod.java new file mode 100644 index 000000000..c42155da0 --- /dev/null +++ b/src/main/java/com/volmit/iris/core/pregenerator/methods/HeadlessPregenMethod.java @@ -0,0 +1,70 @@ +/* + * Iris is a World Generator for Minecraft Bukkit Servers + * Copyright (c) 2021 Arcane Arts (Volmit Software) + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +package com.volmit.iris.core.pregenerator.methods; + +import com.volmit.iris.core.pregenerator.PregenListener; +import com.volmit.iris.core.pregenerator.PregeneratorMethod; +import com.volmit.iris.engine.headless.HeadlessGenerator; +import com.volmit.iris.engine.headless.HeadlessWorld; + +public class HeadlessPregenMethod implements PregeneratorMethod { + private final HeadlessWorld world; + private final HeadlessGenerator generator; + + public HeadlessPregenMethod(HeadlessWorld world) + { + this.world = world; + this.generator = world.generate(); + } + + @Override + public void init() { + + } + + @Override + public void close() { + generator.close(); + } + + @Override + public void save() { + generator.save(); + } + + @Override + public boolean supportsRegions(int x, int z) { + return true; + } + + @Override + public String getMethod(int x, int z) { + return "Headless"; + } + + @Override + public void generateRegion(int x, int z, PregenListener listener) { + generator.generateRegion(x, z, listener); + } + + @Override + public void generateChunk(int x, int z) { + throw new UnsupportedOperationException(); + } +} diff --git a/src/main/java/com/volmit/iris/core/pregenerator/methods/HybridPregenMethod.java b/src/main/java/com/volmit/iris/core/pregenerator/methods/HybridPregenMethod.java new file mode 100644 index 000000000..b6efb1c25 --- /dev/null +++ b/src/main/java/com/volmit/iris/core/pregenerator/methods/HybridPregenMethod.java @@ -0,0 +1,87 @@ +/* + * Iris is a World Generator for Minecraft Bukkit Servers + * Copyright (c) 2021 Arcane Arts (Volmit Software) + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +package com.volmit.iris.core.pregenerator.methods; + +import com.volmit.iris.core.pregenerator.PregenListener; +import com.volmit.iris.core.pregenerator.PregeneratorMethod; +import com.volmit.iris.engine.IrisWorlds; +import com.volmit.iris.engine.headless.HeadlessWorld; +import org.bukkit.World; + +import java.io.File; + +public class HybridPregenMethod implements PregeneratorMethod { + private final PregeneratorMethod headless; + private final PregeneratorMethod inWorld; + private final World world; + + public HybridPregenMethod(World world, int threads) + { + this.world = world; + headless = supportsHeadless(world) + ? new HeadlessPregenMethod(HeadlessWorld.from(world)) : new DummyPregenMethod(); + inWorld = new PaperOrMedievalPregenMethod(world, threads); + } + + private boolean supportsHeadless(World world) { + return IrisWorlds.access(world) != null; + } + + @Override + public String getMethod(int x, int z) { + return "Hybrid<" + ((supportsRegions(x, z) ? headless.getMethod(x, z) : inWorld.getMethod(x, z)) + ">"); + } + + @Override + public void init() { + headless.init(); + inWorld.init(); + } + + @Override + public void close() { + headless.close(); + inWorld.close(); + } + + @Override + public void save() { + headless.save(); + inWorld.save(); + } + + @Override + public boolean supportsRegions(int x, int z) { + if (headless instanceof DummyPregenMethod) { + return false; + } + + return !new File(world.getWorldFolder(), "region/r." + x + "." + z + ".mca").exists(); + } + + @Override + public void generateRegion(int x, int z, PregenListener listener) { + headless.generateRegion(x, z, listener); + } + + @Override + public void generateChunk(int x, int z) { + inWorld.generateChunk(x, z); + } +} diff --git a/src/main/java/com/volmit/iris/core/pregenerator/methods/MedievalPregenMethod.java b/src/main/java/com/volmit/iris/core/pregenerator/methods/MedievalPregenMethod.java new file mode 100644 index 000000000..51ec8086c --- /dev/null +++ b/src/main/java/com/volmit/iris/core/pregenerator/methods/MedievalPregenMethod.java @@ -0,0 +1,80 @@ +/* + * Iris is a World Generator for Minecraft Bukkit Servers + * Copyright (c) 2021 Arcane Arts (Volmit Software) + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +package com.volmit.iris.core.pregenerator.methods; + +import com.volmit.iris.core.pregenerator.PregenListener; +import com.volmit.iris.core.pregenerator.PregeneratorMethod; +import com.volmit.iris.util.scheduling.J; +import org.bukkit.Chunk; +import org.bukkit.World; + +public class MedievalPregenMethod implements PregeneratorMethod { + private final World world; + + public MedievalPregenMethod(World world) + { + this.world = world; + } + + private void unloadAndSaveAllChunks() { + J.s(() -> { + for(Chunk i : world.getLoadedChunks()) + { + i.unload(true); + } + }); + } + + @Override + public void init() { + unloadAndSaveAllChunks(); + } + + @Override + public void close() { + unloadAndSaveAllChunks(); + world.save(); + } + + @Override + public void save() { + unloadAndSaveAllChunks(); + world.save(); + } + + @Override + public boolean supportsRegions(int x, int z) { + return false; + } + + @Override + public void generateRegion(int x, int z, PregenListener listener) { + throw new UnsupportedOperationException(); + } + + @Override + public String getMethod(int x, int z) { + return "Medieval"; + } + + @Override + public void generateChunk(int x, int z) { + world.getChunkAt(x, z); + } +} diff --git a/src/main/java/com/volmit/iris/core/pregenerator/methods/PaperAsyncPregenMethod.java b/src/main/java/com/volmit/iris/core/pregenerator/methods/PaperAsyncPregenMethod.java new file mode 100644 index 000000000..f38046a23 --- /dev/null +++ b/src/main/java/com/volmit/iris/core/pregenerator/methods/PaperAsyncPregenMethod.java @@ -0,0 +1,119 @@ +/* + * Iris is a World Generator for Minecraft Bukkit Servers + * Copyright (c) 2021 Arcane Arts (Volmit Software) + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +package com.volmit.iris.core.pregenerator.methods; + +import com.volmit.iris.core.pregenerator.PregenListener; +import com.volmit.iris.core.pregenerator.PregeneratorMethod; +import com.volmit.iris.engine.parallel.MultiBurst; +import com.volmit.iris.util.collection.KList; +import com.volmit.iris.util.scheduling.J; +import io.papermc.lib.PaperLib; +import org.bukkit.Chunk; +import org.bukkit.World; + +import java.util.concurrent.CompletableFuture; + +public class PaperAsyncPregenMethod implements PregeneratorMethod { + private final World world; + private final MultiBurst burst; + private final KList> future; + + public PaperAsyncPregenMethod(World world, int threads) + { + if(!PaperLib.isPaper()) + { + throw new UnsupportedOperationException("Cannot use PaperAsync on non paper!"); + } + + this.world = world; + burst = new MultiBurst("Iris PaperAsync Pregenerator", 6, threads); + future = new KList<>(1024); + } + + private void unloadAndSaveAllChunks() { + J.s(() -> { + for(Chunk i : world.getLoadedChunks()) + { + i.unload(true); + } + }); + } + + private void completeChunk(int x, int z) { + try { + PaperLib.getChunkAtAsync(world, x, z, true).get(); + } catch (Throwable e) { + e.printStackTrace(); + } + } + + private void waitForChunks() + { + for(CompletableFuture i : future) + { + try { + i.get(); + } catch (Throwable e) { + e.printStackTrace(); + } + } + + future.clear(); + } + + @Override + public void init() { + unloadAndSaveAllChunks(); + } + + @Override + public String getMethod(int x, int z) { + return "Async"; + } + + @Override + public void close() { + waitForChunks(); + burst.shutdownAndAwait(); + unloadAndSaveAllChunks(); + world.save(); + } + + @Override + public void save() { + waitForChunks(); + unloadAndSaveAllChunks(); + world.save(); + } + + @Override + public boolean supportsRegions(int x, int z) { + return false; + } + + @Override + public void generateRegion(int x, int z, PregenListener listener) { + throw new UnsupportedOperationException(); + } + + @Override + public void generateChunk(int x, int z) { + future.add(burst.complete(() -> completeChunk(x, z))); + } +} diff --git a/src/main/java/com/volmit/iris/core/pregenerator/methods/PaperOrMedievalPregenMethod.java b/src/main/java/com/volmit/iris/core/pregenerator/methods/PaperOrMedievalPregenMethod.java new file mode 100644 index 000000000..4608b68e6 --- /dev/null +++ b/src/main/java/com/volmit/iris/core/pregenerator/methods/PaperOrMedievalPregenMethod.java @@ -0,0 +1,68 @@ +/* + * Iris is a World Generator for Minecraft Bukkit Servers + * Copyright (c) 2021 Arcane Arts (Volmit Software) + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +package com.volmit.iris.core.pregenerator.methods; + +import com.volmit.iris.core.pregenerator.PregenListener; +import com.volmit.iris.core.pregenerator.PregeneratorMethod; +import io.papermc.lib.PaperLib; +import org.bukkit.World; + +public class PaperOrMedievalPregenMethod implements PregeneratorMethod { + private final PregeneratorMethod method; + + public PaperOrMedievalPregenMethod(World world, int threads) + { + method = PaperLib.isPaper() ? new PaperAsyncPregenMethod(world, threads) : new MedievalPregenMethod(world); + } + + @Override + public void init() { + method.init(); + } + + @Override + public void close() { + method.close(); + } + + @Override + public void save() { + method.save(); + } + + @Override + public String getMethod(int x, int z) { + return method.getMethod(x, z); + } + + @Override + public boolean supportsRegions(int x, int z) { + return false; + } + + @Override + public void generateRegion(int x, int z, PregenListener listener) { + throw new UnsupportedOperationException(); + } + + @Override + public void generateChunk(int x, int z) { + method.generateChunk(x, z); + } +} From 2d531c3a153f776b1184fdd094af856ee15bed55 Mon Sep 17 00:00:00 2001 From: Daniel Mills Date: Mon, 19 Jul 2021 04:22:24 -0400 Subject: [PATCH 07/27] The Iris pregenerator (logic) --- .../core/pregenerator/IrisPregenerator.java | 220 ++++++++++++++++++ 1 file changed, 220 insertions(+) create mode 100644 src/main/java/com/volmit/iris/core/pregenerator/IrisPregenerator.java diff --git a/src/main/java/com/volmit/iris/core/pregenerator/IrisPregenerator.java b/src/main/java/com/volmit/iris/core/pregenerator/IrisPregenerator.java new file mode 100644 index 000000000..c1cedf84c --- /dev/null +++ b/src/main/java/com/volmit/iris/core/pregenerator/IrisPregenerator.java @@ -0,0 +1,220 @@ +/* + * Iris is a World Generator for Minecraft Bukkit Servers + * Copyright (c) 2021 Arcane Arts (Volmit Software) + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +package com.volmit.iris.core.pregenerator; + +import com.google.common.util.concurrent.AtomicDouble; +import com.volmit.iris.util.collection.KList; +import com.volmit.iris.util.collection.KSet; +import com.volmit.iris.util.math.M; +import com.volmit.iris.util.math.Position2; +import com.volmit.iris.util.math.RollingSequence; +import com.volmit.iris.util.scheduling.ChronoLatch; +import com.volmit.iris.util.scheduling.J; +import com.volmit.iris.util.scheduling.Looper; + +import java.util.concurrent.atomic.AtomicBoolean; +import java.util.concurrent.atomic.AtomicInteger; +import java.util.concurrent.atomic.AtomicLong; +import java.util.concurrent.atomic.AtomicReference; + +public class IrisPregenerator { + private final PregenTask task; + private final PregeneratorMethod generator; + private final PregenListener listener; + private final Looper ticker; + private final AtomicBoolean paused; + private final AtomicBoolean shutdown; + private final RollingSequence chunksPerSecond; + private final RollingSequence chunksPerMinute; + private final RollingSequence regionsPerMinute; + private final AtomicInteger generated; + private final AtomicInteger generatedLast; + private final AtomicInteger generatedLastMinute; + private final AtomicInteger totalChunks; + private final AtomicLong startTime; + private final ChronoLatch minuteLatch; + private final AtomicReference currentGeneratorMethod; + + public IrisPregenerator(PregenTask task, PregeneratorMethod generator, PregenListener listener) + { + this.listener = listenify(listener); + this.shutdown = new AtomicBoolean(false); + this.paused = new AtomicBoolean(false); + this.task = task; + this.generator = generator; + currentGeneratorMethod = new AtomicReference<>("Void"); + minuteLatch = new ChronoLatch(60000, false); + chunksPerSecond = new RollingSequence(10); + chunksPerMinute = new RollingSequence(10); + regionsPerMinute = new RollingSequence(10); + generated = new AtomicInteger(0); + generatedLast = new AtomicInteger(0); + generatedLastMinute = new AtomicInteger(0); + totalChunks = new AtomicInteger(0); + startTime = new AtomicLong(M.ms()); + ticker = new Looper() { + @Override + protected long loop() { + long eta = computeETA(); + int secondGenerated = generated.get() - generatedLast.get(); + generatedLast.set(generated.get()); + chunksPerSecond.put(secondGenerated); + + if(minuteLatch.flip()) + { + int minuteGenerated = generated.get() - generatedLastMinute.get(); + generatedLastMinute.set(generated.get()); + chunksPerMinute.put(minuteGenerated); + regionsPerMinute.put((double)minuteGenerated / 1024D); + } + + listener.onTick(chunksPerSecond.getAverage(), chunksPerMinute.getAverage(), + regionsPerMinute.getAverage(), + (double)generated.get() / (double)totalChunks.get(), + generated.get(), totalChunks.get(), + totalChunks.get() - generated.get(), + eta, M.ms() - startTime.get(), currentGeneratorMethod.get()); + return 1000; + } + }; + } + + private long computeETA() { + return (long) ((totalChunks.get() - generated.get()) * + ((double) (M.ms() - startTime.get()) / (double) generated.get())); + } + + public void close() + { + shutdown.set(true); + } + + public void start() + { + init(); + task.iterateRegions((__, ___) -> totalChunks.addAndGet(1024)); + ticker.start(); + task.iterateRegions(this::visitRegion); + shutdown(); + } + + private void init() { + generator.init(); + } + + private void shutdown() { + listener.onSaving(); + generator.close(); + ticker.interrupt(); + listener.onClose(); + } + + private void visitRegion(int x, int z) { + while(paused.get() && !shutdown.get()) + { + J.sleep(50); + } + + if(shutdown.get()) + { + listener.onRegionSkipped(x, z); + return; + } + + listener.onRegionGenerating(x, z); + currentGeneratorMethod.set(generator.getMethod(x, z)); + + if(generator.supportsRegions(x, z)) + { + generator.generateRegion(x, z, listener); + } + + else + { + task.iterateRegion(x, z, (xx, zz) -> { + listener.onChunkGenerating(xx, zz); + generator.generateChunk(xx, zz); + listener.onChunkGenerated(xx, zz); + }); + } + + listener.onRegionGenerated(x, z); + listener.onSaving(); + generator.save(); + } + + public void pause() + { + paused.set(true); + } + + public void resume() + { + paused.set(false); + } + + private PregenListener listenify(PregenListener listener) { + return new PregenListener() { + @Override + public void onTick(double chunksPerSecond, double chunksPerMinute, double regionsPerMinute, double percent, int generated, int totalChunks, int chunksRemaining, long eta, long elapsed, String method) { + listener.onTick( chunksPerSecond, chunksPerMinute, regionsPerMinute, percent, generated, totalChunks, chunksRemaining, eta, elapsed, method); + } + + @Override + public void onChunkGenerating(int x, int z) { + listener.onChunkGenerating(x, z); + } + + @Override + public void onChunkGenerated(int x, int z) { + listener.onChunkGenerated(x, z); + generated.addAndGet(1); + } + + @Override + public void onRegionGenerated(int x, int z) { + listener.onRegionGenerated(x, z); + } + + @Override + public void onRegionGenerating(int x, int z) { + listener.onRegionGenerating(x, z); + } + + @Override + public void onRegionSkipped(int x, int z) { + listener.onRegionSkipped(x, z); + } + + @Override + public void onClose() { + listener.onClose(); + } + + @Override + public void onSaving() { + listener.onSaving(); + } + }; + } + + public boolean paused() { + return paused.get(); + } +} From 5d5a1fadd98479e26934f6db2fd17606da4a2f1b Mon Sep 17 00:00:00 2001 From: Daniel Mills Date: Mon, 19 Jul 2021 04:22:33 -0400 Subject: [PATCH 08/27] The Iris Pregenerator (job) --- .../volmit/iris/core/gui/PregeneratorJob.java | 299 ++++++++++++++++++ 1 file changed, 299 insertions(+) create mode 100644 src/main/java/com/volmit/iris/core/gui/PregeneratorJob.java diff --git a/src/main/java/com/volmit/iris/core/gui/PregeneratorJob.java b/src/main/java/com/volmit/iris/core/gui/PregeneratorJob.java new file mode 100644 index 000000000..bd3f110f9 --- /dev/null +++ b/src/main/java/com/volmit/iris/core/gui/PregeneratorJob.java @@ -0,0 +1,299 @@ +/* + * Iris is a World Generator for Minecraft Bukkit Servers + * Copyright (c) 2021 Arcane Arts (Volmit Software) + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +package com.volmit.iris.core.gui; + +import com.volmit.iris.Iris; +import com.volmit.iris.core.IrisSettings; +import com.volmit.iris.core.gui.components.Pregenerator; +import com.volmit.iris.core.pregenerator.IrisPregenerator; +import com.volmit.iris.core.pregenerator.PregenListener; +import com.volmit.iris.core.pregenerator.PregenTask; +import com.volmit.iris.core.pregenerator.PregeneratorMethod; +import com.volmit.iris.engine.object.IrisBiomeCustom; +import com.volmit.iris.util.collection.KList; +import com.volmit.iris.util.format.Form; +import com.volmit.iris.util.function.Consumer2; +import com.volmit.iris.util.math.M; +import com.volmit.iris.util.math.Position2; +import com.volmit.iris.util.scheduling.J; + +import javax.swing.*; +import java.awt.*; +import java.awt.event.KeyEvent; +import java.awt.event.KeyListener; +import java.awt.image.BufferedImage; +import java.util.concurrent.locks.ReentrantLock; + +public class PregeneratorJob implements PregenListener { + public static PregeneratorJob instance; + private static final Color COLOR_GENERATING = parseColor("#346beb"); + private static final Color COLOR_GENERATED = parseColor("#34eb93"); + private JFrame frame; + private final PregenTask task; + private boolean saving; + private final IrisPregenerator pregenerator; + private PregenRenderer renderer; + private String[] info; + + public PregeneratorJob(PregenTask task, PregeneratorMethod method) + { + instance = this; + saving = false; + info = new String[]{"Initializing..."}; + this.task = task; + this.pregenerator = new IrisPregenerator(task, method, this); + this.pregenerator.start(); + } + + public void draw(int x, int z, Color color) + { + try + { + if(renderer != null && frame != null && frame.isVisible()) + { + renderer.func.accept(new Position2(x, z), color); + } + } + + catch(Throwable ignored) + { + + } + } + + public void stop() + { + J.a(() -> { + pregenerator.close(); + close(); + instance = null; + }); + } + + public void close() + { + J.a(() -> { + try + { + frame.setVisible(false); + } + + catch(Throwable e) + { + + } + }); + } + + public void open() + { + J.a(() -> { + try + { + frame = new JFrame("Pregen View"); + renderer = new PregenRenderer(); + frame.addKeyListener(renderer); + renderer.l = new ReentrantLock(); + renderer.frame = frame; + renderer.job = this; + renderer.func = (c, b) -> + { + renderer.l.lock(); + renderer.order.add(() -> renderer.draw(c, b, renderer.bg)); + renderer.l.unlock(); + }; + frame.add(renderer); + frame.setSize(1000, 1000); + frame.setVisible(true); + } + + catch(Throwable e) + { + + } + }); + } + + @Override + public void onTick(double chunksPerSecond, double chunksPerMinute, double regionsPerMinute, double percent, int generated, int totalChunks, int chunksRemaining, long eta, long elapsed, String method) { + info = new String[] { + (paused() ? "PAUSED" : (saving ? "Saving... " : "Generating")) + " " + Form.f(generated) + " of " + Form.f(totalChunks) + " (" + Form.pc(percent, 0) + " Complete)", + "Speed: " + Form.f(chunksPerSecond, 0) + " Chunks/s, " + Form.f(regionsPerMinute, 1) + " Regions/m, " + Form.f(chunksPerMinute, 0) + " Chunks/m", + Form.duration(eta, 2) + " Remaining " + " (" + Form.duration(elapsed, 2) + " Elapsed)", + "Generation Method: " + method, + }; + } + + @Override + public void onChunkGenerating(int x, int z) { + draw(x, z, COLOR_GENERATING); + } + + @Override + public void onChunkGenerated(int x, int z) { + draw(x, z, COLOR_GENERATED); + } + + @Override + public void onRegionGenerated(int x, int z) { + + } + + @Override + public void onRegionGenerating(int x, int z) { + + } + + @Override + public void onRegionSkipped(int x, int z) { + + } + + @Override + public void onClose() { + close(); + instance = null; + } + + @Override + public void onSaving() { + saving = true; + } + + private Position2 getMax() { + return task.getCenter().add(task.getRadius(), task.getRadius()).bottomRightChunkOfRegion(); + } + + private Position2 getMin() { + return task.getCenter().add(-task.getRadius(), -task.getRadius()).topLeftChunkOfRegion(); + } + + private boolean paused() { + return pregenerator.paused(); + } + + private String[] getProgress() { + return info; + } + + public static class PregenRenderer extends JPanel implements KeyListener { + private PregeneratorJob job; + private static final long serialVersionUID = 2094606939770332040L; + private final KList order = new KList<>(); + private final int res = 512; + Graphics2D bg; + private ReentrantLock l; + private final BufferedImage image = new BufferedImage(res, res, BufferedImage.TYPE_INT_RGB); + private Consumer2 func; + private JFrame frame; + + public PregenRenderer() { + + } + + public void paint(int x, int z, Color c) { + func.accept(new Position2(x, z), c); + } + + @Override + public void paint(Graphics gx) { + Graphics2D g = (Graphics2D) gx; + bg = (Graphics2D) image.getGraphics(); + l.lock(); + + while (order.isNotEmpty()) { + try { + order.pop().run(); + } catch (Throwable e) { + Iris.reportError(e); + + } + } + + l.unlock(); + g.drawImage(image, 0, 0, getParent().getWidth(), getParent().getHeight(), (img, infoflags, x, y, width, height) -> true); + g.setColor(Color.WHITE); + g.setFont(new Font("Hevetica", Font.BOLD, 28)); + String[] prog = job.getProgress(); + int h = g.getFontMetrics().getHeight() + 5; + int hh = 20; + + if (job.paused()) { + g.drawString("PAUSED", 20, hh += h); + + g.drawString("Press P to Resume", 20, hh += h); + } else { + for (String i : prog) { + g.drawString(i, 20, hh += h); + } + + g.drawString("Press P to Pause", 20, hh += h); + } + + J.sleep(IrisSettings.get().getGui().isMaximumPregenGuiFPS() ? 4 : 250); + repaint(); + } + + private void draw(Position2 p, Color c, Graphics2D bg) { + double pw = M.lerpInverse(job.getMin().getX(), job.getMax().getX(), p.getX()); + double ph = M.lerpInverse(job.getMin().getZ(), job.getMax().getZ(), p.getZ()); + double pwa = M.lerpInverse(job.getMin().getX(), job.getMax().getX(), p.getX() + 1); + double pha = M.lerpInverse(job.getMin().getZ(), job.getMax().getZ(), p.getZ() + 1); + int x = (int) M.lerp(0, res, pw); + int z = (int) M.lerp(0, res, ph); + int xa = (int) M.lerp(0, res, pwa); + int za = (int) M.lerp(0, res, pha); + bg.setColor(c); + bg.fillRect(x, z, xa - x, za - z); + } + + @Override + public void keyTyped(KeyEvent e) { + + } + + @Override + public void keyPressed(KeyEvent e) { + + } + + @Override + public void keyReleased(KeyEvent e) { + if (e.getKeyCode() == KeyEvent.VK_P) { + Pregenerator.pauseResume(); + } + } + + public void close() { + frame.setVisible(false); + } + } + + private static Color parseColor(String c) { + String v = (c.startsWith("#") ? c : "#" + c).trim(); + try { + return Color.decode(v); + } catch (Throwable e) { + Iris.reportError(e); + Iris.error("Error Parsing 'color', (" + c + ")"); + } + + return Color.RED; + } +} From 66894c2e8a00ac56ae0ce90898b7254d7a831fed Mon Sep 17 00:00:00 2001 From: Daniel Mills Date: Mon, 19 Jul 2021 04:30:59 -0400 Subject: [PATCH 09/27] Pregen utils for commands --- .../volmit/iris/core/gui/PregeneratorJob.java | 41 +++++++++++++++++++ 1 file changed, 41 insertions(+) diff --git a/src/main/java/com/volmit/iris/core/gui/PregeneratorJob.java b/src/main/java/com/volmit/iris/core/gui/PregeneratorJob.java index bd3f110f9..3f5cb15a7 100644 --- a/src/main/java/com/volmit/iris/core/gui/PregeneratorJob.java +++ b/src/main/java/com/volmit/iris/core/gui/PregeneratorJob.java @@ -18,6 +18,7 @@ package com.volmit.iris.core.gui; +import com.sk89q.worldedit.function.factory.ApplyRegion; import com.volmit.iris.Iris; import com.volmit.iris.core.IrisSettings; import com.volmit.iris.core.gui.components.Pregenerator; @@ -61,6 +62,46 @@ public class PregeneratorJob implements PregenListener { this.pregenerator.start(); } + public static boolean shutdownInstance() { + if(instance == null) + { + return false; + } + + J.a(() -> instance.pregenerator.close()); + return true; + } + + public static PregeneratorJob getInstance() { + return instance; + } + + public static void pauseResume() { + if(instance == null) + { + return; + } + + if(isPaused()) + { + instance.pregenerator.resume(); + } + + else + { + instance.pregenerator.pause(); + } + } + + public static boolean isPaused() { + if(instance == null) + { + return true; + } + + return instance.paused(); + } + public void draw(int x, int z, Color color) { try From 482ca5ed15b72d71799d4fdc9d42f723ee200c04 Mon Sep 17 00:00:00 2001 From: Daniel Mills Date: Mon, 19 Jul 2021 04:31:06 -0400 Subject: [PATCH 10/27] Command tests --- .../core/command/world/CommandIrisPregen.java | 19 ++++++++++++++----- 1 file changed, 14 insertions(+), 5 deletions(-) diff --git a/src/main/java/com/volmit/iris/core/command/world/CommandIrisPregen.java b/src/main/java/com/volmit/iris/core/command/world/CommandIrisPregen.java index de70f9ce3..3cd7571c9 100644 --- a/src/main/java/com/volmit/iris/core/command/world/CommandIrisPregen.java +++ b/src/main/java/com/volmit/iris/core/command/world/CommandIrisPregen.java @@ -19,8 +19,12 @@ package com.volmit.iris.core.command.world; import com.volmit.iris.Iris; +import com.volmit.iris.core.gui.PregeneratorJob; import com.volmit.iris.core.gui.components.Pregenerator; +import com.volmit.iris.core.pregenerator.PregenTask; +import com.volmit.iris.core.pregenerator.methods.PaperOrMedievalPregenMethod; import com.volmit.iris.util.collection.KList; +import com.volmit.iris.util.math.Position2; import com.volmit.iris.util.plugin.MortarCommand; import com.volmit.iris.util.plugin.VolmitSender; import org.bukkit.Bukkit; @@ -69,17 +73,17 @@ public class CommandIrisPregen extends MortarCommand { } if (args[0].equalsIgnoreCase("stop") || args[0].equalsIgnoreCase("x")) { - if (Pregenerator.shutdownInstance()) { + if (PregeneratorJob.shutdownInstance()) { sender.sendMessage("Stopped Pregen."); } else { sender.sendMessage("No Active Pregens."); } return true; } else if (args[0].equalsIgnoreCase("pause") || args[0].equalsIgnoreCase("resume")) { - if (Pregenerator.getInstance() != null) { - Pregenerator.pauseResume(); + if (PregeneratorJob.getInstance() != null) { + PregeneratorJob.pauseResume(); - if (Pregenerator.isPaused()) { + if (PregeneratorJob.isPaused()) { sender.sendMessage("Pregen Paused"); } else { sender.sendMessage("Pregen Resumed"); @@ -105,7 +109,12 @@ public class CommandIrisPregen extends MortarCommand { } } try { - new Pregenerator(world, getVal(args[0]) * 2); + new PregeneratorJob(PregenTask + .builder() + .center(new Position2(0, 0)) + .radius(getVal(args[0])) + .build(), + new PaperOrMedievalPregenMethod(world, 16)); } catch (NumberFormatException e) { Iris.reportError(e); sender.sendMessage("Invalid argument in command"); From bc3aaa94de735d55baff6224c3b8c9967755a8e7 Mon Sep 17 00:00:00 2001 From: Daniel Mills Date: Mon, 19 Jul 2021 04:33:14 -0400 Subject: [PATCH 11/27] Actual command tests --- .../volmit/iris/core/command/world/CommandIrisPregen.java | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/src/main/java/com/volmit/iris/core/command/world/CommandIrisPregen.java b/src/main/java/com/volmit/iris/core/command/world/CommandIrisPregen.java index 3cd7571c9..f34d9a189 100644 --- a/src/main/java/com/volmit/iris/core/command/world/CommandIrisPregen.java +++ b/src/main/java/com/volmit/iris/core/command/world/CommandIrisPregen.java @@ -140,7 +140,12 @@ public class CommandIrisPregen extends MortarCommand { } World world = Bukkit.getWorld(args[1]); try { - new Pregenerator(world, getVal(args[0]) * 2); + new PregeneratorJob(PregenTask + .builder() + .center(new Position2(0, 0)) + .radius(getVal(args[0])) + .build(), + new PaperOrMedievalPregenMethod(world, 16)); } catch (NumberFormatException e) { Iris.reportError(e); sender.sendMessage("Invalid argument in command"); From a0ecf72a1c01f61a0b643549ec9cfa03049910bc Mon Sep 17 00:00:00 2001 From: Daniel Mills Date: Mon, 19 Jul 2021 04:34:34 -0400 Subject: [PATCH 12/27] Open gui on pregen start --- src/main/java/com/volmit/iris/core/gui/PregeneratorJob.java | 1 + 1 file changed, 1 insertion(+) diff --git a/src/main/java/com/volmit/iris/core/gui/PregeneratorJob.java b/src/main/java/com/volmit/iris/core/gui/PregeneratorJob.java index 3f5cb15a7..af3666557 100644 --- a/src/main/java/com/volmit/iris/core/gui/PregeneratorJob.java +++ b/src/main/java/com/volmit/iris/core/gui/PregeneratorJob.java @@ -60,6 +60,7 @@ public class PregeneratorJob implements PregenListener { this.task = task; this.pregenerator = new IrisPregenerator(task, method, this); this.pregenerator.start(); + open(); } public static boolean shutdownInstance() { From 658043690057672f6795deff4ed99a8010dc1769 Mon Sep 17 00:00:00 2001 From: Daniel Mills Date: Mon, 19 Jul 2021 04:37:06 -0400 Subject: [PATCH 13/27] Async pregen start --- src/main/java/com/volmit/iris/core/gui/PregeneratorJob.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/com/volmit/iris/core/gui/PregeneratorJob.java b/src/main/java/com/volmit/iris/core/gui/PregeneratorJob.java index af3666557..f491f76fe 100644 --- a/src/main/java/com/volmit/iris/core/gui/PregeneratorJob.java +++ b/src/main/java/com/volmit/iris/core/gui/PregeneratorJob.java @@ -59,7 +59,7 @@ public class PregeneratorJob implements PregenListener { info = new String[]{"Initializing..."}; this.task = task; this.pregenerator = new IrisPregenerator(task, method, this); - this.pregenerator.start(); + J.a(this.pregenerator::start); open(); } From b2630cfb498e78981db1e741be40a221073f252c Mon Sep 17 00:00:00 2001 From: Daniel Mills Date: Mon, 19 Jul 2021 05:40:43 -0400 Subject: [PATCH 14/27] Pos tostring --- src/main/java/com/volmit/iris/util/math/Position2.java | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/main/java/com/volmit/iris/util/math/Position2.java b/src/main/java/com/volmit/iris/util/math/Position2.java index 4b1704145..2acd4148f 100644 --- a/src/main/java/com/volmit/iris/util/math/Position2.java +++ b/src/main/java/com/volmit/iris/util/math/Position2.java @@ -43,6 +43,11 @@ public class Position2 { this.z = z; } + public String toString() + { + return "[" + x + "," + z + "]"; + } + @Override public int hashCode() { final int prime = 31; From 126481833b9fe0df5fb05645d1fa3d59591cf6ef Mon Sep 17 00:00:00 2001 From: Daniel Mills Date: Mon, 19 Jul 2021 05:40:48 -0400 Subject: [PATCH 15/27] Sync get future --- src/main/java/com/volmit/iris/util/scheduling/J.java | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/src/main/java/com/volmit/iris/util/scheduling/J.java b/src/main/java/com/volmit/iris/util/scheduling/J.java index a9706c505..583492d51 100644 --- a/src/main/java/com/volmit/iris/util/scheduling/J.java +++ b/src/main/java/com/volmit/iris/util/scheduling/J.java @@ -208,6 +208,15 @@ public class J { Bukkit.getScheduler().scheduleSyncDelayedTask(Iris.instance, r); } + public static CompletableFuture sfut(Runnable r) { + CompletableFuture f = new CompletableFuture(); + Bukkit.getScheduler().scheduleSyncDelayedTask(Iris.instance, () -> { + r.run(); + f.complete(null); + }); + return f; + } + /** * Queue a sync task * From 37e70fd5bb3902f08b85a35a7afb12caaaccb547 Mon Sep 17 00:00:00 2001 From: Daniel Mills Date: Mon, 19 Jul 2021 05:41:01 -0400 Subject: [PATCH 16/27] fix pregen command to use mca coords --- .../com/volmit/iris/core/command/world/CommandIrisPregen.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/main/java/com/volmit/iris/core/command/world/CommandIrisPregen.java b/src/main/java/com/volmit/iris/core/command/world/CommandIrisPregen.java index f34d9a189..422150803 100644 --- a/src/main/java/com/volmit/iris/core/command/world/CommandIrisPregen.java +++ b/src/main/java/com/volmit/iris/core/command/world/CommandIrisPregen.java @@ -112,7 +112,7 @@ public class CommandIrisPregen extends MortarCommand { new PregeneratorJob(PregenTask .builder() .center(new Position2(0, 0)) - .radius(getVal(args[0])) + .radius(((getVal(args[0])>>4)>>5) + 1) .build(), new PaperOrMedievalPregenMethod(world, 16)); } catch (NumberFormatException e) { @@ -143,7 +143,7 @@ public class CommandIrisPregen extends MortarCommand { new PregeneratorJob(PregenTask .builder() .center(new Position2(0, 0)) - .radius(getVal(args[0])) + .radius(((getVal(args[0])>>4)>>5) + 1) .build(), new PaperOrMedievalPregenMethod(world, 16)); } catch (NumberFormatException e) { From 90d2cf497027773a7cabc93cc7f70df51e50d61f Mon Sep 17 00:00:00 2001 From: Daniel Mills Date: Mon, 19 Jul 2021 05:41:10 -0400 Subject: [PATCH 17/27] Pregen job tweaks --- .../java/com/volmit/iris/core/gui/PregeneratorJob.java | 9 +++------ 1 file changed, 3 insertions(+), 6 deletions(-) diff --git a/src/main/java/com/volmit/iris/core/gui/PregeneratorJob.java b/src/main/java/com/volmit/iris/core/gui/PregeneratorJob.java index f491f76fe..c86cf8633 100644 --- a/src/main/java/com/volmit/iris/core/gui/PregeneratorJob.java +++ b/src/main/java/com/volmit/iris/core/gui/PregeneratorJob.java @@ -18,15 +18,12 @@ package com.volmit.iris.core.gui; -import com.sk89q.worldedit.function.factory.ApplyRegion; import com.volmit.iris.Iris; import com.volmit.iris.core.IrisSettings; -import com.volmit.iris.core.gui.components.Pregenerator; import com.volmit.iris.core.pregenerator.IrisPregenerator; import com.volmit.iris.core.pregenerator.PregenListener; import com.volmit.iris.core.pregenerator.PregenTask; import com.volmit.iris.core.pregenerator.PregeneratorMethod; -import com.volmit.iris.engine.object.IrisBiomeCustom; import com.volmit.iris.util.collection.KList; import com.volmit.iris.util.format.Form; import com.volmit.iris.util.function.Consumer2; @@ -215,11 +212,11 @@ public class PregeneratorJob implements PregenListener { @Override public void onSaving() { - saving = true; + } private Position2 getMax() { - return task.getCenter().add(task.getRadius(), task.getRadius()).bottomRightChunkOfRegion(); + return task.getCenter().add(task.getRadius(), task.getRadius()).topLeftChunkOfRegion(); } private Position2 getMin() { @@ -318,7 +315,7 @@ public class PregeneratorJob implements PregenListener { @Override public void keyReleased(KeyEvent e) { if (e.getKeyCode() == KeyEvent.VK_P) { - Pregenerator.pauseResume(); + PregeneratorJob.pauseResume(); } } From 756f395158e133852853b5e472af2eed183db2e9 Mon Sep 17 00:00:00 2001 From: Daniel Mills Date: Mon, 19 Jul 2021 05:41:19 -0400 Subject: [PATCH 18/27] Method api & impl changes --- .../core/pregenerator/PregeneratorMethod.java | 3 +- .../methods/DummyPregenMethod.java | 2 +- .../methods/HeadlessPregenMethod.java | 2 +- .../methods/HybridPregenMethod.java | 4 +-- .../methods/MedievalPregenMethod.java | 36 ++++++++++++++++--- .../methods/PaperAsyncPregenMethod.java | 16 ++++++--- .../methods/PaperOrMedievalPregenMethod.java | 4 +-- 7 files changed, 51 insertions(+), 16 deletions(-) diff --git a/src/main/java/com/volmit/iris/core/pregenerator/PregeneratorMethod.java b/src/main/java/com/volmit/iris/core/pregenerator/PregeneratorMethod.java index 9bad0e05a..a5c698ba8 100644 --- a/src/main/java/com/volmit/iris/core/pregenerator/PregeneratorMethod.java +++ b/src/main/java/com/volmit/iris/core/pregenerator/PregeneratorMethod.java @@ -67,6 +67,7 @@ public interface PregeneratorMethod { * Called to generate a chunk. You can go async so long as save will wait on the threads to finish * @param x the x * @param z the z + * @param listener */ - void generateChunk(int x, int z); + void generateChunk(int x, int z, PregenListener listener); } diff --git a/src/main/java/com/volmit/iris/core/pregenerator/methods/DummyPregenMethod.java b/src/main/java/com/volmit/iris/core/pregenerator/methods/DummyPregenMethod.java index 08c108431..0147a0441 100644 --- a/src/main/java/com/volmit/iris/core/pregenerator/methods/DummyPregenMethod.java +++ b/src/main/java/com/volmit/iris/core/pregenerator/methods/DummyPregenMethod.java @@ -53,7 +53,7 @@ public class DummyPregenMethod implements PregeneratorMethod { } @Override - public void generateChunk(int x, int z) { + public void generateChunk(int x, int z, PregenListener listener) { } } diff --git a/src/main/java/com/volmit/iris/core/pregenerator/methods/HeadlessPregenMethod.java b/src/main/java/com/volmit/iris/core/pregenerator/methods/HeadlessPregenMethod.java index c42155da0..bac3fe69c 100644 --- a/src/main/java/com/volmit/iris/core/pregenerator/methods/HeadlessPregenMethod.java +++ b/src/main/java/com/volmit/iris/core/pregenerator/methods/HeadlessPregenMethod.java @@ -64,7 +64,7 @@ public class HeadlessPregenMethod implements PregeneratorMethod { } @Override - public void generateChunk(int x, int z) { + public void generateChunk(int x, int z, PregenListener listener) { throw new UnsupportedOperationException(); } } diff --git a/src/main/java/com/volmit/iris/core/pregenerator/methods/HybridPregenMethod.java b/src/main/java/com/volmit/iris/core/pregenerator/methods/HybridPregenMethod.java index b6efb1c25..a50538405 100644 --- a/src/main/java/com/volmit/iris/core/pregenerator/methods/HybridPregenMethod.java +++ b/src/main/java/com/volmit/iris/core/pregenerator/methods/HybridPregenMethod.java @@ -81,7 +81,7 @@ public class HybridPregenMethod implements PregeneratorMethod { } @Override - public void generateChunk(int x, int z) { - inWorld.generateChunk(x, z); + public void generateChunk(int x, int z, PregenListener listener) { + inWorld.generateChunk(x, z, listener); } } diff --git a/src/main/java/com/volmit/iris/core/pregenerator/methods/MedievalPregenMethod.java b/src/main/java/com/volmit/iris/core/pregenerator/methods/MedievalPregenMethod.java index 51ec8086c..49d2ed28a 100644 --- a/src/main/java/com/volmit/iris/core/pregenerator/methods/MedievalPregenMethod.java +++ b/src/main/java/com/volmit/iris/core/pregenerator/methods/MedievalPregenMethod.java @@ -20,24 +20,45 @@ package com.volmit.iris.core.pregenerator.methods; import com.volmit.iris.core.pregenerator.PregenListener; import com.volmit.iris.core.pregenerator.PregeneratorMethod; +import com.volmit.iris.util.collection.KList; import com.volmit.iris.util.scheduling.J; import org.bukkit.Chunk; import org.bukkit.World; +import java.util.concurrent.CompletableFuture; + public class MedievalPregenMethod implements PregeneratorMethod { private final World world; + private final KList> futures; public MedievalPregenMethod(World world) { this.world = world; + futures = new KList<>(); + } + + private void waitForChunks() + { + for(CompletableFuture i : futures) + { + try { + i.get(); + } catch (Throwable e) { + e.printStackTrace(); + } + } + + futures.clear(); } private void unloadAndSaveAllChunks() { + waitForChunks(); J.s(() -> { for(Chunk i : world.getLoadedChunks()) { i.unload(true); } + world.save(); }); } @@ -49,13 +70,11 @@ public class MedievalPregenMethod implements PregeneratorMethod { @Override public void close() { unloadAndSaveAllChunks(); - world.save(); } @Override public void save() { unloadAndSaveAllChunks(); - world.save(); } @Override @@ -74,7 +93,16 @@ public class MedievalPregenMethod implements PregeneratorMethod { } @Override - public void generateChunk(int x, int z) { - world.getChunkAt(x, z); + public void generateChunk(int x, int z, PregenListener listener) { + if(futures.size() > 32) + { + waitForChunks(); + } + + listener.onChunkGenerating(x, z); + futures.add(J.sfut(() -> { + world.getChunkAt(x, z); + listener.onChunkGenerated(x, z); + })); } } diff --git a/src/main/java/com/volmit/iris/core/pregenerator/methods/PaperAsyncPregenMethod.java b/src/main/java/com/volmit/iris/core/pregenerator/methods/PaperAsyncPregenMethod.java index f38046a23..7bb41c3c1 100644 --- a/src/main/java/com/volmit/iris/core/pregenerator/methods/PaperAsyncPregenMethod.java +++ b/src/main/java/com/volmit/iris/core/pregenerator/methods/PaperAsyncPregenMethod.java @@ -52,12 +52,14 @@ public class PaperAsyncPregenMethod implements PregeneratorMethod { { i.unload(true); } + world.save(); }); } - private void completeChunk(int x, int z) { + private void completeChunk(int x, int z, PregenListener listener) { try { PaperLib.getChunkAtAsync(world, x, z, true).get(); + listener.onChunkGenerated(x, z); } catch (Throwable e) { e.printStackTrace(); } @@ -92,14 +94,12 @@ public class PaperAsyncPregenMethod implements PregeneratorMethod { waitForChunks(); burst.shutdownAndAwait(); unloadAndSaveAllChunks(); - world.save(); } @Override public void save() { waitForChunks(); unloadAndSaveAllChunks(); - world.save(); } @Override @@ -113,7 +113,13 @@ public class PaperAsyncPregenMethod implements PregeneratorMethod { } @Override - public void generateChunk(int x, int z) { - future.add(burst.complete(() -> completeChunk(x, z))); + public void generateChunk(int x, int z, PregenListener listener) { + if(future.size() > 32) + { + waitForChunks(); + } + + listener.onChunkGenerating(x, z); + future.add(burst.complete(() -> completeChunk(x, z, listener))); } } diff --git a/src/main/java/com/volmit/iris/core/pregenerator/methods/PaperOrMedievalPregenMethod.java b/src/main/java/com/volmit/iris/core/pregenerator/methods/PaperOrMedievalPregenMethod.java index 4608b68e6..6df75a9b7 100644 --- a/src/main/java/com/volmit/iris/core/pregenerator/methods/PaperOrMedievalPregenMethod.java +++ b/src/main/java/com/volmit/iris/core/pregenerator/methods/PaperOrMedievalPregenMethod.java @@ -62,7 +62,7 @@ public class PaperOrMedievalPregenMethod implements PregeneratorMethod { } @Override - public void generateChunk(int x, int z) { - method.generateChunk(x, z); + public void generateChunk(int x, int z, PregenListener listener) { + method.generateChunk(x, z, listener); } } From 1726d6f59e22b6384fd9182ec285cb4d28ea61be Mon Sep 17 00:00:00 2001 From: Daniel Mills Date: Mon, 19 Jul 2021 05:41:30 -0400 Subject: [PATCH 19/27] Iterator event fixes --- .../iris/core/pregenerator/IrisPregenerator.java | 10 +--------- 1 file changed, 1 insertion(+), 9 deletions(-) diff --git a/src/main/java/com/volmit/iris/core/pregenerator/IrisPregenerator.java b/src/main/java/com/volmit/iris/core/pregenerator/IrisPregenerator.java index c1cedf84c..fec274f1e 100644 --- a/src/main/java/com/volmit/iris/core/pregenerator/IrisPregenerator.java +++ b/src/main/java/com/volmit/iris/core/pregenerator/IrisPregenerator.java @@ -18,11 +18,7 @@ package com.volmit.iris.core.pregenerator; -import com.google.common.util.concurrent.AtomicDouble; -import com.volmit.iris.util.collection.KList; -import com.volmit.iris.util.collection.KSet; import com.volmit.iris.util.math.M; -import com.volmit.iris.util.math.Position2; import com.volmit.iris.util.math.RollingSequence; import com.volmit.iris.util.scheduling.ChronoLatch; import com.volmit.iris.util.scheduling.J; @@ -147,11 +143,7 @@ public class IrisPregenerator { else { - task.iterateRegion(x, z, (xx, zz) -> { - listener.onChunkGenerating(xx, zz); - generator.generateChunk(xx, zz); - listener.onChunkGenerated(xx, zz); - }); + task.iterateRegion(x, z, (xx, zz) -> generator.generateChunk(xx, zz, listener)); } listener.onRegionGenerated(x, z); From e19ae7af59c020718895a47193d3716b9ec6d3f5 Mon Sep 17 00:00:00 2001 From: Daniel Mills Date: Mon, 19 Jul 2021 05:43:46 -0400 Subject: [PATCH 20/27] Math fixes --- .../volmit/iris/core/gui/PregeneratorJob.java | 4 ++-- .../com/volmit/iris/util/math/Position2.java | 19 ++----------------- 2 files changed, 4 insertions(+), 19 deletions(-) diff --git a/src/main/java/com/volmit/iris/core/gui/PregeneratorJob.java b/src/main/java/com/volmit/iris/core/gui/PregeneratorJob.java index c86cf8633..5a0eb6da7 100644 --- a/src/main/java/com/volmit/iris/core/gui/PregeneratorJob.java +++ b/src/main/java/com/volmit/iris/core/gui/PregeneratorJob.java @@ -216,11 +216,11 @@ public class PregeneratorJob implements PregenListener { } private Position2 getMax() { - return task.getCenter().add(task.getRadius(), task.getRadius()).topLeftChunkOfRegion(); + return task.getCenter().add(task.getRadius(), task.getRadius()).regionToChunk(); } private Position2 getMin() { - return task.getCenter().add(-task.getRadius(), -task.getRadius()).topLeftChunkOfRegion(); + return task.getCenter().add(-task.getRadius(), -task.getRadius()).regionToChunk(); } private boolean paused() { diff --git a/src/main/java/com/volmit/iris/util/math/Position2.java b/src/main/java/com/volmit/iris/util/math/Position2.java index 2acd4148f..93b17a101 100644 --- a/src/main/java/com/volmit/iris/util/math/Position2.java +++ b/src/main/java/com/volmit/iris/util/math/Position2.java @@ -57,24 +57,9 @@ public class Position2 { return result; } - public Position2 topLeftChunkOfRegion() + public Position2 regionToChunk() { - return new Position2((x >> 5) << 5, (z >> 5) << 5); - } - - public Position2 bottomRightChunkOfRegion() - { - return new Position2((((x >> 5)+1) << 5) - 1, (((z >> 5)+1) << 5) - 1); - } - - public Position2 topRightChunkOfRegion() - { - return new Position2((((x >> 5)+1) << 5) - 1, (z >> 5) << 5); - } - - public Position2 bottomLeftChunkOfRegion() - { - return new Position2((x >> 5) << 5, (((z >> 5)+1) << 5) - 1); + return new Position2(x << 5, z << 5); } @Override From f9a815bba63d72c5918f5252e3c56de277790093 Mon Sep 17 00:00:00 2001 From: Daniel Mills Date: Mon, 19 Jul 2021 06:31:57 -0400 Subject: [PATCH 21/27] Dont try to load mca regions --- .../java/com/volmit/iris/engine/data/mca/NBTWorld.java | 10 +--------- 1 file changed, 1 insertion(+), 9 deletions(-) diff --git a/src/main/java/com/volmit/iris/engine/data/mca/NBTWorld.java b/src/main/java/com/volmit/iris/engine/data/mca/NBTWorld.java index 3801412a5..22ed2935d 100644 --- a/src/main/java/com/volmit/iris/engine/data/mca/NBTWorld.java +++ b/src/main/java/com/volmit/iris/engine/data/mca/NBTWorld.java @@ -313,15 +313,7 @@ public class NBTWorld { if(mcaf == null) { - File f = getRegionFile(x, z); - try { - mcaf = f.exists() ? MCAUtil.read(f) : new MCAFile(x, z); - } catch (IOException e) { - Iris.error("Failed to properly read MCA File " + f.getPath() + " Using a blank one."); - e.printStackTrace(); - mcaf = new MCAFile(x, z); - } - + mcaf = new MCAFile(x, z); regionLock.lock(); loadedRegions.put(key, mcaf); regionLock.unlock(); From 280ec22348b897464031d53d002f10ad57a399f1 Mon Sep 17 00:00:00 2001 From: Daniel Mills Date: Mon, 19 Jul 2021 06:32:13 -0400 Subject: [PATCH 22/27] Better mca iteration --- .../framework/EngineCompositeGenerator.java | 29 +++++++------------ 1 file changed, 11 insertions(+), 18 deletions(-) diff --git a/src/main/java/com/volmit/iris/engine/framework/EngineCompositeGenerator.java b/src/main/java/com/volmit/iris/engine/framework/EngineCompositeGenerator.java index bf3067f66..145c10abc 100644 --- a/src/main/java/com/volmit/iris/engine/framework/EngineCompositeGenerator.java +++ b/src/main/java/com/volmit/iris/engine/framework/EngineCompositeGenerator.java @@ -24,6 +24,7 @@ import com.volmit.iris.core.IrisSettings; import com.volmit.iris.core.nms.BiomeBaseInjector; import com.volmit.iris.core.nms.INMS; import com.volmit.iris.core.pregenerator.PregenListener; +import com.volmit.iris.core.pregenerator.PregenTask; import com.volmit.iris.engine.IrisEngineCompound; import com.volmit.iris.engine.IrisWorlds; import com.volmit.iris.engine.cache.Cache; @@ -467,26 +468,18 @@ public class EngineCompositeGenerator extends ChunkGenerator implements IrisAcce @Override public void directWriteMCA(IrisWorld w, int x, int z, NBTWorld writer, MultiBurst burst, PregenListener l) { BurstExecutor e = burst.burst(1024); - int mcaox = x << 5; - int mcaoz = z << 5; - for (int i = 0; i < 32; i++) { - int ii = i; - for (int j = 0; j < 32; j++) { - int jj = j; - e.queue(() -> { - if(l != null) - { - l.onChunkGenerating(ii + mcaox, jj + mcaoz); - } - directWriteChunk(w, ii + mcaox, jj + mcaoz, writer); - if(l != null) - { - l.onChunkGenerated(ii + mcaox, jj + mcaoz); - } - }); + PregenTask.iterateRegion(x, z, (ii, jj) -> e.queue(() -> { + if(l != null) + { + l.onChunkGenerating(ii, jj); } - } + directWriteChunk(w, ii, jj, writer); + if(l != null) + { + l.onChunkGenerated(ii, jj); + } + })); e.complete(); } From be2cb5d2f271c57021f490ceb41aefc6e33f1a60 Mon Sep 17 00:00:00 2001 From: Daniel Mills Date: Mon, 19 Jul 2021 06:32:20 -0400 Subject: [PATCH 23/27] Fix pregen thread counts --- .../volmit/iris/core/command/world/CommandIrisPregen.java | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/main/java/com/volmit/iris/core/command/world/CommandIrisPregen.java b/src/main/java/com/volmit/iris/core/command/world/CommandIrisPregen.java index 422150803..74837c9cb 100644 --- a/src/main/java/com/volmit/iris/core/command/world/CommandIrisPregen.java +++ b/src/main/java/com/volmit/iris/core/command/world/CommandIrisPregen.java @@ -22,6 +22,7 @@ import com.volmit.iris.Iris; import com.volmit.iris.core.gui.PregeneratorJob; import com.volmit.iris.core.gui.components.Pregenerator; import com.volmit.iris.core.pregenerator.PregenTask; +import com.volmit.iris.core.pregenerator.methods.HybridPregenMethod; import com.volmit.iris.core.pregenerator.methods.PaperOrMedievalPregenMethod; import com.volmit.iris.util.collection.KList; import com.volmit.iris.util.math.Position2; @@ -114,7 +115,7 @@ public class CommandIrisPregen extends MortarCommand { .center(new Position2(0, 0)) .radius(((getVal(args[0])>>4)>>5) + 1) .build(), - new PaperOrMedievalPregenMethod(world, 16)); + new HybridPregenMethod(world, Runtime.getRuntime().availableProcessors())); } catch (NumberFormatException e) { Iris.reportError(e); sender.sendMessage("Invalid argument in command"); @@ -145,7 +146,7 @@ public class CommandIrisPregen extends MortarCommand { .center(new Position2(0, 0)) .radius(((getVal(args[0])>>4)>>5) + 1) .build(), - new PaperOrMedievalPregenMethod(world, 16)); + new HybridPregenMethod(world, Runtime.getRuntime().availableProcessors())); } catch (NumberFormatException e) { Iris.reportError(e); sender.sendMessage("Invalid argument in command"); From 0a591e748f8f6b63d23a7cd5b02c371d6f6b4eeb Mon Sep 17 00:00:00 2001 From: Daniel Mills Date: Mon, 19 Jul 2021 06:32:27 -0400 Subject: [PATCH 24/27] Fix rendering issues --- .../volmit/iris/core/gui/PregeneratorJob.java | 17 +++++++++++++++-- 1 file changed, 15 insertions(+), 2 deletions(-) diff --git a/src/main/java/com/volmit/iris/core/gui/PregeneratorJob.java b/src/main/java/com/volmit/iris/core/gui/PregeneratorJob.java index 5a0eb6da7..d4bf7c490 100644 --- a/src/main/java/com/volmit/iris/core/gui/PregeneratorJob.java +++ b/src/main/java/com/volmit/iris/core/gui/PregeneratorJob.java @@ -29,6 +29,7 @@ import com.volmit.iris.util.format.Form; import com.volmit.iris.util.function.Consumer2; import com.volmit.iris.util.math.M; import com.volmit.iris.util.math.Position2; +import com.volmit.iris.util.math.Spiraler; import com.volmit.iris.util.scheduling.J; import javax.swing.*; @@ -48,6 +49,8 @@ public class PregeneratorJob implements PregenListener { private final IrisPregenerator pregenerator; private PregenRenderer renderer; private String[] info; + private Position2 min; + private Position2 max; public PregeneratorJob(PregenTask task, PregeneratorMethod method) { @@ -57,6 +60,15 @@ public class PregeneratorJob implements PregenListener { this.task = task; this.pregenerator = new IrisPregenerator(task, method, this); J.a(this.pregenerator::start); + max = new Position2(0, 0); + min = new Position2(0, 0); + KList draw = new KList<>(); + task.iterateRegions((xx,zz) -> { + min.setX(Math.min(xx << 5, min.getX())); + min.setZ(Math.min(zz << 5, min.getZ())); + max.setX(Math.max((xx << 5) + 31, max.getX())); + max.setZ(Math.max((zz << 5) + 31, max.getZ())); + }); open(); } @@ -130,6 +142,7 @@ public class PregeneratorJob implements PregenListener { J.a(() -> { try { + J.sleep(3000); frame.setVisible(false); } @@ -216,11 +229,11 @@ public class PregeneratorJob implements PregenListener { } private Position2 getMax() { - return task.getCenter().add(task.getRadius(), task.getRadius()).regionToChunk(); + return max; } private Position2 getMin() { - return task.getCenter().add(-task.getRadius(), -task.getRadius()).regionToChunk(); + return min; } private boolean paused() { From 6d117f824d02a36b5edf272a4efff88a616b244b Mon Sep 17 00:00:00 2001 From: Daniel Mills Date: Mon, 19 Jul 2021 06:32:38 -0400 Subject: [PATCH 25/27] Fix threading & other issues --- .../iris/core/pregenerator/methods/HybridPregenMethod.java | 2 +- .../iris/core/pregenerator/methods/PaperAsyncPregenMethod.java | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/main/java/com/volmit/iris/core/pregenerator/methods/HybridPregenMethod.java b/src/main/java/com/volmit/iris/core/pregenerator/methods/HybridPregenMethod.java index a50538405..ec274d168 100644 --- a/src/main/java/com/volmit/iris/core/pregenerator/methods/HybridPregenMethod.java +++ b/src/main/java/com/volmit/iris/core/pregenerator/methods/HybridPregenMethod.java @@ -72,7 +72,7 @@ public class HybridPregenMethod implements PregeneratorMethod { return false; } - return !new File(world.getWorldFolder(), "region/r." + x + "." + z + ".mca").exists(); + return new File(world.getWorldFolder(), "region/r." + x + "." + z + ".mca").exists(); } @Override diff --git a/src/main/java/com/volmit/iris/core/pregenerator/methods/PaperAsyncPregenMethod.java b/src/main/java/com/volmit/iris/core/pregenerator/methods/PaperAsyncPregenMethod.java index 7bb41c3c1..51eeb9ac4 100644 --- a/src/main/java/com/volmit/iris/core/pregenerator/methods/PaperAsyncPregenMethod.java +++ b/src/main/java/com/volmit/iris/core/pregenerator/methods/PaperAsyncPregenMethod.java @@ -114,7 +114,7 @@ public class PaperAsyncPregenMethod implements PregeneratorMethod { @Override public void generateChunk(int x, int z, PregenListener listener) { - if(future.size() > 32) + if(future.size() > 128) { waitForChunks(); } From aa510489902acc05bc867c88ad474d18996cfd2f Mon Sep 17 00:00:00 2001 From: Daniel Mills Date: Mon, 19 Jul 2021 06:32:44 -0400 Subject: [PATCH 26/27] Fixes --- .../core/pregenerator/IrisPregenerator.java | 2 +- .../iris/core/pregenerator/PregenTask.java | 32 +++++++++++++++---- 2 files changed, 27 insertions(+), 7 deletions(-) diff --git a/src/main/java/com/volmit/iris/core/pregenerator/IrisPregenerator.java b/src/main/java/com/volmit/iris/core/pregenerator/IrisPregenerator.java index fec274f1e..edded7f24 100644 --- a/src/main/java/com/volmit/iris/core/pregenerator/IrisPregenerator.java +++ b/src/main/java/com/volmit/iris/core/pregenerator/IrisPregenerator.java @@ -143,7 +143,7 @@ public class IrisPregenerator { else { - task.iterateRegion(x, z, (xx, zz) -> generator.generateChunk(xx, zz, listener)); + PregenTask.iterateRegion(x, z, (xx, zz) -> generator.generateChunk(xx, zz, listener)); } listener.onRegionGenerated(x, z); diff --git a/src/main/java/com/volmit/iris/core/pregenerator/PregenTask.java b/src/main/java/com/volmit/iris/core/pregenerator/PregenTask.java index ca3b26bf1..007b3a49b 100644 --- a/src/main/java/com/volmit/iris/core/pregenerator/PregenTask.java +++ b/src/main/java/com/volmit/iris/core/pregenerator/PregenTask.java @@ -18,12 +18,15 @@ package com.volmit.iris.core.pregenerator; +import com.volmit.iris.util.collection.KList; import com.volmit.iris.util.math.Position2; import com.volmit.iris.util.math.Spiraled; import com.volmit.iris.util.math.Spiraler; import lombok.Builder; import lombok.Data; +import java.util.Comparator; + @Builder @Data public class PregenTask { @@ -33,19 +36,20 @@ public class PregenTask { @Builder.Default private int radius = 1; + private static final KList order = computeChunkOrder(); + public void iterateRegions(Spiraled s) { new Spiraler(radius * 2, radius * 2, s) .setOffset(center.getX(), center.getZ()).drain(); } - public void iterateRegion(int x, int z, Spiraled s) + public static void iterateRegion(int xr, int zr, Spiraled s) { - new Spiraler(33, 33, (xx, zz) -> { - if (xx < 0 || xx > 31 || zz < 0 || zz > 31) { - s.on(xx+(x<<5), zz+(z<<5)); - } - }).setOffset(15, 15).drain(); + for(Position2 i : order) + { + s.on(i.getX() + (xr << 5), i.getZ() + (zr << 5)); + } } public void iterateAllChunks(Spiraled s) @@ -53,4 +57,20 @@ public class PregenTask { new Spiraler(radius * 2, radius * 2, (x, z) -> iterateRegion(x, z, s)) .setOffset(center.getX(), center.getZ()).drain(); } + + private static KList computeChunkOrder() { + Position2 center = new Position2(15, 15); + KList p = new KList<>(); + new Spiraler(33, 33, (x, z) -> { + int xx = x + 15; + int zz = z + 15; + if (xx < 0 || xx > 31 || zz < 0 || zz > 31) { + return; + } + + p.add(new Position2(xx, zz)); + }).drain(); + p.sort(Comparator.comparing((i) -> i.distance(center))); + return p; + } } From 5bf75e122c309a8cab047b00fe3de1ed473257fa Mon Sep 17 00:00:00 2001 From: Daniel Mills Date: Mon, 19 Jul 2021 06:40:54 -0400 Subject: [PATCH 27/27] Tweaks --- .../com/volmit/iris/core/pregenerator/IrisPregenerator.java | 2 +- .../iris/core/pregenerator/methods/HybridPregenMethod.java | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/main/java/com/volmit/iris/core/pregenerator/IrisPregenerator.java b/src/main/java/com/volmit/iris/core/pregenerator/IrisPregenerator.java index edded7f24..16a2052b9 100644 --- a/src/main/java/com/volmit/iris/core/pregenerator/IrisPregenerator.java +++ b/src/main/java/com/volmit/iris/core/pregenerator/IrisPregenerator.java @@ -63,6 +63,7 @@ public class IrisPregenerator { generatedLast = new AtomicInteger(0); generatedLastMinute = new AtomicInteger(0); totalChunks = new AtomicInteger(0); + task.iterateRegions((_a, _b) -> totalChunks.addAndGet(1024)); startTime = new AtomicLong(M.ms()); ticker = new Looper() { @Override @@ -104,7 +105,6 @@ public class IrisPregenerator { public void start() { init(); - task.iterateRegions((__, ___) -> totalChunks.addAndGet(1024)); ticker.start(); task.iterateRegions(this::visitRegion); shutdown(); diff --git a/src/main/java/com/volmit/iris/core/pregenerator/methods/HybridPregenMethod.java b/src/main/java/com/volmit/iris/core/pregenerator/methods/HybridPregenMethod.java index ec274d168..a50538405 100644 --- a/src/main/java/com/volmit/iris/core/pregenerator/methods/HybridPregenMethod.java +++ b/src/main/java/com/volmit/iris/core/pregenerator/methods/HybridPregenMethod.java @@ -72,7 +72,7 @@ public class HybridPregenMethod implements PregeneratorMethod { return false; } - return new File(world.getWorldFolder(), "region/r." + x + "." + z + ".mca").exists(); + return !new File(world.getWorldFolder(), "region/r." + x + "." + z + ".mca").exists(); } @Override