From 4902e5b9bb36eb5ed10b6d537122b468403978e2 Mon Sep 17 00:00:00 2001 From: Daniel Mills Date: Fri, 4 Dec 2020 05:07:44 -0500 Subject: [PATCH] Fixes & Fixes --- .../java/com/volmit/iris/IrisSettings.java | 3 + .../com/volmit/iris/generator/IrisEngine.java | 53 ++++--- .../iris/generator/IrisEngineCompound.java | 11 ++ .../nms/v16_2/NMSChunkGenerator_16_2.java | 9 +- .../iris/nms/v16_3/NMSChunkGenerator16_3.java | 9 +- .../com/volmit/iris/scaffold/IrisWorlds.java | 5 +- .../volmit/iris/scaffold/engine/Engine.java | 9 +- .../engine/EngineCompositeGenerator.java | 68 ++++++++- .../iris/scaffold/engine/EngineCompound.java | 7 + .../iris/scaffold/engine/EngineFramework.java | 16 +- .../iris/scaffold/engine/IrisAccess.java | 8 + .../scaffold/engine/IrisAccessProvider.java | 5 + .../scaffold/engine/PregeneratedData.java | 50 +++++++ .../com/volmit/iris/scaffold/hunk/Hunk.java | 8 +- .../scaffold/hunk/view/WriteTrackHunk.java | 57 ++++++++ .../com/volmit/iris/util/AtomicAverage.java | 32 ++-- .../java/com/volmit/iris/util/PregenJob.java | 137 +++++++++++++----- 17 files changed, 402 insertions(+), 85 deletions(-) create mode 100644 src/main/java/com/volmit/iris/scaffold/engine/IrisAccessProvider.java create mode 100644 src/main/java/com/volmit/iris/scaffold/engine/PregeneratedData.java create mode 100644 src/main/java/com/volmit/iris/scaffold/hunk/view/WriteTrackHunk.java diff --git a/src/main/java/com/volmit/iris/IrisSettings.java b/src/main/java/com/volmit/iris/IrisSettings.java index 12d056d3b..a977348bb 100644 --- a/src/main/java/com/volmit/iris/IrisSettings.java +++ b/src/main/java/com/volmit/iris/IrisSettings.java @@ -48,6 +48,9 @@ public class IrisSettings @DontObfuscate public boolean ignoreWorldEdit = false; + @DontObfuscate + public boolean useGleamPregenerator = false; + @DontObfuscate public boolean disableNMS = false; diff --git a/src/main/java/com/volmit/iris/generator/IrisEngine.java b/src/main/java/com/volmit/iris/generator/IrisEngine.java index a436876d1..dcb0195e3 100644 --- a/src/main/java/com/volmit/iris/generator/IrisEngine.java +++ b/src/main/java/com/volmit/iris/generator/IrisEngine.java @@ -4,6 +4,7 @@ import com.volmit.iris.Iris; import com.volmit.iris.scaffold.engine.*; import com.volmit.iris.scaffold.hunk.Hunk; import com.volmit.iris.scaffold.parallel.MultiBurst; +import com.volmit.iris.util.ChronoLatch; import com.volmit.iris.util.J; import com.volmit.iris.util.PrecisionStopwatch; import com.volmit.iris.util.RNG; @@ -17,6 +18,7 @@ import org.bukkit.generator.BlockPopulator; import org.jetbrains.annotations.NotNull; import java.util.Random; +import java.util.concurrent.Semaphore; public class IrisEngine extends BlockPopulator implements Engine { @@ -48,15 +50,20 @@ public class IrisEngine extends BlockPopulator implements Engine @Setter @Getter private volatile int minHeight; + private int permits; private boolean failing; + private ChronoLatch cl = new ChronoLatch(10000); private boolean closed; private int cacheId; + private Semaphore s; private int art; public IrisEngine(EngineTarget target, EngineCompound compound, int index) { Iris.info("Initializing Engine: " + target.getWorld().getName() + "/" + target.getDimension().getLoadKey() + " (" + target.getHeight() + " height)"); metrics = new EngineMetrics(32); + permits = 1000; + this.s = new Semaphore(permits); this.target = target; this.framework = new IrisEngineFramework(this); worldManager = new IrisWorldManager(this); @@ -79,6 +86,11 @@ public class IrisEngine extends BlockPopulator implements Engine getFramework().close(); } + @Override + public int getCurrentlyGenerating() { + return permits - s.availablePermits(); + } + @Override public boolean isClosed() { return closed; @@ -98,31 +110,38 @@ public class IrisEngine extends BlockPopulator implements Engine public void generate(int x, int z, Hunk vblocks, Hunk postblocks, Hunk vbiomes) { try { + s.acquire(1); PrecisionStopwatch p = PrecisionStopwatch.start(); Hunk biomes = vbiomes; Hunk blocks = vblocks.synchronize().listen((xx,y,zz,t) -> catchBlockUpdates(x+xx,y+getMinHeight(),z+zz, t)); Hunk pblocks = postblocks.synchronize().listen((xx,y,zz,t) -> catchBlockUpdates(x+xx,y+getMinHeight(),z+zz, t)); Hunk fringe = Hunk.fringe(blocks, pblocks); - - MultiBurst.burst.burst( - () -> getFramework().getEngineParallax().generateParallaxArea(x, z), - () -> getFramework().getBiomeActuator().actuate(x, z, biomes), - () -> getFramework().getTerrainActuator().actuate(x, z, blocks) - ); - MultiBurst.burst.burst( - () -> getFramework().getCaveModifier().modify(x, z, blocks), - () -> getFramework().getRavineModifier().modify(x, z, blocks) - ); - MultiBurst.burst.burst( - () -> getFramework().getDepositModifier().modify(x, z, blocks), - () -> getFramework().getPostModifier().modify(x, z, blocks), - () -> getFramework().getDecorantActuator().actuate(x, z, fringe) - ); - + getFramework().getEngineParallax().generateParallaxArea(x, z); + getFramework().getBiomeActuator().actuate(x, z, biomes); + getFramework().getTerrainActuator().actuate(x, z, blocks); + getFramework().getCaveModifier().modify(x, z, blocks); + getFramework().getRavineModifier().modify(x, z, blocks); + getFramework().getDepositModifier().modify(x, z, blocks); + getFramework().getPostModifier().modify(x, z, blocks); + getFramework().getDecorantActuator().actuate(x, z, fringe); getFramework().getEngineParallax().insertParallax(x, z, fringe); - getFramework().recycle(); getMetrics().getTotal().put(p.getMilliseconds()); + s.release(1); + + if(cl.flip()) + { + MultiBurst.burst.lazy(() -> { + try { + s.acquire(permits); + getFramework().recycle(); + s.release(permits); + } catch (InterruptedException e) { + e.printStackTrace(); + } + }); + } } + catch(Throwable e) { fail("Failed to generate " + x + ", " + z, e); diff --git a/src/main/java/com/volmit/iris/generator/IrisEngineCompound.java b/src/main/java/com/volmit/iris/generator/IrisEngineCompound.java index 183474865..d1dcf6c25 100644 --- a/src/main/java/com/volmit/iris/generator/IrisEngineCompound.java +++ b/src/main/java/com/volmit/iris/generator/IrisEngineCompound.java @@ -260,6 +260,17 @@ public class IrisEngineCompound implements EngineCompound { wallClock.put(p.getMilliseconds()); } + @Override + public int getCurrentlyGeneratingEngines() { + int v = 0; + for(Engine i : engines) + { + v+= i.getCurrentlyGenerating(); + } + + return v; + } + @Override public int getSize() { return engines.length; diff --git a/src/main/java/com/volmit/iris/nms/v16_2/NMSChunkGenerator_16_2.java b/src/main/java/com/volmit/iris/nms/v16_2/NMSChunkGenerator_16_2.java index ca42033fe..b2a11c2f7 100644 --- a/src/main/java/com/volmit/iris/nms/v16_2/NMSChunkGenerator_16_2.java +++ b/src/main/java/com/volmit/iris/nms/v16_2/NMSChunkGenerator_16_2.java @@ -10,6 +10,8 @@ import com.volmit.iris.Iris; import com.volmit.iris.nms.INMS; import com.volmit.iris.scaffold.cache.Cache; import com.volmit.iris.scaffold.engine.EngineCompositeGenerator; +import com.volmit.iris.scaffold.engine.IrisAccess; +import com.volmit.iris.scaffold.engine.IrisAccessProvider; import com.volmit.iris.util.*; import net.minecraft.server.v1_16_R2.BlockPosition; import net.minecraft.server.v1_16_R2.HeightMap; @@ -26,7 +28,7 @@ import java.util.*; import java.util.concurrent.atomic.AtomicBoolean; import java.util.function.Supplier; -public final class NMSChunkGenerator_16_2 extends ChunkGenerator { +public final class NMSChunkGenerator_16_2 extends ChunkGenerator implements IrisAccessProvider { private static final IBlockData k; private final O ws; protected final IBlockData f; @@ -595,4 +597,9 @@ public final class NMSChunkGenerator_16_2 extends ChunkGenerator { ++i1; } } + + @Override + public IrisAccess getAccess() { + return gen; + } } diff --git a/src/main/java/com/volmit/iris/nms/v16_3/NMSChunkGenerator16_3.java b/src/main/java/com/volmit/iris/nms/v16_3/NMSChunkGenerator16_3.java index a944b6bcf..a5e3ab033 100644 --- a/src/main/java/com/volmit/iris/nms/v16_3/NMSChunkGenerator16_3.java +++ b/src/main/java/com/volmit/iris/nms/v16_3/NMSChunkGenerator16_3.java @@ -10,6 +10,8 @@ import com.volmit.iris.Iris; import com.volmit.iris.nms.INMS; import com.volmit.iris.scaffold.cache.Cache; import com.volmit.iris.scaffold.engine.EngineCompositeGenerator; +import com.volmit.iris.scaffold.engine.IrisAccess; +import com.volmit.iris.scaffold.engine.IrisAccessProvider; import com.volmit.iris.util.*; import net.minecraft.server.v1_16_R3.BlockPosition; import net.minecraft.server.v1_16_R3.HeightMap; @@ -26,7 +28,7 @@ import java.util.*; import java.util.concurrent.atomic.AtomicBoolean; import java.util.function.Supplier; -public final class NMSChunkGenerator16_3 extends ChunkGenerator { +public final class NMSChunkGenerator16_3 extends ChunkGenerator implements IrisAccessProvider { private static final IBlockData k; private final O ws; protected final IBlockData f; @@ -595,4 +597,9 @@ public final class NMSChunkGenerator16_3 extends ChunkGenerator { ++i1; } } + + @Override + public IrisAccess getAccess() { + return gen; + } } diff --git a/src/main/java/com/volmit/iris/scaffold/IrisWorlds.java b/src/main/java/com/volmit/iris/scaffold/IrisWorlds.java index f3a759a3b..58e9bb17d 100644 --- a/src/main/java/com/volmit/iris/scaffold/IrisWorlds.java +++ b/src/main/java/com/volmit/iris/scaffold/IrisWorlds.java @@ -2,6 +2,7 @@ package com.volmit.iris.scaffold; import com.volmit.iris.Iris; import com.volmit.iris.scaffold.engine.IrisAccess; +import com.volmit.iris.scaffold.engine.IrisAccessProvider; import com.volmit.iris.util.KMap; import com.volmit.iris.util.MortarSender; import org.bukkit.Bukkit; @@ -24,7 +25,7 @@ public class IrisWorlds return true; } - return world.getGenerator() instanceof IrisAccess; + return world.getGenerator() instanceof IrisAccess || world.getGenerator() instanceof IrisAccessProvider; } public static IrisAccess access(World world) @@ -36,7 +37,7 @@ public class IrisWorlds return provisioned.get(world.getUID().toString()); } - return ((IrisAccess) world.getGenerator()); + return world.getGenerator() instanceof IrisAccessProvider ? (((IrisAccessProvider)world.getGenerator()).getAccess()) : ((IrisAccess) world.getGenerator()); } return null; diff --git a/src/main/java/com/volmit/iris/scaffold/engine/Engine.java b/src/main/java/com/volmit/iris/scaffold/engine/Engine.java index 9c943e862..2e223a490 100644 --- a/src/main/java/com/volmit/iris/scaffold/engine/Engine.java +++ b/src/main/java/com/volmit/iris/scaffold/engine/Engine.java @@ -26,6 +26,8 @@ import java.util.Arrays; public interface Engine extends DataProvider, Fallible, GeneratorAccess, LootProvider, BlockUpdater, Renderer, Hotloadable { public void close(); + public int getCurrentlyGenerating(); + public boolean isClosed(); public EngineWorldManager getWorldManager(); @@ -145,8 +147,11 @@ public interface Engine extends DataProvider, Fallible, GeneratorAccess, LootPro if(B.isUpdatable(data)) { - getParallax().updateBlock(x,y,z); - getParallax().getMetaRW(x>>4, z>>4).setUpdates(true); + synchronized (getParallax()) + { + getParallax().updateBlock(x,y,z); + getParallax().getMetaRW(x>>4, z>>4).setUpdates(true); + } } } diff --git a/src/main/java/com/volmit/iris/scaffold/engine/EngineCompositeGenerator.java b/src/main/java/com/volmit/iris/scaffold/engine/EngineCompositeGenerator.java index 44d6eed8c..56188d372 100644 --- a/src/main/java/com/volmit/iris/scaffold/engine/EngineCompositeGenerator.java +++ b/src/main/java/com/volmit/iris/scaffold/engine/EngineCompositeGenerator.java @@ -10,6 +10,7 @@ import com.volmit.iris.scaffold.IrisWorlds; import com.volmit.iris.scaffold.cache.Cache; import com.volmit.iris.scaffold.hunk.Hunk; import com.volmit.iris.util.*; +import io.papermc.lib.PaperLib; import lombok.Getter; import org.bukkit.*; import org.bukkit.block.Biome; @@ -36,6 +37,7 @@ public class EngineCompositeGenerator extends ChunkGenerator implements IrisAcce private long mst = 0; private int generated = 0; private int lgenerated = 0; + private final KMap chunkCache; private ChronoLatch hotloadcd; @Getter private double generatedPerSecond = 0; @@ -48,6 +50,7 @@ public class EngineCompositeGenerator extends ChunkGenerator implements IrisAcce public EngineCompositeGenerator(String hint, boolean production) { super(); + chunkCache = new KMap<>(); hotloadcd = new ChronoLatch(3500); mst = M.ms(); this.production = production; @@ -305,16 +308,70 @@ public class EngineCompositeGenerator extends ChunkGenerator implements IrisAcce return tc.getRaw(); } + public Chunk generatePaper(World world, int x, int z) + { + precache(world, x, z); + Chunk c = PaperLib.getChunkAtAsync(world, x, z, true).join(); + chunkCache.remove(Cache.key(x, z)); + return c; + } + + public void precache(World world, int x, int z) + { + synchronized (this) + { + initialize(world); + } + + synchronized (chunkCache) + { + if(chunkCache.containsKey(Cache.key(x, z))) + { + return; + } + } + + PregeneratedData data = new PregeneratedData(getComposite().getHeight()-1); + compound.generate(x * 16, z * 16, data.getBlocks(), data.getPost(), data.getBiomes()); + synchronized (chunkCache) + { + chunkCache.put(Cache.key(x, z), data); + } + } + + @Override + public int getPrecacheSize() { + return chunkCache.size(); + } + + public int getCachedChunks() + { + return chunkCache.size(); + } + public Runnable generateChunkRawData(World world, int x, int z, TerrainChunk tc) { initialize(world); + + synchronized (chunkCache) + { + long g = Cache.key(x, z); + if(chunkCache.containsKey(g)) + { + generated++; + return chunkCache.remove(g).inject(tc); + } + } + Hunk blocks = Hunk.view((ChunkData) tc); Hunk biomes = Hunk.view((BiomeGrid) tc); - Hunk post = Hunk.newAtomicHunk(biomes.getWidth(), biomes.getHeight(), biomes.getDepth()); + AtomicBoolean postMod = new AtomicBoolean(false); + Hunk trk = Hunk.newAtomicHunk(biomes.getWidth(), biomes.getHeight(), biomes.getDepth()); + Hunk post = trk.trackWrite(postMod); compound.generate(x * 16, z * 16, blocks, post, biomes); generated++; - return () -> blocks.insertSoftly(0,0,0,post, (b) -> b == null || B.isAirOrFluid(b)); + return postMod.get() ? () -> blocks.insertSoftly(0,0,0, post, (b) -> b == null || B.isAirOrFluid(b)) : () -> {}; } @Override @@ -454,12 +511,6 @@ public class EngineCompositeGenerator extends ChunkGenerator implements IrisAcce @Override public void regenerate(int x, int z) { - if (true) - { - return; - } - - Chunk chunk = getComposite().getWorld().getChunkAt(x, z); generateChunkRawData(getComposite().getWorld(), x, z, new TerrainChunk() { @Override public void setRaw(ChunkData data) { @@ -557,6 +608,7 @@ public class EngineCompositeGenerator extends ChunkGenerator implements IrisAcce Iris.edit.flushNow(); for (BlockPopulator i : populators) { + Chunk chunk = getComposite().getWorld().getChunkAt(x, z); i.populate(compound.getWorld(), new RNG(Cache.key(x, z)), chunk); } } diff --git a/src/main/java/com/volmit/iris/scaffold/engine/EngineCompound.java b/src/main/java/com/volmit/iris/scaffold/engine/EngineCompound.java index 07af71059..c677fd091 100644 --- a/src/main/java/com/volmit/iris/scaffold/engine/EngineCompound.java +++ b/src/main/java/com/volmit/iris/scaffold/engine/EngineCompound.java @@ -23,10 +23,17 @@ public interface EngineCompound extends Listener, Hotloadable, DataProvider public World getWorld(); + public int getCurrentlyGeneratingEngines(); + public void printMetrics(CommandSender sender); public int getSize(); + public default int getHeight() + { + return 256; + } + public Engine getEngine(int index); public MultiBurst getBurster(); diff --git a/src/main/java/com/volmit/iris/scaffold/engine/EngineFramework.java b/src/main/java/com/volmit/iris/scaffold/engine/EngineFramework.java index 09abf4bdb..97f3288ef 100644 --- a/src/main/java/com/volmit/iris/scaffold/engine/EngineFramework.java +++ b/src/main/java/com/volmit/iris/scaffold/engine/EngineFramework.java @@ -1,14 +1,12 @@ package com.volmit.iris.scaffold.engine; +import com.volmit.iris.generator.IrisComplex; +import com.volmit.iris.manager.IrisDataManager; +import com.volmit.iris.scaffold.data.DataProvider; import com.volmit.iris.util.M; -import com.volmit.iris.scaffold.parallel.MultiBurst; import org.bukkit.block.Biome; import org.bukkit.block.data.BlockData; -import com.volmit.iris.manager.IrisDataManager; -import com.volmit.iris.generator.IrisComplex; -import com.volmit.iris.scaffold.data.DataProvider; - public interface EngineFramework extends DataProvider { public Engine getEngine(); @@ -25,10 +23,12 @@ public interface EngineFramework extends DataProvider { if(M.r(0.1)) { - MultiBurst.burst.lazy(() -> { + synchronized (getEngine().getParallax()) + { getEngine().getParallax().cleanup(); - getData().getObjectLoader().clean(); - }); + } + + getData().getObjectLoader().clean(); } } diff --git a/src/main/java/com/volmit/iris/scaffold/engine/IrisAccess.java b/src/main/java/com/volmit/iris/scaffold/engine/IrisAccess.java index b46fe0e1f..2bd7b77d7 100644 --- a/src/main/java/com/volmit/iris/scaffold/engine/IrisAccess.java +++ b/src/main/java/com/volmit/iris/scaffold/engine/IrisAccess.java @@ -4,7 +4,9 @@ import com.volmit.iris.manager.IrisDataManager; import com.volmit.iris.object.*; import com.volmit.iris.scaffold.data.DataProvider; import com.volmit.iris.util.*; +import org.bukkit.Chunk; import org.bukkit.Location; +import org.bukkit.World; import org.bukkit.command.CommandSender; import java.util.concurrent.atomic.AtomicBoolean; @@ -388,4 +390,10 @@ public interface IrisAccess extends Hotloadable, DataProvider { } public void clearRegeneratedLists(int x, int z); + + void precache(World world, int x, int z); + + int getPrecacheSize(); + + Chunk generatePaper(World world, int cx, int cz); } diff --git a/src/main/java/com/volmit/iris/scaffold/engine/IrisAccessProvider.java b/src/main/java/com/volmit/iris/scaffold/engine/IrisAccessProvider.java new file mode 100644 index 000000000..b6be7c237 --- /dev/null +++ b/src/main/java/com/volmit/iris/scaffold/engine/IrisAccessProvider.java @@ -0,0 +1,5 @@ +package com.volmit.iris.scaffold.engine; + +public interface IrisAccessProvider { + public IrisAccess getAccess(); +} diff --git a/src/main/java/com/volmit/iris/scaffold/engine/PregeneratedData.java b/src/main/java/com/volmit/iris/scaffold/engine/PregeneratedData.java new file mode 100644 index 000000000..466f37697 --- /dev/null +++ b/src/main/java/com/volmit/iris/scaffold/engine/PregeneratedData.java @@ -0,0 +1,50 @@ +package com.volmit.iris.scaffold.engine; + +import com.volmit.iris.scaffold.hunk.Hunk; +import com.volmit.iris.util.B; +import com.volmit.iris.util.TerrainChunk; +import lombok.Data; +import org.bukkit.block.Biome; +import org.bukkit.block.data.BlockData; +import org.bukkit.generator.ChunkGenerator; + +import java.util.concurrent.atomic.AtomicBoolean; + +@Data +public class PregeneratedData { + private final Hunk blocks; + private final Hunk post; + private final Hunk biomes; + private final AtomicBoolean postMod; + + public PregeneratedData(int height) + { + postMod = new AtomicBoolean(false); + blocks = Hunk.newAtomicHunk(16, height, 16); + biomes = Hunk.newAtomicHunk(16, height, 16); + Hunk p = Hunk.newMappedHunkSynced(16, height, 16); + post = p.trackWrite(postMod); + } + + public Runnable inject(TerrainChunk tc) { + blocks.iterateSync((x, y, z, b) -> { + if(b != null) + { + tc.setBlock(x, y, z, b); + } + + Biome bf = biomes.get(x,y,z); + if(bf != null) + { + tc.setBiome(x,y,z,bf); + } + }); + + if(postMod.get()) + { + return () -> Hunk.view((ChunkGenerator.ChunkData) tc).insertSoftly(0,0,0, post, (b) -> b == null || B.isAirOrFluid(b)); + } + + return () -> {}; + } +} diff --git a/src/main/java/com/volmit/iris/scaffold/hunk/Hunk.java b/src/main/java/com/volmit/iris/scaffold/hunk/Hunk.java index 62532b143..112ed28a4 100644 --- a/src/main/java/com/volmit/iris/scaffold/hunk/Hunk.java +++ b/src/main/java/com/volmit/iris/scaffold/hunk/Hunk.java @@ -15,6 +15,7 @@ import org.bukkit.generator.ChunkGenerator.ChunkData; import java.io.File; import java.io.IOException; import java.io.OutputStream; +import java.util.concurrent.atomic.AtomicBoolean; import java.util.concurrent.atomic.AtomicInteger; import java.util.function.Consumer; import java.util.function.Predicate; @@ -82,6 +83,11 @@ public interface Hunk return new SynchronizedHunkView<>(this); } + default Hunk trackWrite(AtomicBoolean b) + { + return new WriteTrackHunk(this, b); + } + public static Hunk newArrayHunk(int w, int h, int d) { return new ArrayHunk<>(w, h, d); @@ -1129,7 +1135,7 @@ public interface Hunk */ default T getClosest(int x, int y, int z) { - return getRaw(x >= getWidth() ? getWidth() - 1 : x, y >= getHeight() ? getHeight() - 1 : y, z >= getDepth() ? getDepth() - 1 : z); + return getRaw(x >= getWidth() ? getWidth() - 1 : x < 0 ? 0 : x, y >= getHeight() ? getHeight() - 1 : y < 0 ? 0 : y, z >= getDepth() ? getDepth() - 1 : z < 0 ? 0 : z); } default void fill(T t) diff --git a/src/main/java/com/volmit/iris/scaffold/hunk/view/WriteTrackHunk.java b/src/main/java/com/volmit/iris/scaffold/hunk/view/WriteTrackHunk.java new file mode 100644 index 000000000..00fdc5d36 --- /dev/null +++ b/src/main/java/com/volmit/iris/scaffold/hunk/view/WriteTrackHunk.java @@ -0,0 +1,57 @@ +package com.volmit.iris.scaffold.hunk.view; + +import com.volmit.iris.scaffold.hunk.Hunk; + +import java.util.concurrent.atomic.AtomicBoolean; + +public class WriteTrackHunk implements Hunk { + private final Hunk src; + private final AtomicBoolean b; + + public WriteTrackHunk(Hunk src, AtomicBoolean b) + { + this.src = src; + this.b = b; + } + + @Override + public void setRaw(int x, int y, int z, T t) + { + if(!b.get()) + { + b.set(true); + } + + src.setRaw(x,y,z,t); + } + + @Override + public T getRaw(int x, int y, int z) + { + return src.getRaw(x, y, z); + } + + @Override + public int getWidth() + { + return src.getWidth(); + } + + @Override + public int getHeight() + { + return src.getHeight(); + } + + @Override + public int getDepth() + { + return src.getDepth(); + } + + @Override + public Hunk getSource() + { + return src; + } +} diff --git a/src/main/java/com/volmit/iris/util/AtomicAverage.java b/src/main/java/com/volmit/iris/util/AtomicAverage.java index a13375273..2ec248a5e 100644 --- a/src/main/java/com/volmit/iris/util/AtomicAverage.java +++ b/src/main/java/com/volmit/iris/util/AtomicAverage.java @@ -40,20 +40,28 @@ public class AtomicAverage { */ public void put(double i) { - dirty = true; - - if(brandNew) + try { - DoubleArrayUtils.fill(values, i); - lastSum = size() * i; - brandNew = false; - return; + dirty = true; + + if(brandNew) + { + DoubleArrayUtils.fill(values, i); + lastSum = size() * i; + brandNew = false; + return; + } + + double current = values.get(cursor); + lastSum = (lastSum - current) + i; + values.set(cursor, i); + cursor = cursor + 1 < size() ? cursor + 1 : 0; + } + + catch(Throwable e) + { + } - - double current = values.get(cursor); - lastSum = (lastSum - current) + i; - values.set(cursor, i); - cursor = cursor + 1 < size() ? cursor + 1 : 0; } /** diff --git a/src/main/java/com/volmit/iris/util/PregenJob.java b/src/main/java/com/volmit/iris/util/PregenJob.java index ade9b4b3a..228d634f1 100644 --- a/src/main/java/com/volmit/iris/util/PregenJob.java +++ b/src/main/java/com/volmit/iris/util/PregenJob.java @@ -3,6 +3,9 @@ package com.volmit.iris.util; import com.volmit.iris.Iris; import com.volmit.iris.IrisSettings; import com.volmit.iris.manager.gui.PregenGui; +import com.volmit.iris.scaffold.IrisWorlds; +import com.volmit.iris.scaffold.engine.IrisAccess; +import com.volmit.iris.scaffold.parallel.MultiBurst; import io.papermc.lib.PaperLib; import org.bukkit.Bukkit; import org.bukkit.Chunk; @@ -34,6 +37,7 @@ public class PregenJob implements Listener private ChronoLatch clx; private ChronoLatch clf; private MortarSender sender; + private MultiBurst burst; private int mcaWidth; private int mcaX; private int mcaZ; @@ -42,25 +46,30 @@ public class PregenJob implements Listener private Runnable onDone; private Spiraler spiraler; private Spiraler chunkSpiraler; + private Spiraler preSpiraler; private boolean first; private static Consumer2 consumer; private double cps = 0; private int lg = 0; private long lt = M.ms(); - private int cubeSize = 32; + private int cubeSize = IrisSettings.get().isUseGleamPregenerator() ? 32 : 32; private long nogen = M.ms(); private KList requeueMCA = new KList(); private RollingSequence acps = new RollingSequence(PaperLib.isPaper() ? 8 : 32); private boolean paused = false; private long pausedAt = 0; private double pms = 0; + private boolean gleaming = false; int xc = 0; + private IrisAccess access = null; public PregenJob(World world, int size, MortarSender sender, Runnable onDone) { + gleaming = IrisSettings.get().isUseGleamPregenerator(); g.set(0); + burst = new MultiBurst(gleaming ? IrisSettings.get().getMaxAsyncChunkPregenThreads() : tc()); instance = this; - working = new Semaphore(tc()); + working = new Semaphore(gleaming ? IrisSettings.get().getMaxAsyncChunkPregenThreads() : tc()); this.s = PrecisionStopwatch.start(); Iris.instance.registerListener(this); this.world = world; @@ -86,6 +95,11 @@ public class PregenJob implements Listener chunkZ = (mcaZ * cubeSize) + z; }); + preSpiraler = new Spiraler(cubeSize, cubeSize, (x, z) -> + { + + }); + spiraler = new Spiraler(mcaWidth, mcaWidth, (x, z) -> { mcaX = x; @@ -115,6 +129,17 @@ public class PregenJob implements Listener return IrisSettings.get().maxAsyncChunkPregenThreads; } + private IrisAccess access() { + if(access != null) + { + return access; + } + + access = IrisWorlds.access(world); + + return access; + } + public static void stop() { try @@ -183,10 +208,7 @@ public class PregenJob implements Listener if(PaperLib.isPaper()) { - for(int i = 0; i < 16; i++) - { - tickPaper(skip); - } + tickPaper(skip); } else @@ -225,12 +247,12 @@ public class PregenJob implements Listener public void tickPaper(boolean skip) { - if(working.getQueueLength() >= tc() / 2) + if(working.getQueueLength() >= tc()) { return; } - for(int i = 0; i < 128; i++) + for(int i = 0; i < 64; i++) { tick(skip); } @@ -326,7 +348,7 @@ public class PregenJob implements Listener if(isChunkWithin(chunkX, chunkZ) && consumer != null) { - consumer.accept(new ChunkPosition(chunkX, chunkZ), Color.BLUE.darker().darker()); + consumer.accept(new ChunkPosition(chunkX, chunkZ), Color.BLACK.brighter()); } } chunkSpiraler.retarget(cubeSize, cubeSize); @@ -361,48 +383,78 @@ public class PregenJob implements Listener { if(PaperLib.isPaper()) { - if(consumer != null) - { - consumer.accept(new ChunkPosition(chunkX, chunkZ), Color.magenta.darker().darker().darker()); - } int cx = chunkX; int cz = chunkZ; - J.a(() -> + + if(gleaming) { - try + if(consumer != null) { - working.acquire(); + consumer.accept(new ChunkPosition(chunkX, chunkZ), Color.cyan.darker().darker().darker()); + } - if(consumer != null) - { - consumer.accept(new ChunkPosition(cx, cz), Color.magenta); - } - - PaperLib.getChunkAtAsyncUrgently(world, cx, cz, true).thenAccept(chunk -> - { + J.a(() -> { + try { + working.acquire(); + if(consumer != null) + { + consumer.accept(new ChunkPosition(cx, cz), Color.cyan); + } + Chunk chunk = access().generatePaper(world, cx, cz); working.release(); genned++; nogen = M.ms(); if(consumer != null) { - consumer.accept(new ChunkPosition(chunk.getX(), chunk.getZ()), Color.blue); + consumer.accept(new ChunkPosition(chunk.getX(), chunk.getZ()), Color.yellow); } - }); - } + } catch (InterruptedException e) { + e.printStackTrace(); + } + }); + } - catch(InterruptedException e) + else + {if(consumer != null) + { + consumer.accept(new ChunkPosition(chunkX, chunkZ), Color.magenta.darker().darker().darker()); + } + J.a(() -> { - e.printStackTrace(); - } - }); + try + { + working.acquire(); + + if(consumer != null) + { + consumer.accept(new ChunkPosition(cx, cz), Color.magenta); + } + + Chunk chunk = PaperLib.getChunkAtAsync(world, cx, cz, true).join(); + working.release(); + genned++; + nogen = M.ms(); + + if(consumer != null) + { + consumer.accept(new ChunkPosition(chunk.getX(), chunk.getZ()), Color.green); + } + } + + catch(InterruptedException e) + { + e.printStackTrace(); + } + }); + } } else { if(consumer != null) { - consumer.accept(new ChunkPosition(chunkX, chunkZ), Color.blue.darker().darker()); + consumer.accept(new ChunkPosition(chunkX, chunkZ), Color.black.brighter()); } world.loadChunk(chunkX, chunkZ); @@ -533,8 +585,27 @@ public class PregenJob implements Listener { long eta = (long) ((total - genned) * 1000D / cps); - return new String[] {"Progress: " + Form.pc(Math.min((double) genned / (double) total, 1.0), 0), "Generated: " + Form.f(genned) + " Chunks", "Remaining: " + Form.f(total - genned) + " Chunks", "Elapsed: " + Form.duration((long) (paused ? pms : s.getMilliseconds()), 2), "Estimate: " + ((genned >= total - 5 ? "Any second..." : s.getMilliseconds() < 25000 ? "Calculating..." : Form.duration(eta, 2))), "ChunksMS: " + Form.duration(1000D / cps, 2), "Chunks/s: " + Form.f(cps, 1), - }; + KList vv = new KList( new String[] {"Progress: " + Form.pc(Math.min((double) genned / (double) total, 1.0), 0), + "Generated: " + Form.f(genned) + " Chunks", + "Remaining: " + Form.f(total - genned) + " Chunks", + "Elapsed: " + Form.duration((long) (paused ? pms : s.getMilliseconds()), 2), + "Estimate: " + ((genned >= total - 5 ? "Any second..." : s.getMilliseconds() < 25000 ? "Calculating..." : Form.duration(eta, 2))), + "ChunksMS: " + Form.duration(1000D / cps, 2), + "Chunks/zs: " + Form.f(cps, 1), + }); + + try + { + vv.add("Parallelism: " + access().getCompound().getCurrentlyGeneratingEngines()); + vv.add("Precache : " + access().getPrecacheSize()); + } + + catch(Throwable e) + { + + } + + return vv.toArray(new String[vv.size()]); } public static void pauseResume()