From 6d08faa30f2da9129261d91d30b9da1007a19fa3 Mon Sep 17 00:00:00 2001 From: Daniel Mills Date: Sun, 15 Nov 2020 23:36:33 -0500 Subject: [PATCH] Metrics --- src/main/java/com/volmit/iris/Iris.java | 1 - .../com/volmit/iris/generator/IrisEngine.java | 20 ++++ .../iris/generator/IrisEngineCompound.java | 87 ++++++++++++++- .../generator/actuator/IrisBiomeActuator.java | 3 + .../actuator/IrisDecorantActuator.java | 4 + .../actuator/IrisTerrainActuator.java | 4 + .../generator/modifier/IrisCaveModifier.java | 13 ++- .../modifier/IrisDepositModifier.java | 7 +- .../generator/modifier/IrisPostModifier.java | 3 + .../modifier/IrisRavineModifier.java | 2 + .../volmit/iris/manager/IrisDataManager.java | 25 ----- .../iris/manager/command/CommandIris.java | 9 -- .../iris/manager/command/CommandIrisCTC.java | 71 ------------ .../iris/manager/command/CommandIrisIDM.java | 43 -------- .../iris/manager/command/CommandIrisLMM.java | 36 ------- .../manager/command/CommandIrisMetrics.java | 11 +- .../manager/command/CommandIrisStudio.java | 4 +- .../manager/command/CommandIrisStudioMap.java | 5 +- .../volmit/iris/manager/gui/IrisVision.java | 30 ++---- .../com/volmit/iris/object/IrisBiome.java | 27 +---- .../com/volmit/iris/object/IrisColor.java | 97 +++++++++++++++++ .../com/volmit/iris/object/IrisRegion.java | 5 +- .../volmit/iris/scaffold/engine/Engine.java | 28 ++++- .../engine/EngineCompositeGenerator.java | 6 ++ .../iris/scaffold/engine/EngineCompound.java | 10 +- .../iris/scaffold/engine/EngineMetrics.java | 51 +++++++++ .../engine/EngineParallaxManager.java | 8 +- .../iris/scaffold/engine/GeneratorAccess.java | 5 +- .../iris/scaffold/engine/IrisAccess.java | 3 + .../com/volmit/iris/util/AtomicAverage.java | 87 +++++++++++++++ .../iris/util/AtomicRollingSequence.java | 102 ++++++++++++++++++ .../volmit/iris/util/DoubleArrayUtils.java | 14 ++- src/main/java/com/volmit/iris/util/KList.java | 20 ++-- 33 files changed, 576 insertions(+), 265 deletions(-) delete mode 100644 src/main/java/com/volmit/iris/manager/command/CommandIrisCTC.java delete mode 100644 src/main/java/com/volmit/iris/manager/command/CommandIrisIDM.java delete mode 100644 src/main/java/com/volmit/iris/manager/command/CommandIrisLMM.java create mode 100644 src/main/java/com/volmit/iris/object/IrisColor.java create mode 100644 src/main/java/com/volmit/iris/scaffold/engine/EngineMetrics.java create mode 100644 src/main/java/com/volmit/iris/util/AtomicAverage.java create mode 100644 src/main/java/com/volmit/iris/util/AtomicRollingSequence.java diff --git a/src/main/java/com/volmit/iris/Iris.java b/src/main/java/com/volmit/iris/Iris.java index 4a9e6393b..f9c36fb12 100644 --- a/src/main/java/com/volmit/iris/Iris.java +++ b/src/main/java/com/volmit/iris/Iris.java @@ -190,7 +190,6 @@ public class Iris extends VolmitPlugin board.disable(); Bukkit.getScheduler().cancelTasks(this); HandlerList.unregisterAll((Plugin) this); - IrisDataManager.managers.clear(); super.onDisable(); } diff --git a/src/main/java/com/volmit/iris/generator/IrisEngine.java b/src/main/java/com/volmit/iris/generator/IrisEngine.java index 79059cc00..d2b5010c0 100644 --- a/src/main/java/com/volmit/iris/generator/IrisEngine.java +++ b/src/main/java/com/volmit/iris/generator/IrisEngine.java @@ -4,6 +4,8 @@ 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.PrecisionStopwatch; +import com.volmit.iris.util.RNG; import lombok.Getter; import lombok.Setter; import org.bukkit.Chunk; @@ -36,15 +38,20 @@ public class IrisEngine extends BlockPopulator implements Engine @Getter private final int index; + @Getter + private final EngineMetrics metrics; + @Setter @Getter private volatile int minHeight; private boolean failing; private boolean closed; + private int cacheId; 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); this.target = target; this.framework = new IrisEngineFramework(this); worldManager = new IrisWorldManager(this); @@ -53,6 +60,7 @@ public class IrisEngine extends BlockPopulator implements Engine failing = false; closed = false; this.index = index; + cacheId = RNG.r.nextInt(); } @Override @@ -82,6 +90,7 @@ public class IrisEngine extends BlockPopulator implements Engine public void generate(int x, int z, Hunk vblocks, Hunk vbiomes) { try { + PrecisionStopwatch p = PrecisionStopwatch.start(); Hunk biomes = vbiomes; Hunk blocks = vblocks.synchronize().listen((xx,y,zz,t) -> catchBlockUpdates(x+xx,y+getMinHeight(),z+zz, t)); @@ -102,6 +111,7 @@ public class IrisEngine extends BlockPopulator implements Engine getFramework().getEngineParallax().insertParallax(x, z, blocks); getFramework().recycle(); + getMetrics().getTotal().put(p.getMilliseconds()); } catch(Throwable e) { @@ -127,4 +137,14 @@ public class IrisEngine extends BlockPopulator implements Engine public boolean hasFailed() { return failing; } + + @Override + public int getCacheID() { + return cacheId; + } + + @Override + public void hotload() { + cacheId = RNG.r.nextInt(); + } } diff --git a/src/main/java/com/volmit/iris/generator/IrisEngineCompound.java b/src/main/java/com/volmit/iris/generator/IrisEngineCompound.java index 25e487479..72023cba9 100644 --- a/src/main/java/com/volmit/iris/generator/IrisEngineCompound.java +++ b/src/main/java/com/volmit/iris/generator/IrisEngineCompound.java @@ -11,12 +11,13 @@ import com.volmit.iris.scaffold.engine.EngineTarget; import com.volmit.iris.scaffold.hunk.Hunk; import com.volmit.iris.scaffold.parallel.BurstExecutor; import com.volmit.iris.scaffold.parallel.MultiBurst; -import com.volmit.iris.util.KList; +import com.volmit.iris.util.*; import lombok.Getter; import lombok.Setter; import org.bukkit.World; import org.bukkit.block.Biome; import org.bukkit.block.data.BlockData; +import org.bukkit.command.CommandSender; import org.bukkit.event.EventHandler; import org.bukkit.event.world.WorldSaveEvent; import org.bukkit.generator.BlockPopulator; @@ -29,6 +30,8 @@ public class IrisEngineCompound implements EngineCompound { @Getter private final World world; + private final AtomicRollingSequence wallClock; + @Getter private final EngineData engineMetadata; @@ -52,6 +55,7 @@ public class IrisEngineCompound implements EngineCompound { public IrisEngineCompound(World world, IrisDimension rootDimension, IrisDataManager data, int maximumThreads) { + wallClock = new AtomicRollingSequence(32); this.rootDimension = rootDimension; Iris.info("Initializing Engine Composite for " + world.getName()); this.world = world; @@ -116,6 +120,75 @@ public class IrisEngineCompound implements EngineCompound { } } + public void printMetrics(CommandSender sender) + { + KMap totals = new KMap<>(); + KMap weights = new KMap<>(); + double masterWallClock = wallClock.getAverage(); + + for(int i = 0; i < getSize(); i++) + { + Engine e = getEngine(i); + KMap timings = e.getMetrics().pull(); + double totalWeight = 0; + double wallClock = e.getMetrics().getTotal().getAverage(); + + for(double j : timings.values()) + { + totalWeight += j; + } + + for(String j : timings.k()) + { + weights.put(e.getName() + "[" + e.getIndex() + "]." + j, (wallClock / totalWeight) * timings.get(j)); + } + + totals.put(e.getName() + "[" + e.getIndex() + "]", wallClock); + } + + double mtotals = 0; + + for(double i : totals.values()) + { + mtotals+=i; + } + + for(String i : totals.k()) + { + totals.put(i, (masterWallClock / mtotals) * totals.get(i)); + } + + double v = 0; + + for(double i : weights.values()) + { + v+=i; + } + + for(String i : weights.k()) + { + weights.put(i, weights.get(i) / v); + } + + sender.sendMessage("Total: " + C.BOLD + C.WHITE + Form.duration(masterWallClock, 0)); + + for(String i : totals.k()) + { + sender.sendMessage(" Engine " + C.UNDERLINE + C.GREEN + i + C.RESET + ": " + C.BOLD + C.WHITE + Form.duration(totals.get(i), 0)); + } + + sender.sendMessage("Details: "); + + for(String i : weights.sortKNumber().reverse()) + { + String befb = C.UNDERLINE +""+ C.GREEN + "" + i.split("\\Q[\\E")[0] + C.RESET + C.GRAY + "["; + String num = C.GOLD + i.split("\\Q[\\E")[1].split("]")[0] + C.RESET + C.GRAY + "]."; + String afb = C.ITALIC +""+ C.AQUA + i.split("\\Q]\\E")[1].substring(1) + C.RESET + C.GRAY; + + sender.sendMessage(" " + befb + num + afb + ": " + C.BOLD + C.WHITE + Form.pc(weights.get(i), 0)); + } + } + private File getEngineMetadataFile() { return new File(world.getWorldFolder(), "iris/engine-metadata.json"); } @@ -123,6 +196,7 @@ public class IrisEngineCompound implements EngineCompound { @Override public void generate(int x, int z, Hunk blocks, Hunk biomes) { + PrecisionStopwatch p = PrecisionStopwatch.start(); if(engines.length == 1 && !getEngine(0).getTarget().isInverted()) { engines[0].generate(x, z, blocks, biomes); @@ -166,8 +240,9 @@ public class IrisEngineCompound implements EngineCompound { insert[i].run(); } } - } + wallClock.put(p.getMilliseconds()); + } @Override public int getSize() { @@ -194,4 +269,12 @@ public class IrisEngineCompound implements EngineCompound { public boolean isFailing() { return false; } + + @Override + public void hotload() { + for(int i = 0; i < getSize(); i++) + { + getEngine(i).hotload(); + } + } } diff --git a/src/main/java/com/volmit/iris/generator/actuator/IrisBiomeActuator.java b/src/main/java/com/volmit/iris/generator/actuator/IrisBiomeActuator.java index 36c31abad..b93ac8651 100644 --- a/src/main/java/com/volmit/iris/generator/actuator/IrisBiomeActuator.java +++ b/src/main/java/com/volmit/iris/generator/actuator/IrisBiomeActuator.java @@ -3,6 +3,7 @@ package com.volmit.iris.generator.actuator; import com.volmit.iris.scaffold.engine.Engine; import com.volmit.iris.scaffold.engine.EngineAssignedActuator; import com.volmit.iris.scaffold.hunk.Hunk; +import com.volmit.iris.util.PrecisionStopwatch; import org.bukkit.block.Biome; public class IrisBiomeActuator extends EngineAssignedActuator @@ -13,6 +14,7 @@ public class IrisBiomeActuator extends EngineAssignedActuator @Override public void onActuate(int x, int z, Hunk h) { + PrecisionStopwatch p = PrecisionStopwatch.start(); int i,zf; Biome v; @@ -28,5 +30,6 @@ public class IrisBiomeActuator extends EngineAssignedActuator } } } + getEngine().getMetrics().getBiome().put(p.getMilliseconds()); } } diff --git a/src/main/java/com/volmit/iris/generator/actuator/IrisDecorantActuator.java b/src/main/java/com/volmit/iris/generator/actuator/IrisDecorantActuator.java index 7e8066921..3b9af576a 100644 --- a/src/main/java/com/volmit/iris/generator/actuator/IrisDecorantActuator.java +++ b/src/main/java/com/volmit/iris/generator/actuator/IrisDecorantActuator.java @@ -1,6 +1,7 @@ package com.volmit.iris.generator.actuator; import com.volmit.iris.object.IrisBiome; +import com.volmit.iris.util.PrecisionStopwatch; import com.volmit.iris.util.RNG; import com.volmit.iris.generator.decorator.IrisCeilingDecorator; import com.volmit.iris.generator.decorator.IrisSeaSurfaceDecorator; @@ -47,6 +48,7 @@ public class IrisDecorantActuator extends EngineAssignedActuator return; } + PrecisionStopwatch p = PrecisionStopwatch.start(); boolean solid; int emptyFor = 0; int lastSolid = 0; @@ -108,6 +110,8 @@ public class IrisDecorantActuator extends EngineAssignedActuator } } } + + getEngine().getMetrics().getDecoration().put(p.getMilliseconds()); } private boolean shouldRayDecorate() diff --git a/src/main/java/com/volmit/iris/generator/actuator/IrisTerrainActuator.java b/src/main/java/com/volmit/iris/generator/actuator/IrisTerrainActuator.java index 8f50c8912..6f81406cd 100644 --- a/src/main/java/com/volmit/iris/generator/actuator/IrisTerrainActuator.java +++ b/src/main/java/com/volmit/iris/generator/actuator/IrisTerrainActuator.java @@ -2,6 +2,7 @@ package com.volmit.iris.generator.actuator; import com.volmit.iris.object.IrisBiome; import com.volmit.iris.util.KList; +import com.volmit.iris.util.PrecisionStopwatch; import com.volmit.iris.util.RNG; import com.volmit.iris.scaffold.engine.Engine; import com.volmit.iris.scaffold.engine.EngineAssignedActuator; @@ -27,6 +28,7 @@ public class IrisTerrainActuator extends EngineAssignedActuator @Override public void onActuate(int x, int z, Hunk h) { + PrecisionStopwatch p = PrecisionStopwatch.start(); int i, zf, depth, realX, realZ, hf, he, b; IrisBiome biome; KList blocks; @@ -86,5 +88,7 @@ public class IrisTerrainActuator extends EngineAssignedActuator } } } + + getEngine().getMetrics().getTerrain().put(p.getMilliseconds()); } } diff --git a/src/main/java/com/volmit/iris/generator/modifier/IrisCaveModifier.java b/src/main/java/com/volmit/iris/generator/modifier/IrisCaveModifier.java index e1149ef7f..986827441 100644 --- a/src/main/java/com/volmit/iris/generator/modifier/IrisCaveModifier.java +++ b/src/main/java/com/volmit/iris/generator/modifier/IrisCaveModifier.java @@ -3,10 +3,7 @@ package com.volmit.iris.generator.modifier; import com.volmit.iris.generator.noise.FastNoiseDouble; import com.volmit.iris.object.IrisBiome; import com.volmit.iris.object.IrisCaveLayer; -import com.volmit.iris.util.B; -import com.volmit.iris.util.CaveResult; -import com.volmit.iris.util.KList; -import com.volmit.iris.util.RNG; +import com.volmit.iris.util.*; import com.volmit.iris.scaffold.engine.Engine; import com.volmit.iris.scaffold.engine.EngineAssignedModifier; import com.volmit.iris.scaffold.hunk.Hunk; @@ -31,6 +28,12 @@ public class IrisCaveModifier extends EngineAssignedModifier @Override public void onModify(int x, int z, Hunk a) { + if(!getDimension().isCaves()) + { + return; + } + + PrecisionStopwatch p = PrecisionStopwatch.start(); for(int i = 0; i < a.getWidth(); i++) { for(int j = 0; j < a.getDepth(); j++) @@ -71,6 +74,8 @@ public class IrisCaveModifier extends EngineAssignedModifier } } }; + + getEngine().getMetrics().getCave().put(p.getMilliseconds()); } public KList genCaves(double wxx, double wzz, int x, int z, Hunk data) diff --git a/src/main/java/com/volmit/iris/generator/modifier/IrisDepositModifier.java b/src/main/java/com/volmit/iris/generator/modifier/IrisDepositModifier.java index f514c0925..c4562ef74 100644 --- a/src/main/java/com/volmit/iris/generator/modifier/IrisDepositModifier.java +++ b/src/main/java/com/volmit/iris/generator/modifier/IrisDepositModifier.java @@ -4,11 +4,12 @@ import com.volmit.iris.object.IrisBiome; import com.volmit.iris.object.IrisDepositGenerator; import com.volmit.iris.object.IrisObject; import com.volmit.iris.object.IrisRegion; -import com.volmit.iris.util.HeightMap; -import com.volmit.iris.util.RNG; import com.volmit.iris.scaffold.engine.Engine; import com.volmit.iris.scaffold.engine.EngineAssignedModifier; import com.volmit.iris.scaffold.hunk.Hunk; +import com.volmit.iris.util.HeightMap; +import com.volmit.iris.util.PrecisionStopwatch; +import com.volmit.iris.util.RNG; import org.bukkit.block.data.BlockData; import org.bukkit.util.BlockVector; @@ -21,7 +22,9 @@ public class IrisDepositModifier extends EngineAssignedModifier { @Override public void onModify(int x, int z, Hunk output) { + PrecisionStopwatch p = PrecisionStopwatch.start(); generateDeposits(rng, output, Math.floorDiv(x, 16), Math.floorDiv(z, 16)); + getEngine().getMetrics().getDeposit().put(p.getMilliseconds()); } public void generateDeposits(RNG rx, Hunk terrain, int x, int z) diff --git a/src/main/java/com/volmit/iris/generator/modifier/IrisPostModifier.java b/src/main/java/com/volmit/iris/generator/modifier/IrisPostModifier.java index 37d46b727..24209a38d 100644 --- a/src/main/java/com/volmit/iris/generator/modifier/IrisPostModifier.java +++ b/src/main/java/com/volmit/iris/generator/modifier/IrisPostModifier.java @@ -3,6 +3,7 @@ package com.volmit.iris.generator.modifier; import com.volmit.iris.object.*; import com.volmit.iris.util.B; import com.volmit.iris.util.CaveResult; +import com.volmit.iris.util.PrecisionStopwatch; import com.volmit.iris.util.RNG; import com.volmit.iris.scaffold.engine.Engine; import com.volmit.iris.scaffold.engine.EngineAssignedModifier; @@ -25,6 +26,7 @@ public class IrisPostModifier extends EngineAssignedModifier { @Override public void onModify(int x, int z, Hunk output) { + PrecisionStopwatch p = PrecisionStopwatch.start(); for(int i = 0; i < output.getWidth(); i++) { for(int j = 0; j < output.getDepth(); j++) @@ -32,6 +34,7 @@ public class IrisPostModifier extends EngineAssignedModifier { post(i, j, output, i+x, j+z); } } + getEngine().getMetrics().getPost().put(p.getMilliseconds()); } private void post(int currentPostX, int currentPostZ, Hunk currentData, int x, int z) { diff --git a/src/main/java/com/volmit/iris/generator/modifier/IrisRavineModifier.java b/src/main/java/com/volmit/iris/generator/modifier/IrisRavineModifier.java index e8b69662d..6a6af968b 100644 --- a/src/main/java/com/volmit/iris/generator/modifier/IrisRavineModifier.java +++ b/src/main/java/com/volmit/iris/generator/modifier/IrisRavineModifier.java @@ -23,7 +23,9 @@ public class IrisRavineModifier extends EngineAssignedModifier { @Override public void onModify(int x, int z, Hunk output) { + PrecisionStopwatch p = PrecisionStopwatch.start(); generateRavines(rng, Math.floorDiv(x, 16), Math.floorDiv(z, 16), output); + getEngine().getMetrics().getRavine().put(p.getMilliseconds()); } private void set(Hunk pos, int x, int y, int z, BlockData b) diff --git a/src/main/java/com/volmit/iris/manager/IrisDataManager.java b/src/main/java/com/volmit/iris/manager/IrisDataManager.java index 2b8259cf8..2af9d3cba 100644 --- a/src/main/java/com/volmit/iris/manager/IrisDataManager.java +++ b/src/main/java/com/volmit/iris/manager/IrisDataManager.java @@ -2,7 +2,6 @@ package com.volmit.iris.manager; import com.volmit.iris.Iris; import com.volmit.iris.object.*; -import com.volmit.iris.util.KMap; import com.volmit.iris.util.ObjectResourceLoader; import com.volmit.iris.util.RNG; import com.volmit.iris.util.ResourceLoader; @@ -14,7 +13,6 @@ import java.util.function.Function; @Data public class IrisDataManager { - public static final KMap managers = new KMap<>(); private ResourceLoader biomeLoader; private ResourceLoader lootLoader; private ResourceLoader regionLoader; @@ -39,17 +37,11 @@ public class IrisDataManager this.id = RNG.r.imax(); closed = false; hotloaded(); - - if(!oneshot) - { - managers.put(id, this); - } } public void close() { closed = true; - managers.remove(id); dump(); this.lootLoader = null; this.entityLoader = null; @@ -62,23 +54,6 @@ public class IrisDataManager this.objectLoader = null; } - public static void dumpManagers() - { - for(IrisDataManager i : managers.v()) - { - Iris.warn(i.getId() + " @ " + i.getDataFolder().getAbsolutePath()); - printData(i.lootLoader); - printData(i.entityLoader); - printData(i.regionLoader); - printData(i.biomeLoader); - printData(i.dimensionLoader); - printData(i.structureLoader); - printData(i.generatorLoader); - printData(i.blockLoader); - printData(i.objectLoader); - } - } - private static void printData(ResourceLoader rl) { Iris.warn(" " + rl.getResourceTypeName() + " @ /" + rl.getFolderName() + ": Cache=" + rl.getLoadCache().size() + " Folders=" + rl.getFolders().size()); diff --git a/src/main/java/com/volmit/iris/manager/command/CommandIris.java b/src/main/java/com/volmit/iris/manager/command/CommandIris.java index f055e731a..8d869422c 100644 --- a/src/main/java/com/volmit/iris/manager/command/CommandIris.java +++ b/src/main/java/com/volmit/iris/manager/command/CommandIris.java @@ -35,15 +35,6 @@ public class CommandIris extends MortarCommand @Command private CommandIrisMetrics metrics; - @Command - private CommandIrisCTC ctc; - - @Command - private CommandIrisLMM lmm; - - @Command - private CommandIrisIDM idm; - @Command private CommandIrisPregen pregen; diff --git a/src/main/java/com/volmit/iris/manager/command/CommandIrisCTC.java b/src/main/java/com/volmit/iris/manager/command/CommandIrisCTC.java deleted file mode 100644 index 82e0c5e80..000000000 --- a/src/main/java/com/volmit/iris/manager/command/CommandIrisCTC.java +++ /dev/null @@ -1,71 +0,0 @@ -package com.volmit.iris.manager.command; - -import com.volmit.iris.Iris; -import com.volmit.iris.scaffold.IrisWorlds; -import com.volmit.iris.scaffold.engine.IrisAccess; -import com.volmit.iris.util.KList; -import com.volmit.iris.util.MortarCommand; -import com.volmit.iris.util.MortarSender; -import org.bukkit.World; -import org.bukkit.entity.Player; - -public class CommandIrisCTC extends MortarCommand -{ - public CommandIrisCTC() - { - super("ctc", "threads", "thread"); - setDescription("Change generator thread count"); - requiresPermission(Iris.perm.studio); - setCategory("World"); - } - - - @Override - public void addTabOptions(MortarSender sender, String[] args, KList list) { - if(args.length == 0) - { - list.qadd("4").qadd("8").qadd("12").qadd("16").qadd("18").qadd("24").qadd("32"); - } - } - @Override - public boolean handle(MortarSender sender, String[] args) - { - if(sender.isPlayer()) - { - Player p = sender.player(); - World world = p.getWorld(); - - if(!IrisWorlds.isIrisWorld(world)) - { - sender.sendMessage("You must be in an iris world."); - return true; - } - IrisAccess g = IrisWorlds.access(world); - - if(args.length == 0){ - sender.sendMessage("Current threads: " + g.getThreadCount()); - sender.sendMessage("You can change the treadcount with /iris ctc "); - return true; - } - - - int m = Math.min(Math.max(Integer.valueOf(args[0]), 2), 256); - g.changeThreadCount(m); - sender.sendMessage("Thread count changed to " + m); - return true; - } - - else - { - sender.sendMessage("Players only."); - } - - return true; - } - - @Override - protected String getArgsUsage() - { - return "[thread-count]"; - } -} diff --git a/src/main/java/com/volmit/iris/manager/command/CommandIrisIDM.java b/src/main/java/com/volmit/iris/manager/command/CommandIrisIDM.java deleted file mode 100644 index 25832a9f2..000000000 --- a/src/main/java/com/volmit/iris/manager/command/CommandIrisIDM.java +++ /dev/null @@ -1,43 +0,0 @@ -package com.volmit.iris.manager.command; - -import com.volmit.iris.Iris; -import com.volmit.iris.manager.IrisDataManager; -import com.volmit.iris.util.KList; -import com.volmit.iris.util.MortarCommand; -import com.volmit.iris.util.MortarSender; - -public class CommandIrisIDM extends MortarCommand -{ - public CommandIrisIDM() - { - super("idm"); - setDescription("Diagnostics for Iris Data Managers"); - requiresPermission(Iris.perm.studio); - setCategory("World"); - } - - - @Override - public void addTabOptions(MortarSender sender, String[] args, KList list) { - - } - @Override - public boolean handle(MortarSender sender, String[] args) - { - if(sender.isPlayer()) - { - sender.sendMessage("Use this in the console."); - return true; - } - - sender.sendMessage("Total Managers: " + IrisDataManager.managers.size()); - IrisDataManager.dumpManagers(); - return true; - } - - @Override - protected String getArgsUsage() - { - return ""; - } -} diff --git a/src/main/java/com/volmit/iris/manager/command/CommandIrisLMM.java b/src/main/java/com/volmit/iris/manager/command/CommandIrisLMM.java deleted file mode 100644 index e7c481016..000000000 --- a/src/main/java/com/volmit/iris/manager/command/CommandIrisLMM.java +++ /dev/null @@ -1,36 +0,0 @@ -package com.volmit.iris.manager.command; - -import com.volmit.iris.Iris; -import com.volmit.iris.util.KList; -import com.volmit.iris.util.MortarCommand; -import com.volmit.iris.util.MortarSender; - -public class CommandIrisLMM extends MortarCommand -{ - public CommandIrisLMM() - { - super("lmm"); - setDescription("Toggle Low Memory Mode"); - requiresPermission(Iris.perm.studio); - setCategory("World"); - } - - - @Override - public void addTabOptions(MortarSender sender, String[] args, KList list) { - - } - @Override - public boolean handle(MortarSender sender, String[] args) - { - Iris.lowMemoryMode = !Iris.lowMemoryMode; - sender.sendMessage("Low Memory Mode is " + (Iris.lowMemoryMode ? "On" : "Off")); - return true; - } - - @Override - protected String getArgsUsage() - { - return ""; - } -} diff --git a/src/main/java/com/volmit/iris/manager/command/CommandIrisMetrics.java b/src/main/java/com/volmit/iris/manager/command/CommandIrisMetrics.java index 93ee98b03..148977616 100644 --- a/src/main/java/com/volmit/iris/manager/command/CommandIrisMetrics.java +++ b/src/main/java/com/volmit/iris/manager/command/CommandIrisMetrics.java @@ -36,7 +36,16 @@ public class CommandIrisMetrics extends MortarCommand } IrisAccess g = IrisWorlds.access(world); - // TODO: METRICS + + try + { + g.printMetrics(sender); + } + + catch(Throwable e) + { + sender.sendMessage("You must be in an iris world."); + } return true; } diff --git a/src/main/java/com/volmit/iris/manager/command/CommandIrisStudio.java b/src/main/java/com/volmit/iris/manager/command/CommandIrisStudio.java index 9c6366adf..89ea13376 100644 --- a/src/main/java/com/volmit/iris/manager/command/CommandIrisStudio.java +++ b/src/main/java/com/volmit/iris/manager/command/CommandIrisStudio.java @@ -27,8 +27,8 @@ public class CommandIrisStudio extends MortarCommand @Command private CommandIrisStudioUpdate update; - @Command - private CommandIrisStudioMap map; + //@Command + //private CommandIrisStudioMap map; @Command private CommandIrisStudioGoto got0; diff --git a/src/main/java/com/volmit/iris/manager/command/CommandIrisStudioMap.java b/src/main/java/com/volmit/iris/manager/command/CommandIrisStudioMap.java index 51d855ecf..35b070a68 100644 --- a/src/main/java/com/volmit/iris/manager/command/CommandIrisStudioMap.java +++ b/src/main/java/com/volmit/iris/manager/command/CommandIrisStudioMap.java @@ -2,6 +2,7 @@ package com.volmit.iris.manager.command; import com.volmit.iris.Iris; import com.volmit.iris.IrisSettings; +import com.volmit.iris.manager.gui.IrisVision; import com.volmit.iris.scaffold.engine.IrisAccess; import com.volmit.iris.util.KList; import com.volmit.iris.util.MortarCommand; @@ -38,8 +39,8 @@ public class CommandIrisStudioMap extends MortarCommand } IrisAccess g = Iris.proj.getActiveProject().getActiveProvider(); - // IrisVision.launch(g); - sender.sendMessage("NYI: Opening Map!"); + IrisVision.launch(g, 0); + sender.sendMessage("Opening Map!"); return true; } diff --git a/src/main/java/com/volmit/iris/manager/gui/IrisVision.java b/src/main/java/com/volmit/iris/manager/gui/IrisVision.java index 33f868f70..7c409bf50 100644 --- a/src/main/java/com/volmit/iris/manager/gui/IrisVision.java +++ b/src/main/java/com/volmit/iris/manager/gui/IrisVision.java @@ -1,7 +1,7 @@ package com.volmit.iris.manager.gui; import com.volmit.iris.Iris; -import com.volmit.iris.scaffold.engine.GeneratorAccess; +import com.volmit.iris.scaffold.engine.IrisAccess; import com.volmit.iris.util.*; import javax.imageio.ImageIO; @@ -35,7 +35,6 @@ public class IrisVision extends JPanel implements MouseWheelListener private double oz = 0; private double oxp = 0; private double ozp = 0; - private short lid = -1; double tfps = 240D; private RollingSequence rs = new RollingSequence(512); private O m = new O<>(); @@ -131,7 +130,6 @@ public class IrisVision extends JPanel implements MouseWheelListener working.add(key); double mk = mscale; double mkd = scale; - short l = lid; e.submit(() -> { PrecisionStopwatch ps = PrecisionStopwatch.start(); @@ -139,7 +137,7 @@ public class IrisVision extends JPanel implements MouseWheelListener rs.put(ps.getMilliseconds()); working.remove(key); - if(mk == mscale && mkd == scale && lid == l) + if(mk == mscale && mkd == scale) { positions.put(key, b); } @@ -162,7 +160,6 @@ public class IrisVision extends JPanel implements MouseWheelListener workingfast.add(key); double mk = mscale; double mkd = scale; - short l = lid; eh.submit(() -> { PrecisionStopwatch ps = PrecisionStopwatch.start(); @@ -170,7 +167,7 @@ public class IrisVision extends JPanel implements MouseWheelListener rs.put(ps.getMilliseconds()); workingfast.remove(key); - if(mk == mscale && mkd == scale && lid == l) + if(mk == mscale && mkd == scale) { fastpositions.put(key, b); } @@ -202,17 +199,6 @@ public class IrisVision extends JPanel implements MouseWheelListener ozp += Math.abs(ozp - oz) * 0.36; } - // TODO: DETECT HOTLOADS - if(false) - { - working.clear(); - workingfast.clear(); - positions.clear(); - fastpositions.clear(); - //TODO: lid = Iris.proj.getActiveProject().getActiveProvider().getCacheID(); - Iris.info("Hotloading Vision"); - } - PrecisionStopwatch p = PrecisionStopwatch.start(); Graphics2D g = (Graphics2D) gx; w = getWidth(); @@ -293,14 +279,13 @@ public class IrisVision extends JPanel implements MouseWheelListener }); } - private static void createAndShowGUI(Renderer r, short s) + private static void createAndShowGUI(Renderer r, int s) { JFrame frame = new JFrame("Vision"); IrisVision nv = new IrisVision(); nv.renderer = new IrisRenderer(r); frame.add(nv); frame.setSize(1440, 820); - nv.lid = s; frame.setVisible(true); File file = Iris.getCached("Iris Icon", "https://raw.githubusercontent.com/VolmitSoftware/Iris/master/icon.png"); @@ -318,11 +303,10 @@ public class IrisVision extends JPanel implements MouseWheelListener } } - public static void launch(GeneratorAccess g) - { + public static void launch(IrisAccess g, int i) { J.a(() -> { - //createAndShowGUI(g.createRenderer(), g.getCacheID()); + createAndShowGUI((x, z) -> g.getEngineAccess(i).draw(x, z), i); }); } @@ -334,7 +318,7 @@ public class IrisVision extends JPanel implements MouseWheelListener return; } - Iris.info("BPP: " + (mscale) + " BW: " + (w * mscale)); + Iris.info("Blocks/Pixel: " + (mscale) + ", Blocks Wide: " + (w * mscale)); positions.clear(); fastpositions.clear(); mscale = mscale + ((0.044 * mscale) * notches); diff --git a/src/main/java/com/volmit/iris/object/IrisBiome.java b/src/main/java/com/volmit/iris/object/IrisBiome.java index dccc49ed2..20255baac 100644 --- a/src/main/java/com/volmit/iris/object/IrisBiome.java +++ b/src/main/java/com/volmit/iris/object/IrisBiome.java @@ -85,8 +85,8 @@ public class IrisBiome extends IrisRegistrant implements IRare private int rarity = 1; @DontObfuscate - @Desc("A debug color for visualizing this biome with a color. I.e. #F13AF5") - private String debugColor = ""; + @Desc("A color for visualizing this biome with a color. I.e. #F13AF5. This will show up on the map.") + private IrisColor color = null; @Required @DontObfuscate @@ -295,29 +295,6 @@ public class IrisBiome extends IrisRegistrant implements IRare }); } - public Color getCachedColor() - { - return cacheColor.aquire(() -> - { - if(getDebugColor() == null || getDebugColor().isEmpty()) - { - return null; - } - - try - { - return Color.decode(getDebugColor()); - } - - catch(Throwable e) - { - - } - - return null; - }); - } - public double getHeight(IrisAccess xg, double x, double z, long seed) { double height = 0; diff --git a/src/main/java/com/volmit/iris/object/IrisColor.java b/src/main/java/com/volmit/iris/object/IrisColor.java new file mode 100644 index 000000000..c990b6c8e --- /dev/null +++ b/src/main/java/com/volmit/iris/object/IrisColor.java @@ -0,0 +1,97 @@ +package com.volmit.iris.object; + +import com.volmit.iris.scaffold.cache.AtomicCache; +import com.volmit.iris.util.Desc; +import com.volmit.iris.util.DontObfuscate; +import com.volmit.iris.util.MaxNumber; +import com.volmit.iris.util.MinNumber; +import lombok.Data; +import lombok.NoArgsConstructor; +import lombok.experimental.Accessors; + +import java.awt.*; + +@Accessors(chain = true) +@NoArgsConstructor +@Desc("Represents a color") +@Data +public class IrisColor +{ + @DontObfuscate + @MaxNumber(7) + @MinNumber(6) + @Desc("Pass in a 6 digit hexadecimal color to fill R G and B values. You can also include the # symbol, but it's not required.") + private String hex = null; + + @DontObfuscate + @MaxNumber(255) + @MinNumber(0) + @Desc("Represents the red channel. Only define this if you are not defining the hex value.") + private int red = 0; + + @DontObfuscate + @MaxNumber(255) + @MinNumber(0) + @Desc("Represents the green channel. Only define this if you are not defining the hex value.") + private int green = 0; + + @DontObfuscate + @MaxNumber(255) + @MinNumber(0) + @Desc("Represents the blue channel. Only define this if you are not defining the hex value.") + private int blue = 0; + + private final transient AtomicCache color = new AtomicCache<>(); + + public Color getColor() + { + return color.aquire(() -> { + if(hex != null) + { + String v = (hex.startsWith("#") ? hex : "#" + hex).trim(); + try + { + return Color.decode(v); + } + + catch(Throwable e) + { + + } + } + + return new Color(red, green, blue); + }); + } + + public org.bukkit.Color getBukkitColor() + { + return org.bukkit.Color.fromRGB(getColor().getRGB()); + } + + public static Color blend(Color... c) { + if (c == null || c.length <= 0) { + return null; + } + float ratio = 1f / ((float) c.length); + + int a = 0; + int r = 0; + int g = 0; + int b = 0; + + for (int i = 0; i < c.length; i++) { + int rgb = c[i].getRGB(); + int a1 = (rgb >> 24 & 0xff); + int r1 = ((rgb & 0xff0000) >> 16); + int g1 = ((rgb & 0xff00) >> 8); + int b1 = (rgb & 0xff); + a += ((int) a1 * ratio); + r += ((int) r1 * ratio); + g += ((int) g1 * ratio); + b += ((int) b1 * ratio); + } + + return new Color(a << 24 | r << 16 | g << 8 | b); + } +} diff --git a/src/main/java/com/volmit/iris/object/IrisRegion.java b/src/main/java/com/volmit/iris/object/IrisRegion.java index f6e9c655e..269a9b336 100644 --- a/src/main/java/com/volmit/iris/object/IrisRegion.java +++ b/src/main/java/com/volmit/iris/object/IrisRegion.java @@ -18,7 +18,6 @@ import lombok.experimental.Accessors; @EqualsAndHashCode(callSuper = false) public class IrisRegion extends IrisRegistrant implements IRare { - @MinNumber(2) @Required @DontObfuscate @@ -211,6 +210,10 @@ public class IrisRegion extends IrisRegistrant implements IRare @Desc("Generate rivers in this region") private double riverThickness = 0.1; + @DontObfuscate + @Desc("A color for visualizing this region with a color. I.e. #F13AF5. This will show up on the map.") + private IrisColor color = null; + private final transient AtomicCache> surfaceObjectsCache = new AtomicCache<>(); private final transient AtomicCache> carveObjectsCache = new AtomicCache<>(); private final transient AtomicCache> cacheRidge = new AtomicCache<>(); 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 b79af1cdb..3313c81f4 100644 --- a/src/main/java/com/volmit/iris/scaffold/engine/Engine.java +++ b/src/main/java/com/volmit/iris/scaffold/engine/Engine.java @@ -1,15 +1,14 @@ package com.volmit.iris.scaffold.engine; import com.volmit.iris.manager.IrisDataManager; +import com.volmit.iris.manager.gui.Renderer; import com.volmit.iris.object.*; import com.volmit.iris.scaffold.cache.Cache; import com.volmit.iris.scaffold.data.DataProvider; import com.volmit.iris.scaffold.hunk.Hunk; import com.volmit.iris.scaffold.parallax.ParallaxAccess; import com.volmit.iris.scaffold.parallel.MultiBurst; -import com.volmit.iris.util.B; -import com.volmit.iris.util.KList; -import com.volmit.iris.util.RNG; +import com.volmit.iris.util.*; import org.bukkit.Chunk; import org.bukkit.Material; import org.bukkit.World; @@ -20,9 +19,10 @@ import org.bukkit.inventory.Inventory; import org.bukkit.inventory.InventoryHolder; import org.bukkit.inventory.ItemStack; +import java.awt.*; import java.util.Arrays; -public interface Engine extends DataProvider, Fallible, GeneratorAccess, LootProvider, BlockUpdater { +public interface Engine extends DataProvider, Fallible, GeneratorAccess, LootProvider, BlockUpdater, Renderer, Hotloadable { public void close(); public boolean isClosed(); @@ -49,6 +49,8 @@ public interface Engine extends DataProvider, Fallible, GeneratorAccess, LootPro public void generate(int x, int z, Hunk blocks, Hunk biomes); + public EngineMetrics getMetrics(); + default void save() { getParallax().saveAll(); @@ -89,6 +91,21 @@ public interface Engine extends DataProvider, Fallible, GeneratorAccess, LootPro return getTarget().getParallaxWorld(); } + public default Color draw(double x, double z) + { + IrisRegion region = getRegion((int)x, (int)z); + IrisBiome biome = getSurfaceBiome((int)x, (int)z); + int height = getHeight((int) x, (int) z); + double heightFactor = M.lerpInverse(0, getHeight(), height); + IrisColor irc = region.getColor(); + IrisColor ibc = biome.getColor(); + Color rc = irc != null ? irc.getColor() : Color.GREEN.darker(); + Color bc = ibc != null ? ibc.getColor() : biome.isAquatic() ? Color.BLUE : Color.YELLOW; + Color f = IrisColor.blend(rc, bc, bc, Color.getHSBColor(0, 0, (float)heightFactor)); + + return f; + } + @Override public default IrisRegion getRegion(int x, int z) { return getFramework().getComplex().getRegionStream().get(x, z); @@ -136,6 +153,7 @@ public interface Engine extends DataProvider, Fallible, GeneratorAccess, LootPro @Override public default void updateChunk(Chunk c) { + PrecisionStopwatch p = PrecisionStopwatch.start(); if(getParallax().getMetaR(c.getX(), c.getZ()).isUpdates()) { Hunk b = getParallax().getUpdatesR(c.getX(), c.getZ()); @@ -155,6 +173,8 @@ public interface Engine extends DataProvider, Fallible, GeneratorAccess, LootPro } }); } + + getMetrics().getUpdates().put(p.getMilliseconds()); } public default void updateLighting(int x, int y, int z, Chunk c) 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 47df70d3c..f8f9e7490 100644 --- a/src/main/java/com/volmit/iris/scaffold/engine/EngineCompositeGenerator.java +++ b/src/main/java/com/volmit/iris/scaffold/engine/EngineCompositeGenerator.java @@ -12,6 +12,7 @@ import com.volmit.iris.util.*; import org.bukkit.*; import org.bukkit.block.Biome; import org.bukkit.block.data.BlockData; +import org.bukkit.command.CommandSender; import org.bukkit.generator.BlockPopulator; import org.bukkit.generator.ChunkGenerator; import org.bukkit.material.MaterialData; @@ -250,6 +251,11 @@ public class EngineCompositeGenerator extends ChunkGenerator implements IrisAcce return generated; } + @Override + public void printMetrics(CommandSender sender) { + getComposite().printMetrics(sender); + } + @Override public IrisBiome getBiome(int x, int y, int z) { // TODO: REMOVE GET ABS BIOME OR THIS ONE 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 c126f3712..44db020c2 100644 --- a/src/main/java/com/volmit/iris/scaffold/engine/EngineCompound.java +++ b/src/main/java/com/volmit/iris/scaffold/engine/EngineCompound.java @@ -2,17 +2,17 @@ package com.volmit.iris.scaffold.engine; import com.volmit.iris.manager.IrisDataManager; import com.volmit.iris.object.IrisDimension; +import com.volmit.iris.scaffold.hunk.Hunk; +import com.volmit.iris.scaffold.parallel.MultiBurst; import com.volmit.iris.util.KList; import org.bukkit.World; import org.bukkit.block.Biome; import org.bukkit.block.data.BlockData; +import org.bukkit.command.CommandSender; import org.bukkit.event.Listener; - -import com.volmit.iris.scaffold.hunk.Hunk; -import com.volmit.iris.scaffold.parallel.MultiBurst; import org.bukkit.generator.BlockPopulator; -public interface EngineCompound extends Listener +public interface EngineCompound extends Listener, Hotloadable { public IrisDimension getRootDimension(); @@ -20,6 +20,8 @@ public interface EngineCompound extends Listener public World getWorld(); + public void printMetrics(CommandSender sender); + public int getSize(); public Engine getEngine(int index); diff --git a/src/main/java/com/volmit/iris/scaffold/engine/EngineMetrics.java b/src/main/java/com/volmit/iris/scaffold/engine/EngineMetrics.java new file mode 100644 index 000000000..e8d75903d --- /dev/null +++ b/src/main/java/com/volmit/iris/scaffold/engine/EngineMetrics.java @@ -0,0 +1,51 @@ +package com.volmit.iris.scaffold.engine; + +import com.volmit.iris.util.AtomicRollingSequence; +import com.volmit.iris.util.KMap; +import lombok.Data; + +@Data +public class EngineMetrics { + private final AtomicRollingSequence total; + private final AtomicRollingSequence updates; + private final AtomicRollingSequence terrain; + private final AtomicRollingSequence biome; + private final AtomicRollingSequence parallax; + private final AtomicRollingSequence parallaxInsert; + private final AtomicRollingSequence post; + private final AtomicRollingSequence decoration; + private final AtomicRollingSequence cave; + private final AtomicRollingSequence ravine; + private final AtomicRollingSequence deposit; + + public EngineMetrics(int mem) + { + this.total = new AtomicRollingSequence(mem); + this.terrain = new AtomicRollingSequence(mem); + this.biome = new AtomicRollingSequence(mem); + this.parallax = new AtomicRollingSequence(mem); + this.parallaxInsert = new AtomicRollingSequence(mem); + this.post = new AtomicRollingSequence(mem); + this.decoration = new AtomicRollingSequence(mem); + this.updates = new AtomicRollingSequence(mem); + this.cave = new AtomicRollingSequence(mem); + this.ravine = new AtomicRollingSequence(mem); + this.deposit = new AtomicRollingSequence(mem); + } + + public KMap pull() { + KMap v = new KMap<>(); + v.put("terrain", terrain.getAverage()); + v.put("biome", biome.getAverage()); + v.put("parallax", parallax.getAverage()); + v.put("parallax.insert", parallaxInsert.getAverage()); + v.put("post", post.getAverage()); + v.put("decoration", decoration.getAverage()); + v.put("updates", updates.getAverage()); + v.put("cave", cave.getAverage()); + v.put("ravine", ravine.getAverage()); + v.put("deposit", deposit.getAverage()); + + return v; + } +} diff --git a/src/main/java/com/volmit/iris/scaffold/engine/EngineParallaxManager.java b/src/main/java/com/volmit/iris/scaffold/engine/EngineParallaxManager.java index 023096ced..b4ed9a754 100644 --- a/src/main/java/com/volmit/iris/scaffold/engine/EngineParallaxManager.java +++ b/src/main/java/com/volmit/iris/scaffold/engine/EngineParallaxManager.java @@ -73,9 +73,11 @@ public interface EngineParallaxManager extends DataProvider, IObjectPlacer default void insertParallax(int x, int z, Hunk data) { + PrecisionStopwatch p = PrecisionStopwatch.start(); ParallaxChunkMeta meta = getParallaxAccess().getMetaR(x>>4, z>>4); if(!meta.isObjects()) { + getEngine().getMetrics().getParallaxInsert().put(p.getMilliseconds()); return; } @@ -94,10 +96,13 @@ public interface EngineParallaxManager extends DataProvider, IObjectPlacer } } } + + getEngine().getMetrics().getParallaxInsert().put(p.getMilliseconds()); } default void generateParallaxArea(int x, int z) { + PrecisionStopwatch p = PrecisionStopwatch.start(); int s = (int) Math.ceil(getParallaxSize() / 2D); int j; BurstExecutor e = MultiBurst.burst.burst(getParallaxSize() * getParallaxSize()); @@ -114,8 +119,9 @@ public interface EngineParallaxManager extends DataProvider, IObjectPlacer } e.complete(); - getParallaxAccess().setChunkGenerated(x>>4, z>>4); + p.end(); + getEngine().getMetrics().getParallax().put(p.getMilliseconds()); } default void generateParallaxLayer(int x, int z) diff --git a/src/main/java/com/volmit/iris/scaffold/engine/GeneratorAccess.java b/src/main/java/com/volmit/iris/scaffold/engine/GeneratorAccess.java index 94d0db42c..c3f2cae32 100644 --- a/src/main/java/com/volmit/iris/scaffold/engine/GeneratorAccess.java +++ b/src/main/java/com/volmit/iris/scaffold/engine/GeneratorAccess.java @@ -1,13 +1,14 @@ package com.volmit.iris.scaffold.engine; import com.volmit.iris.manager.IrisDataManager; +import com.volmit.iris.manager.gui.Renderer; import com.volmit.iris.object.IrisBiome; import com.volmit.iris.object.IrisObjectPlacement; import com.volmit.iris.object.IrisRegion; import com.volmit.iris.scaffold.data.DataProvider; import com.volmit.iris.scaffold.parallax.ParallaxAccess; -public interface GeneratorAccess extends DataProvider +public interface GeneratorAccess extends DataProvider, Renderer { public IrisRegion getRegion(int x, int z); @@ -64,4 +65,6 @@ public interface GeneratorAccess extends DataProvider return new PlacedObject(null, getData().getObjectLoader().load(object), id, x, z); } + + public int getCacheID(); } 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 baa5b7fb3..70fdbd649 100644 --- a/src/main/java/com/volmit/iris/scaffold/engine/IrisAccess.java +++ b/src/main/java/com/volmit/iris/scaffold/engine/IrisAccess.java @@ -5,6 +5,7 @@ import com.volmit.iris.object.*; import com.volmit.iris.scaffold.data.DataProvider; import com.volmit.iris.util.*; import org.bukkit.Location; +import org.bukkit.command.CommandSender; import java.util.concurrent.atomic.AtomicBoolean; import java.util.concurrent.atomic.AtomicInteger; @@ -15,6 +16,8 @@ public interface IrisAccess extends Hotloadable, DataProvider { public int getGenerated(); + public void printMetrics(CommandSender sender); + public IrisBiome getBiome(int x, int y, int z); public IrisBiome getCaveBiome(int x, int y, int z); diff --git a/src/main/java/com/volmit/iris/util/AtomicAverage.java b/src/main/java/com/volmit/iris/util/AtomicAverage.java new file mode 100644 index 000000000..a13375273 --- /dev/null +++ b/src/main/java/com/volmit/iris/util/AtomicAverage.java @@ -0,0 +1,87 @@ +package com.volmit.iris.util; + +import com.google.common.util.concurrent.AtomicDoubleArray; + +/** + * Provides an incredibly fast averaging object. It swaps values from a sum + * using an array. Averages do not use any form of looping. An average of 10,000 + * entries is the same speed as an average with 5 entries. + * + * @author cyberpwn + * + */ +public class AtomicAverage { + protected AtomicDoubleArray values; + private double average; + private double lastSum; + private boolean dirty; + protected int cursor; + private boolean brandNew; + + /** + * Create an average holder + * + * @param size the size of entries to keep + */ + public AtomicAverage(int size) { + values = new AtomicDoubleArray(size); + DoubleArrayUtils.fill(values, 0); + brandNew = true; + average = 0; + cursor = 0; + lastSum = 0; + dirty = false; + } + + /** + * Put a value into the average (rolls over if full) + * + * @param i the value + */ + public void put(double i) { + + 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; + } + + /** + * Get the current average + * + * @return the average + */ + public double getAverage() { + if (dirty) { + calculateAverage(); + return getAverage(); + } + + return average; + } + + private void calculateAverage() { + average = lastSum / (double) size(); + dirty = false; + } + + public int size() + { + return values.length(); + } + + public boolean isDirty() + { + return dirty; + } +} diff --git a/src/main/java/com/volmit/iris/util/AtomicRollingSequence.java b/src/main/java/com/volmit/iris/util/AtomicRollingSequence.java new file mode 100644 index 000000000..de71cc6cb --- /dev/null +++ b/src/main/java/com/volmit/iris/util/AtomicRollingSequence.java @@ -0,0 +1,102 @@ +package com.volmit.iris.util; + +public class AtomicRollingSequence extends AtomicAverage +{ + private double median; + private double max; + private double min; + private boolean dirtyMedian; + private int dirtyExtremes; + private boolean precision; + + public AtomicRollingSequence(int size) + { + super(size); + median = 0; + min = 0; + max = 0; + setPrecision(false); + } + + public double addLast(int amt) + { + double f = 0; + + for(int i = 0; i < Math.min(values.length(), amt); i++) + { + f += values.get(i); + } + + return f; + } + + public void setPrecision(boolean p) + { + this.precision = p; + } + + public boolean isPrecision() + { + return precision; + } + + public double getMin() + { + if(dirtyExtremes > (isPrecision() ? 0 : values.length())) + { + resetExtremes(); + } + + return min; + } + + public double getMax() + { + if(dirtyExtremes > (isPrecision() ? 0 : values.length())) + { + resetExtremes(); + } + + return max; + } + + public double getMedian() + { + if(dirtyMedian) + { + recalculateMedian(); + } + + return median; + } + + private void recalculateMedian() + { + median = new KList().forceAdd(values).sort().middleValue(); + dirtyMedian = false; + } + + public void resetExtremes() + { + max = Integer.MIN_VALUE; + min = Integer.MAX_VALUE; + + for(int i = 0; i < values.length(); i++) + { + double v = values.get(i); + max = M.max(max, v); + min = M.min(min, v); + } + + dirtyExtremes = 0; + } + + public void put(double i) + { + super.put(i); + dirtyMedian = true; + dirtyExtremes++; + max = M.max(max, i); + min = M.min(min, i); + } +} diff --git a/src/main/java/com/volmit/iris/util/DoubleArrayUtils.java b/src/main/java/com/volmit/iris/util/DoubleArrayUtils.java index 016acee40..7e0172388 100644 --- a/src/main/java/com/volmit/iris/util/DoubleArrayUtils.java +++ b/src/main/java/com/volmit/iris/util/DoubleArrayUtils.java @@ -1,6 +1,10 @@ package com.volmit.iris.util; +import com.google.common.util.concurrent.AtomicDoubleArray; + +import java.util.Arrays; + public class DoubleArrayUtils { public static void shiftRight(double[] values, double push) @@ -21,9 +25,15 @@ public class DoubleArrayUtils public static void fill(double[] values, double value) { - for(int i = 0; i < values.length; i++) + Arrays.fill(values, value); + } + + public static void fill(AtomicDoubleArray values, double value) + { + for(int i = 0; i < values.length(); i++) { - values[i] = value; + values.set(i, value); } } + } diff --git a/src/main/java/com/volmit/iris/util/KList.java b/src/main/java/com/volmit/iris/util/KList.java index 6035b6b0e..bdddefc83 100644 --- a/src/main/java/com/volmit/iris/util/KList.java +++ b/src/main/java/com/volmit/iris/util/KList.java @@ -1,11 +1,8 @@ package com.volmit.iris.util; -import java.util.ArrayList; -import java.util.Collection; -import java.util.Collections; -import java.util.Enumeration; -import java.util.LinkedHashSet; -import java.util.List; +import com.google.common.util.concurrent.AtomicDoubleArray; + +import java.util.*; import java.util.function.Function; public class KList extends ArrayList implements List @@ -594,6 +591,17 @@ public class KList extends ArrayList implements List return this; } + @SuppressWarnings("unchecked") + public KList forceAdd(AtomicDoubleArray values) + { + for(int i = 0; i < values.length(); i++) + { + add((T) ((Object)values.get(i))); + } + + return this; + } + @SuppressWarnings("unchecked") public KList forceAdd(float[] values) {