From 2702c0f2e45a5ecf7cd5a4ab8797558f5942c36b Mon Sep 17 00:00:00 2001 From: Daniel Mills Date: Mon, 20 Jan 2020 19:46:20 -0500 Subject: [PATCH] f --- .../java/ninja/bytecode/iris/CommandIris.java | 93 ++++++ .../java/ninja/bytecode/iris/Settings.java | 4 +- .../iris/generator/IrisGenerator.java | 4 +- .../bytecode/iris/generator/WorldReactor.java | 277 ++++++++++++++++++ .../atomics}/AtomicCharArray.java | 2 +- .../atomics}/AtomicChunkData.java | 3 +- .../atomics/AtomicRegionData.java} | 6 +- .../atomics}/AtomicWorldData.java | 19 +- .../genobject/GenObjectDecorator.java | 2 +- .../iris/generator/layer/GenLayerCarving.java | 2 +- .../iris/generator/layer/GenLayerCaverns.java | 2 +- .../iris/generator/layer/GenLayerCaves.java | 2 +- .../parallax}/ParallaxAnchor.java | 3 +- .../parallax}/ParallaxCache.java | 6 +- .../parallax}/ParallaxWorldGenerator.java | 41 ++- .../parallax}/ParallelChunkGenerator.java | 22 +- .../placer/AtomicParallaxPlacer.java | 2 +- .../ninja/bytecode/iris/util/ChronoQueue.java | 27 +- .../iris/util/ChunkSpliceListener.java | 14 + .../bytecode/iris/util/IrisWorldData.java | 32 +- .../bytecode/iris/util/PrepackagedChunk.java | 2 + 21 files changed, 525 insertions(+), 40 deletions(-) create mode 100644 src/main/java/ninja/bytecode/iris/generator/WorldReactor.java rename src/main/java/ninja/bytecode/iris/{util => generator/atomics}/AtomicCharArray.java (97%) rename src/main/java/ninja/bytecode/iris/{util => generator/atomics}/AtomicChunkData.java (99%) rename src/main/java/ninja/bytecode/iris/{util/AtomicMCAData.java => generator/atomics/AtomicRegionData.java} (93%) rename src/main/java/ninja/bytecode/iris/{util => generator/atomics}/AtomicWorldData.java (82%) rename src/main/java/ninja/bytecode/iris/{util => generator/parallax}/ParallaxAnchor.java (85%) rename src/main/java/ninja/bytecode/iris/{util => generator/parallax}/ParallaxCache.java (90%) rename src/main/java/ninja/bytecode/iris/{util => generator/parallax}/ParallaxWorldGenerator.java (82%) rename src/main/java/ninja/bytecode/iris/{util => generator/parallax}/ParallelChunkGenerator.java (85%) create mode 100644 src/main/java/ninja/bytecode/iris/util/ChunkSpliceListener.java diff --git a/src/main/java/ninja/bytecode/iris/CommandIris.java b/src/main/java/ninja/bytecode/iris/CommandIris.java index 3938ed0da..80c0abbd6 100644 --- a/src/main/java/ninja/bytecode/iris/CommandIris.java +++ b/src/main/java/ninja/bytecode/iris/CommandIris.java @@ -1,5 +1,7 @@ package ninja.bytecode.iris; +import java.util.Random; + import org.bukkit.ChatColor; import org.bukkit.Chunk; import org.bukkit.Location; @@ -10,13 +12,24 @@ import org.bukkit.command.CommandSender; import org.bukkit.entity.Player; import mortar.api.nms.NMP; +import mortar.compute.math.M; +import mortar.lang.collection.FinalBoolean; import mortar.util.text.C; +import mortar.util.text.PhantomSpinner; import ninja.bytecode.iris.controller.TimingsController; import ninja.bytecode.iris.generator.IrisGenerator; +import ninja.bytecode.iris.generator.WorldReactor; import ninja.bytecode.iris.generator.genobject.PlacedObject; +import ninja.bytecode.iris.generator.layer.GenLayerLayeredNoise; import ninja.bytecode.iris.pack.IrisBiome; import ninja.bytecode.iris.util.BiomeLayer; +import ninja.bytecode.iris.util.SMCAVector; +import ninja.bytecode.shuriken.collections.GMap; +import ninja.bytecode.shuriken.execution.ChronoLatch; +import ninja.bytecode.shuriken.execution.TaskExecutor; import ninja.bytecode.shuriken.format.F; +import ninja.bytecode.shuriken.math.CNG; +import ninja.bytecode.shuriken.math.RNG; public class CommandIris implements CommandExecutor { @@ -212,6 +225,86 @@ public class CommandIris implements CommandExecutor Iris.instance.reload(); } + if(args[0].equalsIgnoreCase("pregen")) + { + Player p = ((Player) sender); + int x = Integer.valueOf(args[1]); + int z = Integer.valueOf(args[2]); + int tc = Integer.valueOf(args[3]); + msg(sender, "Generating MCA[" + x + "," + z + "] with " + tc + " Threads"); + WorldReactor reactor = new WorldReactor(p.getWorld()); + + GMap xf = new GMap<>(); + xf.put(new SMCAVector(x, z), new TaskExecutor(tc / 4, Thread.MAX_PRIORITY, "Iris Reactor " + x + "," + z)); + xf.put(new SMCAVector(x + 1, z), new TaskExecutor(tc / 4, Thread.MAX_PRIORITY, "Iris Reactor " + x + "," + z)); + xf.put(new SMCAVector(x, z + 1), new TaskExecutor(tc / 4, Thread.MAX_PRIORITY, "Iris Reactor " + x + "," + z)); + xf.put(new SMCAVector(x + 1, z + 1), new TaskExecutor(tc / 4, Thread.MAX_PRIORITY, "Iris Reactor " + x + "," + z)); + FinalBoolean d = new FinalBoolean(false); + CNG cng = new CNG(RNG.r, 1D, 12); + reactor.generateMultipleRegions(xf, true, 45, (px) -> + { + for(int mf = 0; mf < 20; mf++) + { + double n = cng.noise(0, (double) (mf + ((double) M.tick() / 1D)) / 6D); + int b = 40; + int g = (int) (n * b); + p.sendMessage(F.repeat(" ", g) + "◐"); + } + + p.sendMessage(" "); + + msg(p, "Generating: " + C.GOLD + F.pc(px)); + }, () -> + { + d.set(true); + msg(sender, "Done."); + p.teleport(new Location(p.getWorld(), (((x << 5) + 32) << 4), 200, (((z << 5) + 32) << 4))); + + for(TaskExecutor i : xf.v()) + { + i.close(); + } + }); + } + + if(args[0].equalsIgnoreCase("regen")) + { + Player p = ((Player) sender); + int x = p.getLocation().getChunk().getX() >> 5; + int z = p.getLocation().getChunk().getZ() >> 5; + int tc = Runtime.getRuntime().availableProcessors(); + msg(sender, "Generating with " + tc + " Threads"); + WorldReactor reactor = new WorldReactor(p.getWorld()); + TaskExecutor e = new TaskExecutor(tc, Thread.MAX_PRIORITY, "Iris Reactor " + x + "," + z); + FinalBoolean d = new FinalBoolean(false); + CNG cng = new CNG(RNG.r, 1D, 12); + Location l = new Location(p.getWorld(), (((x << 5) + 16) << 4), 200, (((z << 5) + 16) << 4)); + l.setDirection(p.getLocation().getDirection()); + l.setY(p.getLocation().getY()); + p.teleport(l); + + reactor.generateRegionNormal(p, x, z, true, 45, (px) -> + { + for(int mf = 0; mf < 20; mf++) + { + double n = cng.noise(0, (double) (mf + ((double) M.tick() / 1D)) / 6D); + int b = 40; + int g = (int) (n * b); + p.sendMessage(F.repeat(" ", g) + "◐"); + } + + p.sendMessage(" "); + + msg(p, "Generating: " + C.GOLD + F.pc(px)); + }, () -> + { + d.set(true); + msg(sender, "Done."); + + e.close(); + }); + } + if(args[0].equalsIgnoreCase("refresh")) { msg(sender, "Sec..."); diff --git a/src/main/java/ninja/bytecode/iris/Settings.java b/src/main/java/ninja/bytecode/iris/Settings.java index cbaf81bab..bfe4c5f59 100644 --- a/src/main/java/ninja/bytecode/iris/Settings.java +++ b/src/main/java/ninja/bytecode/iris/Settings.java @@ -9,8 +9,8 @@ public class Settings public static class PerformanceSettings { - public PerformanceMode performanceMode = PerformanceMode.HALF_CPU; - public boolean fastMode = true; + public PerformanceMode performanceMode = PerformanceMode.DOUBLE_CPU; + public boolean fastMode = false; public int threadPriority = Thread.MAX_PRIORITY; public int threadCount = 4; public boolean debugMode = true; diff --git a/src/main/java/ninja/bytecode/iris/generator/IrisGenerator.java b/src/main/java/ninja/bytecode/iris/generator/IrisGenerator.java index ea833bebe..1fddc9151 100644 --- a/src/main/java/ninja/bytecode/iris/generator/IrisGenerator.java +++ b/src/main/java/ninja/bytecode/iris/generator/IrisGenerator.java @@ -11,6 +11,7 @@ import org.bukkit.util.NumberConversions; import mortar.util.text.C; import ninja.bytecode.iris.Iris; import ninja.bytecode.iris.controller.PackController; +import ninja.bytecode.iris.generator.atomics.AtomicChunkData; import ninja.bytecode.iris.generator.genobject.GenObjectDecorator; import ninja.bytecode.iris.generator.genobject.PlacedObject; import ninja.bytecode.iris.generator.layer.GenLayerBiome; @@ -20,15 +21,14 @@ import ninja.bytecode.iris.generator.layer.GenLayerCaves; import ninja.bytecode.iris.generator.layer.GenLayerCliffs; import ninja.bytecode.iris.generator.layer.GenLayerLayeredNoise; import ninja.bytecode.iris.generator.layer.GenLayerSnow; +import ninja.bytecode.iris.generator.parallax.ParallaxWorldGenerator; import ninja.bytecode.iris.pack.BiomeType; import ninja.bytecode.iris.pack.CompiledDimension; import ninja.bytecode.iris.pack.IrisBiome; import ninja.bytecode.iris.pack.IrisRegion; -import ninja.bytecode.iris.util.AtomicChunkData; import ninja.bytecode.iris.util.ChunkPlan; import ninja.bytecode.iris.util.IrisInterpolation; import ninja.bytecode.iris.util.MB; -import ninja.bytecode.iris.util.ParallaxWorldGenerator; import ninja.bytecode.iris.util.SChunkVector; import ninja.bytecode.shuriken.collections.GList; import ninja.bytecode.shuriken.logging.L; diff --git a/src/main/java/ninja/bytecode/iris/generator/WorldReactor.java b/src/main/java/ninja/bytecode/iris/generator/WorldReactor.java new file mode 100644 index 000000000..c71c1fc6b --- /dev/null +++ b/src/main/java/ninja/bytecode/iris/generator/WorldReactor.java @@ -0,0 +1,277 @@ +package ninja.bytecode.iris.generator; + +import java.util.concurrent.locks.ReentrantLock; +import java.util.function.Consumer; + +import org.bukkit.Chunk; +import org.bukkit.World; +import org.bukkit.entity.Player; + +import mortar.api.nms.NMP; +import mortar.api.sched.J; +import mortar.compute.math.M; +import mortar.lang.collection.FinalDouble; +import ninja.bytecode.iris.generator.atomics.AtomicChunkData; +import ninja.bytecode.iris.util.ChronoQueue; +import ninja.bytecode.iris.util.ChunkPlan; +import ninja.bytecode.iris.util.SMCAVector; +import ninja.bytecode.shuriken.bench.PrecisionStopwatch; +import ninja.bytecode.shuriken.collections.GList; +import ninja.bytecode.shuriken.collections.GMap; +import ninja.bytecode.shuriken.execution.ChronoLatch; +import ninja.bytecode.shuriken.execution.NastyRunnable; +import ninja.bytecode.shuriken.execution.TaskExecutor; +import ninja.bytecode.shuriken.math.RNG; + +public class WorldReactor +{ + private final World world; + private IrisGenerator gen; + + public WorldReactor(World world) + { + this.world = world; + + if(!(world.getGenerator() instanceof IrisGenerator)) + { + throw new IllegalArgumentException(world.getName() + " is not an iris world."); + } + + this.gen = ((IrisGenerator) world.getGenerator()); + } + + public void generateMultipleRegions(GMap g, boolean force, double mst, Consumer progress, Runnable done) + { + ChronoLatch cl = new ChronoLatch(50); + GMap p = new GMap<>(); + ReentrantLock r = new ReentrantLock(); + for(SMCAVector i : g.k()) + { + generateRegion(i.getX(), i.getZ(), g.get(i), force, mst / (double) g.size(), (xp) -> + { + r.lock(); + p.put(i, xp); + double m = 0; + + for(double j : p.v()) + { + m += j; + } + r.unlock(); + + double h = m / (double) p.size(); + + if(h == 1D || cl.flip()) + { + progress.accept(h); + } + }, () -> + { + p.remove(i); + + if(p.isEmpty()) + { + done.run(); + } + }); + } + } + + public void generateRegion(int mx, int mz, TaskExecutor executor, boolean force, double mst, Consumer progress, Runnable done) + { + J.a(() -> + { + FinalDouble of = new FinalDouble(0D); + FinalDouble max = new FinalDouble(0D); + PrecisionStopwatch t = PrecisionStopwatch.start(); + GMap data = new GMap<>(); + GMap plan = new GMap<>(); + GList parallax = new GList<>(); + GList noise = new GList<>(); + GList chunk = new GList<>(); + ReentrantLock lock = new ReentrantLock(); + + for(int xx = mx << 5; xx < (mx << 5) + 32; xx++) + { + int x = xx; + + for(int zz = mz << 5; zz < (mz << 5) + 32; zz++) + { + int z = zz; + SMCAVector w = new SMCAVector(x, z); + + if(!force && world.loadChunk(x, z, false)) + { + // continue; + } + + max.add(1); + parallax.add(() -> + { + gen.doGenParallax(x, z); + of.add(1); + progress.accept(of.get() / max.get()); + }); + + max.add(0.1); + noise.add(() -> + { + AtomicChunkData tydata = new AtomicChunkData(world); + ChunkPlan typlan = new ChunkPlan(); + + for(int i = 0; i < 16; i++) + { + for(int j = 0; j < 16; j++) + { + gen.onGenColumn((x << 4) + i, (z << 4) + j, i, j, typlan, tydata); + } + } + + gen.getWorldData().getChunk(x, z).inject(tydata); + gen.onPostChunk(world, x, z, new RNG(world.getSeed()), tydata, typlan); + + lock.lock(); + data.put(w, tydata); + plan.put(w, typlan); + lock.unlock(); + of.add(1); + progress.accept(of.get() / max.get()); + }); + + max.add(4); + chunk.add(() -> + { + if(world.loadChunk(x, z, false)) + { + world.regenerateChunk(x, z); + } + + else + { + world.loadChunk(x, z, true); + } + + Chunk cc = world.getChunkAt(x, z); + NMP.host.relight(cc); + cc.unload(true); + }); + } + } + + executor.startWork().queue(parallax).execute(); + executor.startWork().queue(noise).execute(); + + gen.setSplicer((world, random, x, z, biome) -> + { + SMCAVector w = new SMCAVector(x, z); + + for(int i = 0; i < 16; i++) + { + for(int j = 0; j < 16; j++) + { + try + { + biome.setBiome((x << 4) + i, (z << 4) + j, plan.get(w).getBiome(i, j).getRealBiome()); + } + + catch(Throwable e) + { + + } + } + } + + AtomicChunkData f = data.get(w); + + if(f != null) + { + + } + + return f; + }); + + t.end(); + J.s(() -> + { + PrecisionStopwatch s = PrecisionStopwatch.start(); + ChronoQueue q = new ChronoQueue(mst, 1096); + int m = 0; + for(Runnable i : chunk) + { + int gg = m; + + q.queue(() -> + { + i.run(); + of.add(4); + if(gg == chunk.size() - 1) + { + progress.accept(1D); + s.end(); + q.dieSlowly(); + done.run(); + } + + else + { + progress.accept(M.clip(of.get() / max.get(), 0D, 1D)); + } + }); + + m++; + } + }); + }); + } + + public void generateRegionNormal(Player p, boolean force, double mst, Consumer progress, Runnable done) + { + ChronoQueue q = new ChronoQueue(mst, 1024); + FinalDouble of = new FinalDouble(0D); + FinalDouble max = new FinalDouble(0D); + + for(int xx = p.getLocation().getChunk().getX() - 32; xx < p.getLocation().getChunk().getX() + 32; xx++) + { + int x = xx; + + for(int zz = p.getLocation().getChunk().getX() - 32; zz < p.getLocation().getChunk().getX() + 32; zz++) + { + int z = zz; + + max.add(1); + + q.queue(() -> + { + if(world.loadChunk(x, z, false)) + { + world.regenerateChunk(x, z); + } + + else + { + world.loadChunk(x, z, true); + } + + Chunk cc = world.getChunkAt(x, z); + NMP.host.relight(cc); + of.add(1); + + if(of.get() == max.get()) + { + progress.accept(1D); + q.dieSlowly(); + done.run(); + } + + else + { + progress.accept(M.clip(of.get() / max.get(), 0D, 1D)); + } + }); + } + } + + q.dieSlowly(); + } +} diff --git a/src/main/java/ninja/bytecode/iris/util/AtomicCharArray.java b/src/main/java/ninja/bytecode/iris/generator/atomics/AtomicCharArray.java similarity index 97% rename from src/main/java/ninja/bytecode/iris/util/AtomicCharArray.java rename to src/main/java/ninja/bytecode/iris/generator/atomics/AtomicCharArray.java index 71076507a..7f032167e 100644 --- a/src/main/java/ninja/bytecode/iris/util/AtomicCharArray.java +++ b/src/main/java/ninja/bytecode/iris/generator/atomics/AtomicCharArray.java @@ -1,4 +1,4 @@ -package ninja.bytecode.iris.util; +package ninja.bytecode.iris.generator.atomics; import java.io.Serializable; import java.lang.reflect.Field; diff --git a/src/main/java/ninja/bytecode/iris/util/AtomicChunkData.java b/src/main/java/ninja/bytecode/iris/generator/atomics/AtomicChunkData.java similarity index 99% rename from src/main/java/ninja/bytecode/iris/util/AtomicChunkData.java rename to src/main/java/ninja/bytecode/iris/generator/atomics/AtomicChunkData.java index b96d38a9a..c97fde72c 100644 --- a/src/main/java/ninja/bytecode/iris/util/AtomicChunkData.java +++ b/src/main/java/ninja/bytecode/iris/generator/atomics/AtomicChunkData.java @@ -1,4 +1,4 @@ -package ninja.bytecode.iris.util; +package ninja.bytecode.iris.generator.atomics; import java.io.DataInputStream; import java.io.DataOutputStream; @@ -16,6 +16,7 @@ import org.bukkit.generator.ChunkGenerator.ChunkData; import org.bukkit.material.MaterialData; import mortar.compute.math.M; +import ninja.bytecode.iris.util.MB; public final class AtomicChunkData implements ChunkGenerator.ChunkData { diff --git a/src/main/java/ninja/bytecode/iris/util/AtomicMCAData.java b/src/main/java/ninja/bytecode/iris/generator/atomics/AtomicRegionData.java similarity index 93% rename from src/main/java/ninja/bytecode/iris/util/AtomicMCAData.java rename to src/main/java/ninja/bytecode/iris/generator/atomics/AtomicRegionData.java index cabef8a5c..361e3a305 100644 --- a/src/main/java/ninja/bytecode/iris/util/AtomicMCAData.java +++ b/src/main/java/ninja/bytecode/iris/generator/atomics/AtomicRegionData.java @@ -1,4 +1,4 @@ -package ninja.bytecode.iris.util; +package ninja.bytecode.iris.generator.atomics; import java.io.ByteArrayInputStream; import java.io.ByteArrayOutputStream; @@ -15,12 +15,12 @@ import org.jnbt.Tag; import ninja.bytecode.shuriken.collections.GMap; -public class AtomicMCAData +public class AtomicRegionData { private final World world; private GMap tag; - public AtomicMCAData(World world) + public AtomicRegionData(World world) { this.world = world; tag = new GMap<>(); diff --git a/src/main/java/ninja/bytecode/iris/util/AtomicWorldData.java b/src/main/java/ninja/bytecode/iris/generator/atomics/AtomicWorldData.java similarity index 82% rename from src/main/java/ninja/bytecode/iris/util/AtomicWorldData.java rename to src/main/java/ninja/bytecode/iris/generator/atomics/AtomicWorldData.java index a64514954..847b9c285 100644 --- a/src/main/java/ninja/bytecode/iris/util/AtomicWorldData.java +++ b/src/main/java/ninja/bytecode/iris/generator/atomics/AtomicWorldData.java @@ -1,4 +1,4 @@ -package ninja.bytecode.iris.util; +package ninja.bytecode.iris.generator.atomics; import java.io.File; import java.io.FileInputStream; @@ -7,13 +7,14 @@ import java.io.IOException; import org.bukkit.World; +import ninja.bytecode.iris.util.SMCAVector; import ninja.bytecode.shuriken.collections.GList; import ninja.bytecode.shuriken.collections.GMap; public class AtomicWorldData { private World world; - private GMap loadedSections; + private GMap loadedSections; public AtomicWorldData(World world) { @@ -27,14 +28,14 @@ public class AtomicWorldData return loadedSections.k(); } - public AtomicMCAData getSubregion(int x, int z) throws IOException + public AtomicRegionData getSubregion(int x, int z) throws IOException { if(!isSectionLoaded(x, z)) { loadedSections.put(new SMCAVector(x, z), loadSection(x, z)); } - AtomicMCAData f = loadedSections.get(new SMCAVector(x, z)); + AtomicRegionData f = loadedSections.get(new SMCAVector(x, z)); return f; } @@ -104,14 +105,14 @@ public class AtomicWorldData return false; } - AtomicMCAData data = loadedSections.get(s); + AtomicRegionData data = loadedSections.get(s); FileOutputStream fos = new FileOutputStream(getSubregionFile(s.getX(), s.getZ())); data.write(fos); fos.close(); return true; } - public AtomicMCAData loadSection(int x, int z) throws IOException + public AtomicRegionData loadSection(int x, int z) throws IOException { if(isSectionLoaded(x, z)) { @@ -126,20 +127,20 @@ public class AtomicWorldData } FileInputStream fin = new FileInputStream(file); - AtomicMCAData data = new AtomicMCAData(world); + AtomicRegionData data = new AtomicRegionData(world); data.read(fin); fin.close(); return data; } - public AtomicMCAData createSection(int x, int z) + public AtomicRegionData createSection(int x, int z) { if(isSectionLoaded(x, z)) { return loadedSections.get(new SMCAVector(x, z)); } - AtomicMCAData data = new AtomicMCAData(world); + AtomicRegionData data = new AtomicRegionData(world); loadedSections.put(new SMCAVector(x, z), data); return data; diff --git a/src/main/java/ninja/bytecode/iris/generator/genobject/GenObjectDecorator.java b/src/main/java/ninja/bytecode/iris/generator/genobject/GenObjectDecorator.java index 81ceb33e4..d99bc0348 100644 --- a/src/main/java/ninja/bytecode/iris/generator/genobject/GenObjectDecorator.java +++ b/src/main/java/ninja/bytecode/iris/generator/genobject/GenObjectDecorator.java @@ -10,11 +10,11 @@ import mortar.util.text.C; import net.md_5.bungee.api.ChatColor; import ninja.bytecode.iris.Iris; import ninja.bytecode.iris.generator.IrisGenerator; +import ninja.bytecode.iris.generator.parallax.ParallaxCache; import ninja.bytecode.iris.generator.placer.AtomicParallaxPlacer; import ninja.bytecode.iris.pack.IrisBiome; import ninja.bytecode.iris.util.IPlacer; import ninja.bytecode.iris.util.MB; -import ninja.bytecode.iris.util.ParallaxCache; import ninja.bytecode.iris.util.SMCAVector; import ninja.bytecode.shuriken.collections.GList; import ninja.bytecode.shuriken.collections.GMap; diff --git a/src/main/java/ninja/bytecode/iris/generator/layer/GenLayerCarving.java b/src/main/java/ninja/bytecode/iris/generator/layer/GenLayerCarving.java index cad4c5be6..36ce2bc1a 100644 --- a/src/main/java/ninja/bytecode/iris/generator/layer/GenLayerCarving.java +++ b/src/main/java/ninja/bytecode/iris/generator/layer/GenLayerCarving.java @@ -7,8 +7,8 @@ import org.bukkit.World; import ninja.bytecode.iris.Iris; import ninja.bytecode.iris.generator.IrisGenerator; +import ninja.bytecode.iris.generator.atomics.AtomicChunkData; import ninja.bytecode.iris.pack.IrisBiome; -import ninja.bytecode.iris.util.AtomicChunkData; import ninja.bytecode.iris.util.GenLayer; import ninja.bytecode.iris.util.IrisInterpolation; import ninja.bytecode.iris.util.MB; diff --git a/src/main/java/ninja/bytecode/iris/generator/layer/GenLayerCaverns.java b/src/main/java/ninja/bytecode/iris/generator/layer/GenLayerCaverns.java index 88df73988..29da1ad09 100644 --- a/src/main/java/ninja/bytecode/iris/generator/layer/GenLayerCaverns.java +++ b/src/main/java/ninja/bytecode/iris/generator/layer/GenLayerCaverns.java @@ -7,8 +7,8 @@ import org.bukkit.World; import ninja.bytecode.iris.Iris; import ninja.bytecode.iris.generator.IrisGenerator; +import ninja.bytecode.iris.generator.atomics.AtomicChunkData; import ninja.bytecode.iris.pack.IrisBiome; -import ninja.bytecode.iris.util.AtomicChunkData; import ninja.bytecode.iris.util.GenLayer; import ninja.bytecode.iris.util.IrisInterpolation; import ninja.bytecode.iris.util.MB; diff --git a/src/main/java/ninja/bytecode/iris/generator/layer/GenLayerCaves.java b/src/main/java/ninja/bytecode/iris/generator/layer/GenLayerCaves.java index db7187c15..933573083 100644 --- a/src/main/java/ninja/bytecode/iris/generator/layer/GenLayerCaves.java +++ b/src/main/java/ninja/bytecode/iris/generator/layer/GenLayerCaves.java @@ -7,7 +7,7 @@ import org.bukkit.World; import ninja.bytecode.iris.Iris; import ninja.bytecode.iris.generator.IrisGenerator; -import ninja.bytecode.iris.util.AtomicChunkData; +import ninja.bytecode.iris.generator.atomics.AtomicChunkData; import ninja.bytecode.iris.util.GenLayer; import ninja.bytecode.iris.util.PolygonGenerator; import ninja.bytecode.shuriken.math.CNG; diff --git a/src/main/java/ninja/bytecode/iris/util/ParallaxAnchor.java b/src/main/java/ninja/bytecode/iris/generator/parallax/ParallaxAnchor.java similarity index 85% rename from src/main/java/ninja/bytecode/iris/util/ParallaxAnchor.java rename to src/main/java/ninja/bytecode/iris/generator/parallax/ParallaxAnchor.java index ed7fe2575..b56f51c75 100644 --- a/src/main/java/ninja/bytecode/iris/util/ParallaxAnchor.java +++ b/src/main/java/ninja/bytecode/iris/generator/parallax/ParallaxAnchor.java @@ -1,5 +1,6 @@ -package ninja.bytecode.iris.util; +package ninja.bytecode.iris.generator.parallax; +import ninja.bytecode.iris.generator.atomics.AtomicChunkData; import ninja.bytecode.iris.pack.IrisBiome; public class ParallaxAnchor diff --git a/src/main/java/ninja/bytecode/iris/util/ParallaxCache.java b/src/main/java/ninja/bytecode/iris/generator/parallax/ParallaxCache.java similarity index 90% rename from src/main/java/ninja/bytecode/iris/util/ParallaxCache.java rename to src/main/java/ninja/bytecode/iris/generator/parallax/ParallaxCache.java index 073532aa1..3f1b1fb64 100644 --- a/src/main/java/ninja/bytecode/iris/util/ParallaxCache.java +++ b/src/main/java/ninja/bytecode/iris/generator/parallax/ParallaxCache.java @@ -1,7 +1,11 @@ -package ninja.bytecode.iris.util; +package ninja.bytecode.iris.generator.parallax; import ninja.bytecode.iris.generator.IrisGenerator; +import ninja.bytecode.iris.generator.atomics.AtomicChunkData; import ninja.bytecode.iris.pack.IrisBiome; +import ninja.bytecode.iris.util.ChunkPlan; +import ninja.bytecode.iris.util.MB; +import ninja.bytecode.iris.util.SMCAVector; import ninja.bytecode.shuriken.collections.GMap; import ninja.bytecode.shuriken.collections.GSet; diff --git a/src/main/java/ninja/bytecode/iris/util/ParallaxWorldGenerator.java b/src/main/java/ninja/bytecode/iris/generator/parallax/ParallaxWorldGenerator.java similarity index 82% rename from src/main/java/ninja/bytecode/iris/util/ParallaxWorldGenerator.java rename to src/main/java/ninja/bytecode/iris/generator/parallax/ParallaxWorldGenerator.java index 12478bbbf..0af842718 100644 --- a/src/main/java/ninja/bytecode/iris/util/ParallaxWorldGenerator.java +++ b/src/main/java/ninja/bytecode/iris/generator/parallax/ParallaxWorldGenerator.java @@ -1,4 +1,4 @@ -package ninja.bytecode.iris.util; +package ninja.bytecode.iris.generator.parallax; import java.util.Random; @@ -16,6 +16,10 @@ import org.bukkit.event.world.WorldUnloadEvent; import mortar.api.nms.NMP; import ninja.bytecode.iris.Iris; import ninja.bytecode.iris.controller.TimingsController; +import ninja.bytecode.iris.generator.atomics.AtomicChunkData; +import ninja.bytecode.iris.util.ChunkPlan; +import ninja.bytecode.iris.util.IrisWorldData; +import ninja.bytecode.iris.util.SChunkVector; import ninja.bytecode.shuriken.bench.PrecisionStopwatch; import ninja.bytecode.shuriken.collections.GSet; import ninja.bytecode.shuriken.execution.ChronoLatch; @@ -31,11 +35,13 @@ public abstract class ParallaxWorldGenerator extends ParallelChunkGenerator impl private AtomicChunkData buffer; private GSet fix; private ChronoLatch cl; + protected boolean saving; @Override public final void init(World world, Random random) { this.world = world; + saving = true; cl = new ChronoLatch(3000); fix = new GSet<>(); buffer = new AtomicChunkData(world); @@ -45,9 +51,26 @@ public abstract class ParallaxWorldGenerator extends ParallelChunkGenerator impl Bukkit.getPluginManager().registerEvents(this, Iris.instance); } + public void disableSaving() + { + saving = false; + data.disableSaving(); + } + + public void enableSaving() + { + saving = true; + data.enableSaving(); + } + @EventHandler public void on(ChunkLoadEvent e) { + if(!saving) + { + return; + } + if(!Iris.settings.performance.fastMode && e.getWorld().equals(world)) { NMP.host.relight(e.getChunk()); @@ -81,6 +104,11 @@ public abstract class ParallaxWorldGenerator extends ParallelChunkGenerator impl @EventHandler public void on(WorldSaveEvent e) { + if(!saving) + { + return; + } + if(e.getWorld().equals(world)) { getWorldData().saveAll(); @@ -102,6 +130,12 @@ public abstract class ParallaxWorldGenerator extends ParallelChunkGenerator impl return new ParallaxAnchor(heightBuffer.getRealHeight(wx & 15, wz & 15), heightBuffer.getRealWaterHeight(wx & 15, wz & 15), heightBuffer.getBiome(wx & 15, wz & 15), buffer); } + public void doGenParallax(int x, int z) + { + onGenParallax(x, z, getRMaster(x, z, -59328)); + getWorldData().getChunk(x, z); + } + @Override public final ChunkPlan initChunk(World world, int x, int z, Random random) { @@ -136,7 +170,10 @@ public abstract class ParallaxWorldGenerator extends ParallelChunkGenerator impl double a = ps.getMilliseconds(); double b = g.execute().timeElapsed; - System.out.println("MS: " + F.duration(Iris.getController(TimingsController.class).getResult("terrain"), 2) + " \tQMS: " + F.duration(a, 2) + " " + " \tEMS: " + F.duration(b, 2) + "\tSCG: " + gg + " / " + gx + " (" + F.pc(((double) gg / (double) gx)) + ") " + " \tTC: " + F.f(getWorldData().getLoadedChunks().size()) + " \tTR: " + getWorldData().getLoadedRegions().size()); + if(Iris.settings.performance.verbose) + { + System.out.println("MS: " + F.duration(Iris.getController(TimingsController.class).getResult("terrain"), 2) + " \tQMS: " + F.duration(a, 2) + " " + " \tEMS: " + F.duration(b, 2) + "\tSCG: " + gg + " / " + gx + " (" + F.pc(((double) gg / (double) gx)) + ") " + " \tTC: " + F.f(getWorldData().getLoadedChunks().size()) + " \tTR: " + getWorldData().getLoadedRegions().size()); + } return onInitChunk(world, x, z, random); } diff --git a/src/main/java/ninja/bytecode/iris/util/ParallelChunkGenerator.java b/src/main/java/ninja/bytecode/iris/generator/parallax/ParallelChunkGenerator.java similarity index 85% rename from src/main/java/ninja/bytecode/iris/util/ParallelChunkGenerator.java rename to src/main/java/ninja/bytecode/iris/generator/parallax/ParallelChunkGenerator.java index 5a60156e6..f1c818cbe 100644 --- a/src/main/java/ninja/bytecode/iris/util/ParallelChunkGenerator.java +++ b/src/main/java/ninja/bytecode/iris/generator/parallax/ParallelChunkGenerator.java @@ -1,4 +1,4 @@ -package ninja.bytecode.iris.util; +package ninja.bytecode.iris.generator.parallax; import java.util.Random; import java.util.concurrent.locks.ReentrantLock; @@ -11,9 +11,13 @@ import org.bukkit.generator.ChunkGenerator; import ninja.bytecode.iris.Iris; import ninja.bytecode.iris.controller.ExecutionController; import ninja.bytecode.iris.controller.TimingsController; +import ninja.bytecode.iris.generator.atomics.AtomicChunkData; +import ninja.bytecode.iris.util.ChunkPlan; +import ninja.bytecode.iris.util.ChunkSpliceListener; import ninja.bytecode.shuriken.execution.TaskExecutor; import ninja.bytecode.shuriken.execution.TaskExecutor.TaskGroup; import ninja.bytecode.shuriken.execution.TaskExecutor.TaskResult; +import ninja.bytecode.shuriken.logging.L; import ninja.bytecode.shuriken.math.RollingSequence; import ninja.bytecode.shuriken.reaction.O; @@ -31,6 +35,12 @@ public abstract class ParallelChunkGenerator extends ChunkGenerator private World world; private TaskExecutor genPool; private TaskExecutor genPar; + private ChunkSpliceListener splicer; + + public void setSplicer(ChunkSpliceListener splicer) + { + this.splicer = splicer; + } public World getWorld() { @@ -64,6 +74,16 @@ public abstract class ParallelChunkGenerator extends ChunkGenerator public ChunkData generateChunkData(World world, Random random, int x, int z, BiomeGrid biome) { + if(splicer != null) + { + AtomicChunkData d = splicer.onSpliceAvailable(world, random, x, z, biome); + + if(d != null) + { + return d.toChunkData(); + } + } + AtomicChunkData data = new AtomicChunkData(world); try diff --git a/src/main/java/ninja/bytecode/iris/generator/placer/AtomicParallaxPlacer.java b/src/main/java/ninja/bytecode/iris/generator/placer/AtomicParallaxPlacer.java index 004e7ef38..3481b1d8f 100644 --- a/src/main/java/ninja/bytecode/iris/generator/placer/AtomicParallaxPlacer.java +++ b/src/main/java/ninja/bytecode/iris/generator/placer/AtomicParallaxPlacer.java @@ -3,9 +3,9 @@ package ninja.bytecode.iris.generator.placer; import org.bukkit.Location; import ninja.bytecode.iris.generator.IrisGenerator; +import ninja.bytecode.iris.generator.parallax.ParallaxCache; import ninja.bytecode.iris.util.IrisWorldData; import ninja.bytecode.iris.util.MB; -import ninja.bytecode.iris.util.ParallaxCache; import ninja.bytecode.iris.util.Placer; public class AtomicParallaxPlacer extends Placer diff --git a/src/main/java/ninja/bytecode/iris/util/ChronoQueue.java b/src/main/java/ninja/bytecode/iris/util/ChronoQueue.java index b36f5c09b..f40d9a1d0 100644 --- a/src/main/java/ninja/bytecode/iris/util/ChronoQueue.java +++ b/src/main/java/ninja/bytecode/iris/util/ChronoQueue.java @@ -16,16 +16,27 @@ public class ChronoQueue private Queue q; private double limit; private int jobLimit; - private ChronoLatch cl; + private boolean die; + private int j; public ChronoQueue(double limit, int jobLimit) { + die = false; this.limit = limit; this.jobLimit = jobLimit; s = new PrecisionStopwatch(); - Bukkit.getScheduler().scheduleSyncRepeatingTask(Iris.instance, this::tick, 0, 0); + j = Bukkit.getScheduler().scheduleSyncRepeatingTask(Iris.instance, this::tick, 0, 0); q = new ShurikenQueue<>(); - cl = new ChronoLatch(1); + } + + public void close() + { + Bukkit.getScheduler().cancelTask(j); + } + + public void dieSlowly() + { + die = true; } public void queue(Runnable r) @@ -52,11 +63,11 @@ public class ChronoQueue } } - if(cl.flip()) - { - System.out.println("Q: " + F.f(q.size()) + " T: " + F.duration(s.getMilliseconds(), 2) + " DID: " + F.f(m)); - } - s.end(); + + if(q.size() == 0 && die) + { + close(); + } } } diff --git a/src/main/java/ninja/bytecode/iris/util/ChunkSpliceListener.java b/src/main/java/ninja/bytecode/iris/util/ChunkSpliceListener.java new file mode 100644 index 000000000..381288cd4 --- /dev/null +++ b/src/main/java/ninja/bytecode/iris/util/ChunkSpliceListener.java @@ -0,0 +1,14 @@ +package ninja.bytecode.iris.util; + +import java.util.Random; + +import org.bukkit.World; +import org.bukkit.generator.ChunkGenerator.BiomeGrid; + +import ninja.bytecode.iris.generator.atomics.AtomicChunkData; + +@FunctionalInterface +public interface ChunkSpliceListener +{ + public AtomicChunkData onSpliceAvailable(World world, Random random, int x, int z, BiomeGrid biome); +} diff --git a/src/main/java/ninja/bytecode/iris/util/IrisWorldData.java b/src/main/java/ninja/bytecode/iris/util/IrisWorldData.java index 218b19eb8..823cdf1bd 100644 --- a/src/main/java/ninja/bytecode/iris/util/IrisWorldData.java +++ b/src/main/java/ninja/bytecode/iris/util/IrisWorldData.java @@ -8,27 +8,46 @@ import org.bukkit.World; import mortar.logic.format.F; import mortar.util.text.C; import ninja.bytecode.iris.Iris; +import ninja.bytecode.iris.generator.atomics.AtomicChunkData; +import ninja.bytecode.iris.generator.atomics.AtomicRegionData; +import ninja.bytecode.iris.generator.atomics.AtomicWorldData; import ninja.bytecode.shuriken.collections.GList; import ninja.bytecode.shuriken.collections.GMap; -import ninja.bytecode.shuriken.execution.ChronoLatch; import ninja.bytecode.shuriken.logging.L; public class IrisWorldData { private final World world; private final AtomicWorldData data; + private boolean saving; private final GMap loadedChunks; public IrisWorldData(World world) { this.world = world; + saving = true; data = new AtomicWorldData(world); loadedChunks = new GMap<>(); Bukkit.getScheduler().scheduleSyncRepeatingTask(Iris.instance, this::softUnloadWorld, 200, 20); } + public void disableSaving() + { + saving = false; + } + + public void enableSaving() + { + saving = true; + } + private void softUnloadWorld() { + if(!saving) + { + return; + } + L.i("Load: " + F.f(getLoadedChunks().size()) + " Chunks in " + F.f(getLoadedRegions().size()) + " Regions"); for(SMCAVector i : getLoadedChunks()) @@ -56,6 +75,11 @@ public class IrisWorldData private boolean softUnloadRegion(int rx, int rz) { + if(!saving) + { + return false; + } + for(SMCAVector i : loadedChunks.keySet()) { if(i.getX() >> 5 == rx && i.getZ() >> 5 == rz) @@ -88,7 +112,7 @@ public class IrisWorldData try { - AtomicMCAData region = data.getSubregion(x >> 5, z >> 5); + AtomicRegionData region = data.getSubregion(x >> 5, z >> 5); region.delete(x & 31, z & 31); return true; } @@ -127,7 +151,7 @@ public class IrisWorldData try { - AtomicMCAData region = data.getSubregion(x >> 5, z >> 5); + AtomicRegionData region = data.getSubregion(x >> 5, z >> 5); region.set(x & 31, z & 31, getChunk(x, z)); return true; } @@ -157,7 +181,7 @@ public class IrisWorldData { try { - AtomicMCAData region = data.getSubregion(x >> 5, z >> 5); + AtomicRegionData region = data.getSubregion(x >> 5, z >> 5); if(region.contains(x & 31, z & 31)) { diff --git a/src/main/java/ninja/bytecode/iris/util/PrepackagedChunk.java b/src/main/java/ninja/bytecode/iris/util/PrepackagedChunk.java index 0d5692e66..da6344608 100644 --- a/src/main/java/ninja/bytecode/iris/util/PrepackagedChunk.java +++ b/src/main/java/ninja/bytecode/iris/util/PrepackagedChunk.java @@ -2,6 +2,8 @@ package ninja.bytecode.iris.util; import org.bukkit.block.Biome; +import ninja.bytecode.iris.generator.atomics.AtomicChunkData; + public class PrepackagedChunk { private AtomicChunkData data;