This commit is contained in:
Daniel Mills 2020-01-20 19:46:20 -05:00
parent 2aef5f94c0
commit 2702c0f2e4
21 changed files with 525 additions and 40 deletions

View File

@ -1,5 +1,7 @@
package ninja.bytecode.iris; package ninja.bytecode.iris;
import java.util.Random;
import org.bukkit.ChatColor; import org.bukkit.ChatColor;
import org.bukkit.Chunk; import org.bukkit.Chunk;
import org.bukkit.Location; import org.bukkit.Location;
@ -10,13 +12,24 @@ import org.bukkit.command.CommandSender;
import org.bukkit.entity.Player; import org.bukkit.entity.Player;
import mortar.api.nms.NMP; import mortar.api.nms.NMP;
import mortar.compute.math.M;
import mortar.lang.collection.FinalBoolean;
import mortar.util.text.C; import mortar.util.text.C;
import mortar.util.text.PhantomSpinner;
import ninja.bytecode.iris.controller.TimingsController; import ninja.bytecode.iris.controller.TimingsController;
import ninja.bytecode.iris.generator.IrisGenerator; import ninja.bytecode.iris.generator.IrisGenerator;
import ninja.bytecode.iris.generator.WorldReactor;
import ninja.bytecode.iris.generator.genobject.PlacedObject; import ninja.bytecode.iris.generator.genobject.PlacedObject;
import ninja.bytecode.iris.generator.layer.GenLayerLayeredNoise;
import ninja.bytecode.iris.pack.IrisBiome; import ninja.bytecode.iris.pack.IrisBiome;
import ninja.bytecode.iris.util.BiomeLayer; 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.format.F;
import ninja.bytecode.shuriken.math.CNG;
import ninja.bytecode.shuriken.math.RNG;
public class CommandIris implements CommandExecutor public class CommandIris implements CommandExecutor
{ {
@ -212,6 +225,86 @@ public class CommandIris implements CommandExecutor
Iris.instance.reload(); 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<SMCAVector, TaskExecutor> 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")) if(args[0].equalsIgnoreCase("refresh"))
{ {
msg(sender, "Sec..."); msg(sender, "Sec...");

View File

@ -9,8 +9,8 @@ public class Settings
public static class PerformanceSettings public static class PerformanceSettings
{ {
public PerformanceMode performanceMode = PerformanceMode.HALF_CPU; public PerformanceMode performanceMode = PerformanceMode.DOUBLE_CPU;
public boolean fastMode = true; public boolean fastMode = false;
public int threadPriority = Thread.MAX_PRIORITY; public int threadPriority = Thread.MAX_PRIORITY;
public int threadCount = 4; public int threadCount = 4;
public boolean debugMode = true; public boolean debugMode = true;

View File

@ -11,6 +11,7 @@ import org.bukkit.util.NumberConversions;
import mortar.util.text.C; import mortar.util.text.C;
import ninja.bytecode.iris.Iris; import ninja.bytecode.iris.Iris;
import ninja.bytecode.iris.controller.PackController; 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.GenObjectDecorator;
import ninja.bytecode.iris.generator.genobject.PlacedObject; import ninja.bytecode.iris.generator.genobject.PlacedObject;
import ninja.bytecode.iris.generator.layer.GenLayerBiome; 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.GenLayerCliffs;
import ninja.bytecode.iris.generator.layer.GenLayerLayeredNoise; import ninja.bytecode.iris.generator.layer.GenLayerLayeredNoise;
import ninja.bytecode.iris.generator.layer.GenLayerSnow; 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.BiomeType;
import ninja.bytecode.iris.pack.CompiledDimension; import ninja.bytecode.iris.pack.CompiledDimension;
import ninja.bytecode.iris.pack.IrisBiome; import ninja.bytecode.iris.pack.IrisBiome;
import ninja.bytecode.iris.pack.IrisRegion; import ninja.bytecode.iris.pack.IrisRegion;
import ninja.bytecode.iris.util.AtomicChunkData;
import ninja.bytecode.iris.util.ChunkPlan; import ninja.bytecode.iris.util.ChunkPlan;
import ninja.bytecode.iris.util.IrisInterpolation; import ninja.bytecode.iris.util.IrisInterpolation;
import ninja.bytecode.iris.util.MB; import ninja.bytecode.iris.util.MB;
import ninja.bytecode.iris.util.ParallaxWorldGenerator;
import ninja.bytecode.iris.util.SChunkVector; import ninja.bytecode.iris.util.SChunkVector;
import ninja.bytecode.shuriken.collections.GList; import ninja.bytecode.shuriken.collections.GList;
import ninja.bytecode.shuriken.logging.L; import ninja.bytecode.shuriken.logging.L;

View File

@ -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<SMCAVector, TaskExecutor> g, boolean force, double mst, Consumer<Double> progress, Runnable done)
{
ChronoLatch cl = new ChronoLatch(50);
GMap<SMCAVector, Double> 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<Double> progress, Runnable done)
{
J.a(() ->
{
FinalDouble of = new FinalDouble(0D);
FinalDouble max = new FinalDouble(0D);
PrecisionStopwatch t = PrecisionStopwatch.start();
GMap<SMCAVector, AtomicChunkData> data = new GMap<>();
GMap<SMCAVector, ChunkPlan> plan = new GMap<>();
GList<NastyRunnable> parallax = new GList<>();
GList<NastyRunnable> noise = new GList<>();
GList<Runnable> 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<Double> 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();
}
}

View File

@ -1,4 +1,4 @@
package ninja.bytecode.iris.util; package ninja.bytecode.iris.generator.atomics;
import java.io.Serializable; import java.io.Serializable;
import java.lang.reflect.Field; import java.lang.reflect.Field;

View File

@ -1,4 +1,4 @@
package ninja.bytecode.iris.util; package ninja.bytecode.iris.generator.atomics;
import java.io.DataInputStream; import java.io.DataInputStream;
import java.io.DataOutputStream; import java.io.DataOutputStream;
@ -16,6 +16,7 @@ import org.bukkit.generator.ChunkGenerator.ChunkData;
import org.bukkit.material.MaterialData; import org.bukkit.material.MaterialData;
import mortar.compute.math.M; import mortar.compute.math.M;
import ninja.bytecode.iris.util.MB;
public final class AtomicChunkData implements ChunkGenerator.ChunkData public final class AtomicChunkData implements ChunkGenerator.ChunkData
{ {

View File

@ -1,4 +1,4 @@
package ninja.bytecode.iris.util; package ninja.bytecode.iris.generator.atomics;
import java.io.ByteArrayInputStream; import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream; import java.io.ByteArrayOutputStream;
@ -15,12 +15,12 @@ import org.jnbt.Tag;
import ninja.bytecode.shuriken.collections.GMap; import ninja.bytecode.shuriken.collections.GMap;
public class AtomicMCAData public class AtomicRegionData
{ {
private final World world; private final World world;
private GMap<String, Tag> tag; private GMap<String, Tag> tag;
public AtomicMCAData(World world) public AtomicRegionData(World world)
{ {
this.world = world; this.world = world;
tag = new GMap<>(); tag = new GMap<>();

View File

@ -1,4 +1,4 @@
package ninja.bytecode.iris.util; package ninja.bytecode.iris.generator.atomics;
import java.io.File; import java.io.File;
import java.io.FileInputStream; import java.io.FileInputStream;
@ -7,13 +7,14 @@ import java.io.IOException;
import org.bukkit.World; import org.bukkit.World;
import ninja.bytecode.iris.util.SMCAVector;
import ninja.bytecode.shuriken.collections.GList; import ninja.bytecode.shuriken.collections.GList;
import ninja.bytecode.shuriken.collections.GMap; import ninja.bytecode.shuriken.collections.GMap;
public class AtomicWorldData public class AtomicWorldData
{ {
private World world; private World world;
private GMap<SMCAVector, AtomicMCAData> loadedSections; private GMap<SMCAVector, AtomicRegionData> loadedSections;
public AtomicWorldData(World world) public AtomicWorldData(World world)
{ {
@ -27,14 +28,14 @@ public class AtomicWorldData
return loadedSections.k(); 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)) if(!isSectionLoaded(x, z))
{ {
loadedSections.put(new SMCAVector(x, z), loadSection(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; return f;
} }
@ -104,14 +105,14 @@ public class AtomicWorldData
return false; return false;
} }
AtomicMCAData data = loadedSections.get(s); AtomicRegionData data = loadedSections.get(s);
FileOutputStream fos = new FileOutputStream(getSubregionFile(s.getX(), s.getZ())); FileOutputStream fos = new FileOutputStream(getSubregionFile(s.getX(), s.getZ()));
data.write(fos); data.write(fos);
fos.close(); fos.close();
return true; return true;
} }
public AtomicMCAData loadSection(int x, int z) throws IOException public AtomicRegionData loadSection(int x, int z) throws IOException
{ {
if(isSectionLoaded(x, z)) if(isSectionLoaded(x, z))
{ {
@ -126,20 +127,20 @@ public class AtomicWorldData
} }
FileInputStream fin = new FileInputStream(file); FileInputStream fin = new FileInputStream(file);
AtomicMCAData data = new AtomicMCAData(world); AtomicRegionData data = new AtomicRegionData(world);
data.read(fin); data.read(fin);
fin.close(); fin.close();
return data; return data;
} }
public AtomicMCAData createSection(int x, int z) public AtomicRegionData createSection(int x, int z)
{ {
if(isSectionLoaded(x, z)) if(isSectionLoaded(x, z))
{ {
return loadedSections.get(new SMCAVector(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); loadedSections.put(new SMCAVector(x, z), data);
return data; return data;

View File

@ -10,11 +10,11 @@ import mortar.util.text.C;
import net.md_5.bungee.api.ChatColor; import net.md_5.bungee.api.ChatColor;
import ninja.bytecode.iris.Iris; import ninja.bytecode.iris.Iris;
import ninja.bytecode.iris.generator.IrisGenerator; import ninja.bytecode.iris.generator.IrisGenerator;
import ninja.bytecode.iris.generator.parallax.ParallaxCache;
import ninja.bytecode.iris.generator.placer.AtomicParallaxPlacer; import ninja.bytecode.iris.generator.placer.AtomicParallaxPlacer;
import ninja.bytecode.iris.pack.IrisBiome; import ninja.bytecode.iris.pack.IrisBiome;
import ninja.bytecode.iris.util.IPlacer; import ninja.bytecode.iris.util.IPlacer;
import ninja.bytecode.iris.util.MB; import ninja.bytecode.iris.util.MB;
import ninja.bytecode.iris.util.ParallaxCache;
import ninja.bytecode.iris.util.SMCAVector; import ninja.bytecode.iris.util.SMCAVector;
import ninja.bytecode.shuriken.collections.GList; import ninja.bytecode.shuriken.collections.GList;
import ninja.bytecode.shuriken.collections.GMap; import ninja.bytecode.shuriken.collections.GMap;

View File

@ -7,8 +7,8 @@ import org.bukkit.World;
import ninja.bytecode.iris.Iris; import ninja.bytecode.iris.Iris;
import ninja.bytecode.iris.generator.IrisGenerator; import ninja.bytecode.iris.generator.IrisGenerator;
import ninja.bytecode.iris.generator.atomics.AtomicChunkData;
import ninja.bytecode.iris.pack.IrisBiome; import ninja.bytecode.iris.pack.IrisBiome;
import ninja.bytecode.iris.util.AtomicChunkData;
import ninja.bytecode.iris.util.GenLayer; import ninja.bytecode.iris.util.GenLayer;
import ninja.bytecode.iris.util.IrisInterpolation; import ninja.bytecode.iris.util.IrisInterpolation;
import ninja.bytecode.iris.util.MB; import ninja.bytecode.iris.util.MB;

View File

@ -7,8 +7,8 @@ import org.bukkit.World;
import ninja.bytecode.iris.Iris; import ninja.bytecode.iris.Iris;
import ninja.bytecode.iris.generator.IrisGenerator; import ninja.bytecode.iris.generator.IrisGenerator;
import ninja.bytecode.iris.generator.atomics.AtomicChunkData;
import ninja.bytecode.iris.pack.IrisBiome; import ninja.bytecode.iris.pack.IrisBiome;
import ninja.bytecode.iris.util.AtomicChunkData;
import ninja.bytecode.iris.util.GenLayer; import ninja.bytecode.iris.util.GenLayer;
import ninja.bytecode.iris.util.IrisInterpolation; import ninja.bytecode.iris.util.IrisInterpolation;
import ninja.bytecode.iris.util.MB; import ninja.bytecode.iris.util.MB;

View File

@ -7,7 +7,7 @@ import org.bukkit.World;
import ninja.bytecode.iris.Iris; import ninja.bytecode.iris.Iris;
import ninja.bytecode.iris.generator.IrisGenerator; 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.GenLayer;
import ninja.bytecode.iris.util.PolygonGenerator; import ninja.bytecode.iris.util.PolygonGenerator;
import ninja.bytecode.shuriken.math.CNG; import ninja.bytecode.shuriken.math.CNG;

View File

@ -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; import ninja.bytecode.iris.pack.IrisBiome;
public class ParallaxAnchor public class ParallaxAnchor

View File

@ -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.IrisGenerator;
import ninja.bytecode.iris.generator.atomics.AtomicChunkData;
import ninja.bytecode.iris.pack.IrisBiome; 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.GMap;
import ninja.bytecode.shuriken.collections.GSet; import ninja.bytecode.shuriken.collections.GSet;

View File

@ -1,4 +1,4 @@
package ninja.bytecode.iris.util; package ninja.bytecode.iris.generator.parallax;
import java.util.Random; import java.util.Random;
@ -16,6 +16,10 @@ import org.bukkit.event.world.WorldUnloadEvent;
import mortar.api.nms.NMP; import mortar.api.nms.NMP;
import ninja.bytecode.iris.Iris; import ninja.bytecode.iris.Iris;
import ninja.bytecode.iris.controller.TimingsController; 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.bench.PrecisionStopwatch;
import ninja.bytecode.shuriken.collections.GSet; import ninja.bytecode.shuriken.collections.GSet;
import ninja.bytecode.shuriken.execution.ChronoLatch; import ninja.bytecode.shuriken.execution.ChronoLatch;
@ -31,11 +35,13 @@ public abstract class ParallaxWorldGenerator extends ParallelChunkGenerator impl
private AtomicChunkData buffer; private AtomicChunkData buffer;
private GSet<Chunk> fix; private GSet<Chunk> fix;
private ChronoLatch cl; private ChronoLatch cl;
protected boolean saving;
@Override @Override
public final void init(World world, Random random) public final void init(World world, Random random)
{ {
this.world = world; this.world = world;
saving = true;
cl = new ChronoLatch(3000); cl = new ChronoLatch(3000);
fix = new GSet<>(); fix = new GSet<>();
buffer = new AtomicChunkData(world); buffer = new AtomicChunkData(world);
@ -45,9 +51,26 @@ public abstract class ParallaxWorldGenerator extends ParallelChunkGenerator impl
Bukkit.getPluginManager().registerEvents(this, Iris.instance); Bukkit.getPluginManager().registerEvents(this, Iris.instance);
} }
public void disableSaving()
{
saving = false;
data.disableSaving();
}
public void enableSaving()
{
saving = true;
data.enableSaving();
}
@EventHandler @EventHandler
public void on(ChunkLoadEvent e) public void on(ChunkLoadEvent e)
{ {
if(!saving)
{
return;
}
if(!Iris.settings.performance.fastMode && e.getWorld().equals(world)) if(!Iris.settings.performance.fastMode && e.getWorld().equals(world))
{ {
NMP.host.relight(e.getChunk()); NMP.host.relight(e.getChunk());
@ -81,6 +104,11 @@ public abstract class ParallaxWorldGenerator extends ParallelChunkGenerator impl
@EventHandler @EventHandler
public void on(WorldSaveEvent e) public void on(WorldSaveEvent e)
{ {
if(!saving)
{
return;
}
if(e.getWorld().equals(world)) if(e.getWorld().equals(world))
{ {
getWorldData().saveAll(); 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); 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 @Override
public final ChunkPlan initChunk(World world, int x, int z, Random random) 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 a = ps.getMilliseconds();
double b = g.execute().timeElapsed; 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); return onInitChunk(world, x, z, random);
} }

View File

@ -1,4 +1,4 @@
package ninja.bytecode.iris.util; package ninja.bytecode.iris.generator.parallax;
import java.util.Random; import java.util.Random;
import java.util.concurrent.locks.ReentrantLock; import java.util.concurrent.locks.ReentrantLock;
@ -11,9 +11,13 @@ import org.bukkit.generator.ChunkGenerator;
import ninja.bytecode.iris.Iris; import ninja.bytecode.iris.Iris;
import ninja.bytecode.iris.controller.ExecutionController; import ninja.bytecode.iris.controller.ExecutionController;
import ninja.bytecode.iris.controller.TimingsController; 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;
import ninja.bytecode.shuriken.execution.TaskExecutor.TaskGroup; import ninja.bytecode.shuriken.execution.TaskExecutor.TaskGroup;
import ninja.bytecode.shuriken.execution.TaskExecutor.TaskResult; import ninja.bytecode.shuriken.execution.TaskExecutor.TaskResult;
import ninja.bytecode.shuriken.logging.L;
import ninja.bytecode.shuriken.math.RollingSequence; import ninja.bytecode.shuriken.math.RollingSequence;
import ninja.bytecode.shuriken.reaction.O; import ninja.bytecode.shuriken.reaction.O;
@ -31,6 +35,12 @@ public abstract class ParallelChunkGenerator extends ChunkGenerator
private World world; private World world;
private TaskExecutor genPool; private TaskExecutor genPool;
private TaskExecutor genPar; private TaskExecutor genPar;
private ChunkSpliceListener splicer;
public void setSplicer(ChunkSpliceListener splicer)
{
this.splicer = splicer;
}
public World getWorld() 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) 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); AtomicChunkData data = new AtomicChunkData(world);
try try

View File

@ -3,9 +3,9 @@ package ninja.bytecode.iris.generator.placer;
import org.bukkit.Location; import org.bukkit.Location;
import ninja.bytecode.iris.generator.IrisGenerator; import ninja.bytecode.iris.generator.IrisGenerator;
import ninja.bytecode.iris.generator.parallax.ParallaxCache;
import ninja.bytecode.iris.util.IrisWorldData; import ninja.bytecode.iris.util.IrisWorldData;
import ninja.bytecode.iris.util.MB; import ninja.bytecode.iris.util.MB;
import ninja.bytecode.iris.util.ParallaxCache;
import ninja.bytecode.iris.util.Placer; import ninja.bytecode.iris.util.Placer;
public class AtomicParallaxPlacer extends Placer public class AtomicParallaxPlacer extends Placer

View File

@ -16,16 +16,27 @@ public class ChronoQueue
private Queue<Runnable> q; private Queue<Runnable> q;
private double limit; private double limit;
private int jobLimit; private int jobLimit;
private ChronoLatch cl; private boolean die;
private int j;
public ChronoQueue(double limit, int jobLimit) public ChronoQueue(double limit, int jobLimit)
{ {
die = false;
this.limit = limit; this.limit = limit;
this.jobLimit = jobLimit; this.jobLimit = jobLimit;
s = new PrecisionStopwatch(); 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<>(); q = new ShurikenQueue<>();
cl = new ChronoLatch(1); }
public void close()
{
Bukkit.getScheduler().cancelTask(j);
}
public void dieSlowly()
{
die = true;
} }
public void queue(Runnable r) 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(); s.end();
if(q.size() == 0 && die)
{
close();
}
} }
} }

View File

@ -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);
}

View File

@ -8,27 +8,46 @@ import org.bukkit.World;
import mortar.logic.format.F; import mortar.logic.format.F;
import mortar.util.text.C; import mortar.util.text.C;
import ninja.bytecode.iris.Iris; 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.GList;
import ninja.bytecode.shuriken.collections.GMap; import ninja.bytecode.shuriken.collections.GMap;
import ninja.bytecode.shuriken.execution.ChronoLatch;
import ninja.bytecode.shuriken.logging.L; import ninja.bytecode.shuriken.logging.L;
public class IrisWorldData public class IrisWorldData
{ {
private final World world; private final World world;
private final AtomicWorldData data; private final AtomicWorldData data;
private boolean saving;
private final GMap<SMCAVector, AtomicChunkData> loadedChunks; private final GMap<SMCAVector, AtomicChunkData> loadedChunks;
public IrisWorldData(World world) public IrisWorldData(World world)
{ {
this.world = world; this.world = world;
saving = true;
data = new AtomicWorldData(world); data = new AtomicWorldData(world);
loadedChunks = new GMap<>(); loadedChunks = new GMap<>();
Bukkit.getScheduler().scheduleSyncRepeatingTask(Iris.instance, this::softUnloadWorld, 200, 20); Bukkit.getScheduler().scheduleSyncRepeatingTask(Iris.instance, this::softUnloadWorld, 200, 20);
} }
public void disableSaving()
{
saving = false;
}
public void enableSaving()
{
saving = true;
}
private void softUnloadWorld() private void softUnloadWorld()
{ {
if(!saving)
{
return;
}
L.i("Load: " + F.f(getLoadedChunks().size()) + " Chunks in " + F.f(getLoadedRegions().size()) + " Regions"); L.i("Load: " + F.f(getLoadedChunks().size()) + " Chunks in " + F.f(getLoadedRegions().size()) + " Regions");
for(SMCAVector i : getLoadedChunks()) for(SMCAVector i : getLoadedChunks())
@ -56,6 +75,11 @@ public class IrisWorldData
private boolean softUnloadRegion(int rx, int rz) private boolean softUnloadRegion(int rx, int rz)
{ {
if(!saving)
{
return false;
}
for(SMCAVector i : loadedChunks.keySet()) for(SMCAVector i : loadedChunks.keySet())
{ {
if(i.getX() >> 5 == rx && i.getZ() >> 5 == rz) if(i.getX() >> 5 == rx && i.getZ() >> 5 == rz)
@ -88,7 +112,7 @@ public class IrisWorldData
try try
{ {
AtomicMCAData region = data.getSubregion(x >> 5, z >> 5); AtomicRegionData region = data.getSubregion(x >> 5, z >> 5);
region.delete(x & 31, z & 31); region.delete(x & 31, z & 31);
return true; return true;
} }
@ -127,7 +151,7 @@ public class IrisWorldData
try 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)); region.set(x & 31, z & 31, getChunk(x, z));
return true; return true;
} }
@ -157,7 +181,7 @@ public class IrisWorldData
{ {
try try
{ {
AtomicMCAData region = data.getSubregion(x >> 5, z >> 5); AtomicRegionData region = data.getSubregion(x >> 5, z >> 5);
if(region.contains(x & 31, z & 31)) if(region.contains(x & 31, z & 31))
{ {

View File

@ -2,6 +2,8 @@ package ninja.bytecode.iris.util;
import org.bukkit.block.Biome; import org.bukkit.block.Biome;
import ninja.bytecode.iris.generator.atomics.AtomicChunkData;
public class PrepackagedChunk public class PrepackagedChunk
{ {
private AtomicChunkData data; private AtomicChunkData data;