mirror of
https://github.com/PolyhedralDev/Terra.git
synced 2025-07-04 00:45:57 +00:00
implement new profiler
This commit is contained in:
parent
f4716cb28f
commit
9c1a35f444
@ -4,16 +4,10 @@ import com.dfsek.terra.api.TerraPlugin;
|
|||||||
import com.dfsek.terra.api.command.CommandTemplate;
|
import com.dfsek.terra.api.command.CommandTemplate;
|
||||||
import com.dfsek.terra.api.command.annotation.Command;
|
import com.dfsek.terra.api.command.annotation.Command;
|
||||||
import com.dfsek.terra.api.command.annotation.type.DebugCommand;
|
import com.dfsek.terra.api.command.annotation.type.DebugCommand;
|
||||||
import com.dfsek.terra.api.command.annotation.type.PlayerCommand;
|
|
||||||
import com.dfsek.terra.api.command.annotation.type.WorldCommand;
|
|
||||||
import com.dfsek.terra.api.injection.annotations.Inject;
|
import com.dfsek.terra.api.injection.annotations.Inject;
|
||||||
import com.dfsek.terra.api.platform.CommandSender;
|
import com.dfsek.terra.api.platform.CommandSender;
|
||||||
import com.dfsek.terra.api.platform.entity.Player;
|
|
||||||
import com.dfsek.terra.world.TerraWorld;
|
|
||||||
|
|
||||||
@Command
|
@Command
|
||||||
@WorldCommand
|
|
||||||
@PlayerCommand
|
|
||||||
@DebugCommand
|
@DebugCommand
|
||||||
public class ProfileQueryCommand implements CommandTemplate {
|
public class ProfileQueryCommand implements CommandTemplate {
|
||||||
@Inject
|
@Inject
|
||||||
@ -21,8 +15,9 @@ public class ProfileQueryCommand implements CommandTemplate {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void execute(CommandSender sender) {
|
public void execute(CommandSender sender) {
|
||||||
Player player = (Player) sender;
|
StringBuilder data = new StringBuilder("Terra Profiler data dump: \n");
|
||||||
TerraWorld world = main.getWorld(player.getWorld());
|
main.getProfiler().getTimings().forEach((id, timings) -> data.append(id).append(": ").append(timings.toString()).append('\n'));
|
||||||
player.sendMessage(world.getProfiler().getResultsFormatted());
|
main.logger().info(data.toString());
|
||||||
|
sender.sendMessage("Profiler data dumped to console.");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -4,16 +4,10 @@ import com.dfsek.terra.api.TerraPlugin;
|
|||||||
import com.dfsek.terra.api.command.CommandTemplate;
|
import com.dfsek.terra.api.command.CommandTemplate;
|
||||||
import com.dfsek.terra.api.command.annotation.Command;
|
import com.dfsek.terra.api.command.annotation.Command;
|
||||||
import com.dfsek.terra.api.command.annotation.type.DebugCommand;
|
import com.dfsek.terra.api.command.annotation.type.DebugCommand;
|
||||||
import com.dfsek.terra.api.command.annotation.type.PlayerCommand;
|
|
||||||
import com.dfsek.terra.api.command.annotation.type.WorldCommand;
|
|
||||||
import com.dfsek.terra.api.injection.annotations.Inject;
|
import com.dfsek.terra.api.injection.annotations.Inject;
|
||||||
import com.dfsek.terra.api.platform.CommandSender;
|
import com.dfsek.terra.api.platform.CommandSender;
|
||||||
import com.dfsek.terra.api.platform.entity.Player;
|
|
||||||
import com.dfsek.terra.world.TerraWorld;
|
|
||||||
|
|
||||||
@Command
|
@Command
|
||||||
@WorldCommand
|
|
||||||
@PlayerCommand
|
|
||||||
@DebugCommand
|
@DebugCommand
|
||||||
public class ProfileResetCommand implements CommandTemplate {
|
public class ProfileResetCommand implements CommandTemplate {
|
||||||
@Inject
|
@Inject
|
||||||
@ -21,9 +15,7 @@ public class ProfileResetCommand implements CommandTemplate {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void execute(CommandSender sender) {
|
public void execute(CommandSender sender) {
|
||||||
Player player = (Player) sender;
|
main.getProfiler().reset();
|
||||||
TerraWorld world = main.getWorld(player.getWorld());
|
sender.sendMessage("Profiler reset.");
|
||||||
world.getProfiler().reset();
|
|
||||||
player.sendMessage("Profiler reset.");
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -4,16 +4,10 @@ import com.dfsek.terra.api.TerraPlugin;
|
|||||||
import com.dfsek.terra.api.command.CommandTemplate;
|
import com.dfsek.terra.api.command.CommandTemplate;
|
||||||
import com.dfsek.terra.api.command.annotation.Command;
|
import com.dfsek.terra.api.command.annotation.Command;
|
||||||
import com.dfsek.terra.api.command.annotation.type.DebugCommand;
|
import com.dfsek.terra.api.command.annotation.type.DebugCommand;
|
||||||
import com.dfsek.terra.api.command.annotation.type.PlayerCommand;
|
|
||||||
import com.dfsek.terra.api.command.annotation.type.WorldCommand;
|
|
||||||
import com.dfsek.terra.api.injection.annotations.Inject;
|
import com.dfsek.terra.api.injection.annotations.Inject;
|
||||||
import com.dfsek.terra.api.platform.CommandSender;
|
import com.dfsek.terra.api.platform.CommandSender;
|
||||||
import com.dfsek.terra.api.platform.entity.Player;
|
|
||||||
import com.dfsek.terra.world.TerraWorld;
|
|
||||||
|
|
||||||
@Command
|
@Command
|
||||||
@WorldCommand
|
|
||||||
@PlayerCommand
|
|
||||||
@DebugCommand
|
@DebugCommand
|
||||||
public class ProfileStartCommand implements CommandTemplate {
|
public class ProfileStartCommand implements CommandTemplate {
|
||||||
@Inject
|
@Inject
|
||||||
@ -21,9 +15,7 @@ public class ProfileStartCommand implements CommandTemplate {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void execute(CommandSender sender) {
|
public void execute(CommandSender sender) {
|
||||||
Player player = (Player) sender;
|
main.getProfiler().start();
|
||||||
TerraWorld world = main.getWorld(player.getWorld());
|
sender.sendMessage("Profiling enabled.");
|
||||||
world.getProfiler().setProfiling(true);
|
|
||||||
player.sendMessage("Profiling enabled.");
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -4,16 +4,10 @@ import com.dfsek.terra.api.TerraPlugin;
|
|||||||
import com.dfsek.terra.api.command.CommandTemplate;
|
import com.dfsek.terra.api.command.CommandTemplate;
|
||||||
import com.dfsek.terra.api.command.annotation.Command;
|
import com.dfsek.terra.api.command.annotation.Command;
|
||||||
import com.dfsek.terra.api.command.annotation.type.DebugCommand;
|
import com.dfsek.terra.api.command.annotation.type.DebugCommand;
|
||||||
import com.dfsek.terra.api.command.annotation.type.PlayerCommand;
|
|
||||||
import com.dfsek.terra.api.command.annotation.type.WorldCommand;
|
|
||||||
import com.dfsek.terra.api.injection.annotations.Inject;
|
import com.dfsek.terra.api.injection.annotations.Inject;
|
||||||
import com.dfsek.terra.api.platform.CommandSender;
|
import com.dfsek.terra.api.platform.CommandSender;
|
||||||
import com.dfsek.terra.api.platform.entity.Player;
|
|
||||||
import com.dfsek.terra.world.TerraWorld;
|
|
||||||
|
|
||||||
@Command
|
@Command
|
||||||
@WorldCommand
|
|
||||||
@PlayerCommand
|
|
||||||
@DebugCommand
|
@DebugCommand
|
||||||
public class ProfileStopCommand implements CommandTemplate {
|
public class ProfileStopCommand implements CommandTemplate {
|
||||||
@Inject
|
@Inject
|
||||||
@ -21,9 +15,7 @@ public class ProfileStopCommand implements CommandTemplate {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void execute(CommandSender sender) {
|
public void execute(CommandSender sender) {
|
||||||
Player player = (Player) sender;
|
main.getProfiler().stop();
|
||||||
TerraWorld world = main.getWorld(player.getWorld());
|
sender.sendMessage("Profiling disabled.");
|
||||||
world.getProfiler().setProfiling(false);
|
|
||||||
player.sendMessage("Profiling disabled.");
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,36 +0,0 @@
|
|||||||
package com.dfsek.terra.profiler;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Class to hold a profiler data value. Contains formatting method to highlight value based on desired range.
|
|
||||||
*/
|
|
||||||
public class DataHolder {
|
|
||||||
private final long desired;
|
|
||||||
private final DataType type;
|
|
||||||
private final double desiredRangePercent;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Constructs a DataHolder with a DataType and a desired value, including a percentage around the desired value considered acceptable
|
|
||||||
*
|
|
||||||
* @param type The type of data held in this instance.
|
|
||||||
* @param desired The desired value. This should be the average value of whatever is being measured.
|
|
||||||
* @param desiredRangePercent The percentage around the desired value to be considered acceptable.
|
|
||||||
*/
|
|
||||||
public DataHolder(DataType type, long desired, double desiredRangePercent) {
|
|
||||||
this.desired = desired;
|
|
||||||
this.type = type;
|
|
||||||
this.desiredRangePercent = desiredRangePercent;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Returns a String, formatted with Bungee ChatColors.<br>
|
|
||||||
* GREEN if the value is better than desired and outside of acceptable range.<br>
|
|
||||||
* YELLOW if the value is better or worse than desired, and within acceptable range.<br>
|
|
||||||
* RED if the value is worse than desired and outside of acceptable range.<br>
|
|
||||||
*
|
|
||||||
* @param data The data to format.
|
|
||||||
* @return String - The formatted data.
|
|
||||||
*/
|
|
||||||
public String getFormattedData(long data) {
|
|
||||||
return type.getFormatted(data);
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,24 +0,0 @@
|
|||||||
package com.dfsek.terra.profiler;
|
|
||||||
|
|
||||||
import net.jafama.FastMath;
|
|
||||||
|
|
||||||
public enum DataType {
|
|
||||||
PERIOD_MILLISECONDS(Desire.LOW, 1000000, "ms"), PERIOD_NANOSECONDS(Desire.LOW, 1, "ns");
|
|
||||||
private final Desire desire;
|
|
||||||
private final long divisor;
|
|
||||||
private final String unit;
|
|
||||||
|
|
||||||
DataType(Desire d, long divisor, String unit) {
|
|
||||||
this.desire = d;
|
|
||||||
this.divisor = divisor;
|
|
||||||
this.unit = unit;
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getFormatted(long value) {
|
|
||||||
return (double) FastMath.round(((double) value / divisor) * 100D) / 100D + unit;
|
|
||||||
}
|
|
||||||
|
|
||||||
public Desire getDesire() {
|
|
||||||
return desire;
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,10 +0,0 @@
|
|||||||
package com.dfsek.terra.profiler;
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Enum to represent the "goal" of a value, whether it is desirable for the value to be high (e.g. Frequency), or low (e.g. Period)
|
|
||||||
*/
|
|
||||||
public enum Desire {
|
|
||||||
LOW, HIGH
|
|
||||||
|
|
||||||
}
|
|
@ -1,87 +0,0 @@
|
|||||||
package com.dfsek.terra.profiler;
|
|
||||||
|
|
||||||
import com.dfsek.terra.api.math.MathUtil;
|
|
||||||
import com.dfsek.terra.api.util.GlueList;
|
|
||||||
import net.jafama.FastMath;
|
|
||||||
|
|
||||||
import java.math.BigInteger;
|
|
||||||
import java.util.LinkedList;
|
|
||||||
import java.util.List;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Class to record and hold all data for a single type of measurement performed by the profiler.
|
|
||||||
*/
|
|
||||||
public class Measurement {
|
|
||||||
private final List<Long> measurements = new LinkedList<>();
|
|
||||||
private final long desirable;
|
|
||||||
private final DataType type;
|
|
||||||
private long min = Long.MAX_VALUE;
|
|
||||||
private long max = Long.MIN_VALUE;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Constructs a new Measurement with a desired value and DataType.
|
|
||||||
*
|
|
||||||
* @param desirable The desired value of the measurement.
|
|
||||||
* @param type The type of data the measurement is holding.
|
|
||||||
*/
|
|
||||||
public Measurement(long desirable, DataType type) {
|
|
||||||
this.desirable = desirable;
|
|
||||||
this.type = type;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void record(long value) {
|
|
||||||
max = FastMath.max(value, max);
|
|
||||||
min = FastMath.min(value, min);
|
|
||||||
measurements.add(value);
|
|
||||||
}
|
|
||||||
|
|
||||||
public int size() {
|
|
||||||
return measurements.size();
|
|
||||||
}
|
|
||||||
|
|
||||||
public ProfileFuture beginMeasurement() {
|
|
||||||
ProfileFuture future = new ProfileFuture();
|
|
||||||
long current = System.nanoTime();
|
|
||||||
future.thenRun(() -> record(System.nanoTime() - current));
|
|
||||||
return future;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void reset() {
|
|
||||||
min = Long.MAX_VALUE;
|
|
||||||
max = Long.MIN_VALUE;
|
|
||||||
measurements.clear();
|
|
||||||
}
|
|
||||||
|
|
||||||
public DataHolder getDataHolder() {
|
|
||||||
return new DataHolder(type, desirable, 0.25);
|
|
||||||
}
|
|
||||||
|
|
||||||
public long getMin() {
|
|
||||||
if(min == Long.MAX_VALUE) return 0;
|
|
||||||
return min;
|
|
||||||
}
|
|
||||||
|
|
||||||
public long getMax() {
|
|
||||||
if(max == Long.MIN_VALUE) return 0;
|
|
||||||
return max;
|
|
||||||
}
|
|
||||||
|
|
||||||
public long average() {
|
|
||||||
BigInteger running = BigInteger.valueOf(0);
|
|
||||||
List<Long> mTemp = new GlueList<>(measurements);
|
|
||||||
for(Long l : mTemp) {
|
|
||||||
running = running.add(BigInteger.valueOf(l));
|
|
||||||
}
|
|
||||||
if(measurements.size() == 0) return 0;
|
|
||||||
return running.divide(BigInteger.valueOf(measurements.size())).longValue();
|
|
||||||
}
|
|
||||||
|
|
||||||
public double getStdDev() {
|
|
||||||
return MathUtil.standardDeviation(new GlueList<>(measurements));
|
|
||||||
}
|
|
||||||
|
|
||||||
public int entries() {
|
|
||||||
return measurements.size();
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
@ -0,0 +1,14 @@
|
|||||||
|
package com.dfsek.terra.profiler;
|
||||||
|
|
||||||
|
public class ProfileFrame implements AutoCloseable {
|
||||||
|
private final Runnable action;
|
||||||
|
|
||||||
|
public ProfileFrame(Runnable action) {
|
||||||
|
this.action = action;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void close() {
|
||||||
|
action.run();
|
||||||
|
}
|
||||||
|
}
|
@ -1,18 +0,0 @@
|
|||||||
package com.dfsek.terra.profiler;
|
|
||||||
|
|
||||||
import java.util.concurrent.CompletableFuture;
|
|
||||||
|
|
||||||
public class ProfileFuture extends CompletableFuture<Boolean> implements AutoCloseable {
|
|
||||||
public ProfileFuture() {
|
|
||||||
super();
|
|
||||||
}
|
|
||||||
|
|
||||||
public boolean complete() {
|
|
||||||
return super.complete(true);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void close() {
|
|
||||||
this.complete();
|
|
||||||
}
|
|
||||||
}
|
|
@ -13,8 +13,12 @@ public interface Profiler {
|
|||||||
|
|
||||||
Map<String, Timings> getTimings();
|
Map<String, Timings> getTimings();
|
||||||
|
|
||||||
default AutoCloseable profile(String frame) {
|
default ProfileFrame profile(String frame) {
|
||||||
push(frame);
|
push(frame);
|
||||||
return () -> pop(frame);
|
return new ProfileFrame(() -> pop(frame));
|
||||||
|
}
|
||||||
|
|
||||||
|
default void reset() {
|
||||||
|
// todo: impl
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,85 +0,0 @@
|
|||||||
package com.dfsek.terra.profiler;
|
|
||||||
|
|
||||||
import com.dfsek.terra.api.platform.world.World;
|
|
||||||
import com.dfsek.terra.world.TerraWorld;
|
|
||||||
import com.google.common.collect.BiMap;
|
|
||||||
import com.google.common.collect.HashBiMap;
|
|
||||||
import net.jafama.FastMath;
|
|
||||||
|
|
||||||
import java.util.Map;
|
|
||||||
|
|
||||||
public class WorldProfiler {
|
|
||||||
private final BiMap<String, Measurement> measures = HashBiMap.create();
|
|
||||||
private final World world;
|
|
||||||
private boolean isProfiling;
|
|
||||||
|
|
||||||
public WorldProfiler(World w) {
|
|
||||||
if(!TerraWorld.isTerraWorld(w))
|
|
||||||
throw new IllegalArgumentException("Attempted to instantiate profiler on non-Terra managed world!");
|
|
||||||
this.addMeasurement(new Measurement(2500000, DataType.PERIOD_MILLISECONDS), "TotalChunkGenTime")
|
|
||||||
.addMeasurement(new Measurement(1500000, DataType.PERIOD_MILLISECONDS), "FloraTime")
|
|
||||||
.addMeasurement(new Measurement(10000000, DataType.PERIOD_MILLISECONDS), "TreeTime")
|
|
||||||
.addMeasurement(new Measurement(1500000, DataType.PERIOD_MILLISECONDS), "OreTime")
|
|
||||||
.addMeasurement(new Measurement(5000000, DataType.PERIOD_MILLISECONDS), "CaveTime")
|
|
||||||
.addMeasurement(new Measurement(1500000, DataType.PERIOD_MILLISECONDS), "StructureTime");
|
|
||||||
|
|
||||||
isProfiling = false;
|
|
||||||
this.world = w;
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getResultsFormatted() {
|
|
||||||
if(! isProfiling) return "Profiler is not currently running.";
|
|
||||||
StringBuilder result = new StringBuilder("Gaea World Profiler Results (Min / Avg / Max / Std Dev): \n");
|
|
||||||
for(Map.Entry<String, Measurement> e : measures.entrySet()) {
|
|
||||||
result
|
|
||||||
.append(e.getKey())
|
|
||||||
.append(": ")
|
|
||||||
.append(e.getValue().getDataHolder().getFormattedData(e.getValue().getMin()))
|
|
||||||
.append(" / ")
|
|
||||||
.append(e.getValue().getDataHolder().getFormattedData(e.getValue().average()))
|
|
||||||
.append(" / ")
|
|
||||||
.append(e.getValue().getDataHolder().getFormattedData(e.getValue().getMax()))
|
|
||||||
.append(" / ")
|
|
||||||
.append((double) FastMath.round((e.getValue().getStdDev() / 1000000) * 100D) / 100D)
|
|
||||||
.append("ms")
|
|
||||||
.append(" (x").append(e.getValue().size()).append(")\n");
|
|
||||||
}
|
|
||||||
return result.toString();
|
|
||||||
}
|
|
||||||
|
|
||||||
public void reset() {
|
|
||||||
for(Map.Entry<String, Measurement> e : measures.entrySet()) {
|
|
||||||
e.getValue().reset();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public com.dfsek.terra.profiler.WorldProfiler addMeasurement(Measurement m, String name) {
|
|
||||||
measures.put(name, m);
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setMeasurement(String id, long value) {
|
|
||||||
if(isProfiling) measures.get(id).record(value);
|
|
||||||
}
|
|
||||||
|
|
||||||
public ProfileFuture measure(String id) {
|
|
||||||
if(isProfiling) return measures.get(id).beginMeasurement();
|
|
||||||
else return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getID(Measurement m) {
|
|
||||||
return measures.inverse().get(m);
|
|
||||||
}
|
|
||||||
|
|
||||||
public boolean isProfiling() {
|
|
||||||
return isProfiling;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setProfiling(boolean enabled) {
|
|
||||||
this.isProfiling = enabled;
|
|
||||||
}
|
|
||||||
|
|
||||||
public World getWorld() {
|
|
||||||
return world;
|
|
||||||
}
|
|
||||||
}
|
|
@ -13,7 +13,6 @@ import com.dfsek.terra.api.world.generation.TerraChunkGenerator;
|
|||||||
import com.dfsek.terra.api.world.palette.Palette;
|
import com.dfsek.terra.api.world.palette.Palette;
|
||||||
import com.dfsek.terra.config.pack.ConfigPack;
|
import com.dfsek.terra.config.pack.ConfigPack;
|
||||||
import com.dfsek.terra.config.pack.WorldConfig;
|
import com.dfsek.terra.config.pack.WorldConfig;
|
||||||
import com.dfsek.terra.profiler.WorldProfiler;
|
|
||||||
import com.dfsek.terra.world.generation.math.samplers.Sampler;
|
import com.dfsek.terra.world.generation.math.samplers.Sampler;
|
||||||
import net.jafama.FastMath;
|
import net.jafama.FastMath;
|
||||||
|
|
||||||
@ -21,7 +20,6 @@ public class TerraWorld {
|
|||||||
private final BiomeProvider provider;
|
private final BiomeProvider provider;
|
||||||
private final WorldConfig config;
|
private final WorldConfig config;
|
||||||
private final boolean safe;
|
private final boolean safe;
|
||||||
private final WorldProfiler profiler;
|
|
||||||
private final World world;
|
private final World world;
|
||||||
private final BlockData air;
|
private final BlockData air;
|
||||||
|
|
||||||
@ -31,7 +29,6 @@ public class TerraWorld {
|
|||||||
this.world = w;
|
this.world = w;
|
||||||
config = c.toWorldConfig(this);
|
config = c.toWorldConfig(this);
|
||||||
this.provider = config.getProvider();
|
this.provider = config.getProvider();
|
||||||
profiler = new WorldProfiler(w);
|
|
||||||
air = main.getWorldHandle().createBlockData("minecraft:air");
|
air = main.getWorldHandle().createBlockData("minecraft:air");
|
||||||
main.getEventManager().callEvent(new TerraWorldLoadEvent(this, c));
|
main.getEventManager().callEvent(new TerraWorldLoadEvent(this, c));
|
||||||
safe = true;
|
safe = true;
|
||||||
@ -61,9 +58,6 @@ public class TerraWorld {
|
|||||||
return safe;
|
return safe;
|
||||||
}
|
}
|
||||||
|
|
||||||
public WorldProfiler getProfiler() {
|
|
||||||
return profiler;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get a block at an ungenerated location
|
* Get a block at an ungenerated location
|
||||||
|
@ -15,7 +15,7 @@ import com.dfsek.terra.api.world.generation.TerraChunkGenerator;
|
|||||||
import com.dfsek.terra.api.world.palette.Palette;
|
import com.dfsek.terra.api.world.palette.Palette;
|
||||||
import com.dfsek.terra.config.pack.ConfigPack;
|
import com.dfsek.terra.config.pack.ConfigPack;
|
||||||
import com.dfsek.terra.config.templates.BiomeTemplate;
|
import com.dfsek.terra.config.templates.BiomeTemplate;
|
||||||
import com.dfsek.terra.profiler.ProfileFuture;
|
import com.dfsek.terra.profiler.ProfileFrame;
|
||||||
import com.dfsek.terra.world.Carver;
|
import com.dfsek.terra.world.Carver;
|
||||||
import com.dfsek.terra.world.TerraWorld;
|
import com.dfsek.terra.world.TerraWorld;
|
||||||
import com.dfsek.terra.world.carving.NoiseCarver;
|
import com.dfsek.terra.world.carving.NoiseCarver;
|
||||||
@ -94,7 +94,7 @@ public class DefaultChunkGenerator2D implements TerraChunkGenerator {
|
|||||||
public ChunkData generateChunkData(@NotNull World world, Random random, int chunkX, int chunkZ, ChunkData chunk) {
|
public ChunkData generateChunkData(@NotNull World world, Random random, int chunkX, int chunkZ, ChunkData chunk) {
|
||||||
TerraWorld tw = main.getWorld(world);
|
TerraWorld tw = main.getWorld(world);
|
||||||
BiomeProvider grid = tw.getBiomeProvider();
|
BiomeProvider grid = tw.getBiomeProvider();
|
||||||
try(ProfileFuture ignore = tw.getProfiler().measure("TotalChunkGenTime")) {
|
try(ProfileFrame ignore = main.getProfiler().profile("chunk_base_2d")) {
|
||||||
if(!tw.isSafe()) return chunk;
|
if(!tw.isSafe()) return chunk;
|
||||||
int xOrig = (chunkX << 4);
|
int xOrig = (chunkX << 4);
|
||||||
int zOrig = (chunkZ << 4);
|
int zOrig = (chunkZ << 4);
|
||||||
|
@ -23,7 +23,7 @@ import com.dfsek.terra.api.world.palette.Palette;
|
|||||||
import com.dfsek.terra.api.world.palette.SinglePalette;
|
import com.dfsek.terra.api.world.palette.SinglePalette;
|
||||||
import com.dfsek.terra.config.pack.ConfigPack;
|
import com.dfsek.terra.config.pack.ConfigPack;
|
||||||
import com.dfsek.terra.config.templates.BiomeTemplate;
|
import com.dfsek.terra.config.templates.BiomeTemplate;
|
||||||
import com.dfsek.terra.profiler.ProfileFuture;
|
import com.dfsek.terra.profiler.ProfileFrame;
|
||||||
import com.dfsek.terra.world.Carver;
|
import com.dfsek.terra.world.Carver;
|
||||||
import com.dfsek.terra.world.TerraWorld;
|
import com.dfsek.terra.world.TerraWorld;
|
||||||
import com.dfsek.terra.world.carving.NoiseCarver;
|
import com.dfsek.terra.world.carving.NoiseCarver;
|
||||||
@ -106,7 +106,7 @@ public class DefaultChunkGenerator3D implements TerraChunkGenerator {
|
|||||||
public ChunkData generateChunkData(@NotNull World world, Random random, int chunkX, int chunkZ, ChunkData chunk) {
|
public ChunkData generateChunkData(@NotNull World world, Random random, int chunkX, int chunkZ, ChunkData chunk) {
|
||||||
TerraWorld tw = main.getWorld(world);
|
TerraWorld tw = main.getWorld(world);
|
||||||
BiomeProvider grid = tw.getBiomeProvider();
|
BiomeProvider grid = tw.getBiomeProvider();
|
||||||
try(ProfileFuture ignore = tw.getProfiler().measure("TotalChunkGenTime")) {
|
try(ProfileFrame ignore = main.getProfiler().profile("chunk_base_3d")) {
|
||||||
if(!tw.isSafe()) return chunk;
|
if(!tw.isSafe()) return chunk;
|
||||||
int xOrig = (chunkX << 4);
|
int xOrig = (chunkX << 4);
|
||||||
int zOrig = (chunkZ << 4);
|
int zOrig = (chunkZ << 4);
|
||||||
|
@ -14,7 +14,7 @@ import com.dfsek.terra.api.world.generation.TerraBlockPopulator;
|
|||||||
import com.dfsek.terra.carving.UserDefinedCarver;
|
import com.dfsek.terra.carving.UserDefinedCarver;
|
||||||
import com.dfsek.terra.config.pack.WorldConfig;
|
import com.dfsek.terra.config.pack.WorldConfig;
|
||||||
import com.dfsek.terra.config.templates.CarverTemplate;
|
import com.dfsek.terra.config.templates.CarverTemplate;
|
||||||
import com.dfsek.terra.profiler.ProfileFuture;
|
import com.dfsek.terra.profiler.ProfileFrame;
|
||||||
import com.dfsek.terra.world.TerraWorld;
|
import com.dfsek.terra.world.TerraWorld;
|
||||||
import org.jetbrains.annotations.NotNull;
|
import org.jetbrains.annotations.NotNull;
|
||||||
|
|
||||||
@ -38,7 +38,7 @@ public class CavePopulator implements TerraBlockPopulator, Chunkified {
|
|||||||
TerraWorld tw = main.getWorld(world);
|
TerraWorld tw = main.getWorld(world);
|
||||||
WorldHandle handle = main.getWorldHandle();
|
WorldHandle handle = main.getWorldHandle();
|
||||||
BlockData AIR = handle.createBlockData("minecraft:air");
|
BlockData AIR = handle.createBlockData("minecraft:air");
|
||||||
try(ProfileFuture ignored = tw.getProfiler().measure("CaveTime")) {
|
try(ProfileFrame ignore = main.getProfiler().profile("carving")) {
|
||||||
Random random = PopulationUtil.getRandom(chunk);
|
Random random = PopulationUtil.getRandom(chunk);
|
||||||
if(!tw.isSafe()) return;
|
if(!tw.isSafe()) return;
|
||||||
WorldConfig config = tw.getConfig();
|
WorldConfig config = tw.getConfig();
|
||||||
@ -93,7 +93,7 @@ public class CavePopulator implements TerraBlockPopulator, Chunkified {
|
|||||||
if(template.getShift().get(entry.getValue().getBlockType()).contains(mut.getBlock().getBlockData().getBlockType())) {
|
if(template.getShift().get(entry.getValue().getBlockType()).contains(mut.getBlock().getBlockData().getBlockType())) {
|
||||||
mut.getBlock().setBlockData(shiftStorage.computeIfAbsent(entry.getValue().getBlockType(), BlockType::getDefaultData), false);
|
mut.getBlock().setBlockData(shiftStorage.computeIfAbsent(entry.getValue().getBlockType(), BlockType::getDefaultData), false);
|
||||||
}
|
}
|
||||||
} catch(NullPointerException ignore) {
|
} catch(NullPointerException ignored) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
for(Block b : updateNeeded) {
|
for(Block b : updateNeeded) {
|
||||||
|
@ -8,7 +8,7 @@ import com.dfsek.terra.api.util.world.PopulationUtil;
|
|||||||
import com.dfsek.terra.api.world.biome.UserDefinedBiome;
|
import com.dfsek.terra.api.world.biome.UserDefinedBiome;
|
||||||
import com.dfsek.terra.api.world.biome.provider.BiomeProvider;
|
import com.dfsek.terra.api.world.biome.provider.BiomeProvider;
|
||||||
import com.dfsek.terra.api.world.generation.TerraBlockPopulator;
|
import com.dfsek.terra.api.world.generation.TerraBlockPopulator;
|
||||||
import com.dfsek.terra.profiler.ProfileFuture;
|
import com.dfsek.terra.profiler.ProfileFrame;
|
||||||
import com.dfsek.terra.world.TerraWorld;
|
import com.dfsek.terra.world.TerraWorld;
|
||||||
import com.dfsek.terra.world.population.items.flora.FloraLayer;
|
import com.dfsek.terra.world.population.items.flora.FloraLayer;
|
||||||
import org.jetbrains.annotations.NotNull;
|
import org.jetbrains.annotations.NotNull;
|
||||||
@ -32,7 +32,7 @@ public class FloraPopulator implements TerraBlockPopulator {
|
|||||||
@Override
|
@Override
|
||||||
public void populate(@NotNull World world, @NotNull Chunk chunk) {
|
public void populate(@NotNull World world, @NotNull Chunk chunk) {
|
||||||
TerraWorld tw = main.getWorld(world);
|
TerraWorld tw = main.getWorld(world);
|
||||||
try(ProfileFuture ignored = tw.getProfiler().measure("FloraTime")) {
|
try(ProfileFrame ignore = main.getProfiler().profile("flora")) {
|
||||||
if(tw.getConfig().getTemplate().disableCarvers()) return;
|
if(tw.getConfig().getTemplate().disableCarvers()) return;
|
||||||
|
|
||||||
if(!tw.isSafe()) return;
|
if(!tw.isSafe()) return;
|
||||||
|
@ -10,7 +10,7 @@ import com.dfsek.terra.api.world.biome.TerraBiome;
|
|||||||
import com.dfsek.terra.api.world.biome.UserDefinedBiome;
|
import com.dfsek.terra.api.world.biome.UserDefinedBiome;
|
||||||
import com.dfsek.terra.api.world.generation.TerraBlockPopulator;
|
import com.dfsek.terra.api.world.generation.TerraBlockPopulator;
|
||||||
import com.dfsek.terra.config.templates.BiomeTemplate;
|
import com.dfsek.terra.config.templates.BiomeTemplate;
|
||||||
import com.dfsek.terra.profiler.ProfileFuture;
|
import com.dfsek.terra.profiler.ProfileFrame;
|
||||||
import com.dfsek.terra.world.TerraWorld;
|
import com.dfsek.terra.world.TerraWorld;
|
||||||
import org.jetbrains.annotations.NotNull;
|
import org.jetbrains.annotations.NotNull;
|
||||||
|
|
||||||
@ -27,7 +27,7 @@ public class OrePopulator implements TerraBlockPopulator {
|
|||||||
@Override
|
@Override
|
||||||
public void populate(@NotNull World world, @NotNull Chunk chunk) {
|
public void populate(@NotNull World world, @NotNull Chunk chunk) {
|
||||||
TerraWorld tw = main.getWorld(world);
|
TerraWorld tw = main.getWorld(world);
|
||||||
try(ProfileFuture ignored = tw.getProfiler().measure("OreTime")) {
|
try(ProfileFrame ignore = main.getProfiler().profile("ore")) {
|
||||||
if(tw.getConfig().getTemplate().disableCarvers()) return;
|
if(tw.getConfig().getTemplate().disableCarvers()) return;
|
||||||
|
|
||||||
if(!tw.isSafe()) return;
|
if(!tw.isSafe()) return;
|
||||||
|
@ -11,9 +11,8 @@ import com.dfsek.terra.api.world.biome.UserDefinedBiome;
|
|||||||
import com.dfsek.terra.api.world.biome.provider.BiomeProvider;
|
import com.dfsek.terra.api.world.biome.provider.BiomeProvider;
|
||||||
import com.dfsek.terra.api.world.generation.Chunkified;
|
import com.dfsek.terra.api.world.generation.Chunkified;
|
||||||
import com.dfsek.terra.api.world.generation.TerraBlockPopulator;
|
import com.dfsek.terra.api.world.generation.TerraBlockPopulator;
|
||||||
import com.dfsek.terra.config.pack.ConfigPack;
|
|
||||||
import com.dfsek.terra.config.pack.WorldConfig;
|
import com.dfsek.terra.config.pack.WorldConfig;
|
||||||
import com.dfsek.terra.profiler.ProfileFuture;
|
import com.dfsek.terra.profiler.ProfileFrame;
|
||||||
import com.dfsek.terra.world.TerraWorld;
|
import com.dfsek.terra.world.TerraWorld;
|
||||||
import com.dfsek.terra.world.population.items.TerraStructure;
|
import com.dfsek.terra.world.population.items.TerraStructure;
|
||||||
import net.jafama.FastMath;
|
import net.jafama.FastMath;
|
||||||
@ -32,7 +31,7 @@ public class StructurePopulator implements TerraBlockPopulator, Chunkified {
|
|||||||
@Override
|
@Override
|
||||||
public void populate(@NotNull World world, @NotNull Chunk chunk) {
|
public void populate(@NotNull World world, @NotNull Chunk chunk) {
|
||||||
TerraWorld tw = main.getWorld(world);
|
TerraWorld tw = main.getWorld(world);
|
||||||
try(ProfileFuture ignored = tw.getProfiler().measure("StructureTime")) {
|
try(ProfileFrame ignore = main.getProfiler().profile("structure")) {
|
||||||
if(tw.getConfig().getTemplate().disableCarvers()) return;
|
if(tw.getConfig().getTemplate().disableCarvers()) return;
|
||||||
|
|
||||||
int cx = (chunk.getX() << 4);
|
int cx = (chunk.getX() << 4);
|
||||||
|
@ -8,7 +8,7 @@ import com.dfsek.terra.api.util.world.PopulationUtil;
|
|||||||
import com.dfsek.terra.api.world.biome.UserDefinedBiome;
|
import com.dfsek.terra.api.world.biome.UserDefinedBiome;
|
||||||
import com.dfsek.terra.api.world.biome.provider.BiomeProvider;
|
import com.dfsek.terra.api.world.biome.provider.BiomeProvider;
|
||||||
import com.dfsek.terra.api.world.generation.TerraBlockPopulator;
|
import com.dfsek.terra.api.world.generation.TerraBlockPopulator;
|
||||||
import com.dfsek.terra.profiler.ProfileFuture;
|
import com.dfsek.terra.profiler.ProfileFrame;
|
||||||
import com.dfsek.terra.world.TerraWorld;
|
import com.dfsek.terra.world.TerraWorld;
|
||||||
import com.dfsek.terra.world.population.items.tree.TreeLayer;
|
import com.dfsek.terra.world.population.items.tree.TreeLayer;
|
||||||
import net.jafama.FastMath;
|
import net.jafama.FastMath;
|
||||||
@ -32,7 +32,7 @@ public class TreePopulator implements TerraBlockPopulator {
|
|||||||
@SuppressWarnings("try")
|
@SuppressWarnings("try")
|
||||||
public void populate(@NotNull World world, @NotNull Chunk chunk) {
|
public void populate(@NotNull World world, @NotNull Chunk chunk) {
|
||||||
TerraWorld tw = main.getWorld(world);
|
TerraWorld tw = main.getWorld(world);
|
||||||
try(ProfileFuture ignored = tw.getProfiler().measure("TreeTime")) {
|
try(ProfileFrame ignore = main.getProfiler().profile("tree")) {
|
||||||
if(tw.getConfig().getTemplate().disableCarvers()) return;
|
if(tw.getConfig().getTemplate().disableCarvers()) return;
|
||||||
|
|
||||||
if(!tw.isSafe()) return;
|
if(!tw.isSafe()) return;
|
||||||
|
@ -3,19 +3,11 @@ package com.dfsek.terra.bukkit.generator;
|
|||||||
import com.dfsek.terra.api.TerraPlugin;
|
import com.dfsek.terra.api.TerraPlugin;
|
||||||
import com.dfsek.terra.api.platform.world.Chunk;
|
import com.dfsek.terra.api.platform.world.Chunk;
|
||||||
import com.dfsek.terra.api.platform.world.generator.GeneratorWrapper;
|
import com.dfsek.terra.api.platform.world.generator.GeneratorWrapper;
|
||||||
import com.dfsek.terra.api.world.generation.TerraBlockPopulator;
|
|
||||||
import com.dfsek.terra.api.world.generation.TerraChunkGenerator;
|
import com.dfsek.terra.api.world.generation.TerraChunkGenerator;
|
||||||
import com.dfsek.terra.bukkit.population.PopulationManager;
|
import com.dfsek.terra.bukkit.population.PopulationManager;
|
||||||
import com.dfsek.terra.bukkit.world.BukkitAdapter;
|
import com.dfsek.terra.bukkit.world.BukkitAdapter;
|
||||||
import com.dfsek.terra.bukkit.world.BukkitBiomeGrid;
|
import com.dfsek.terra.bukkit.world.BukkitBiomeGrid;
|
||||||
import com.dfsek.terra.profiler.DataType;
|
|
||||||
import com.dfsek.terra.profiler.Measurement;
|
|
||||||
import com.dfsek.terra.world.TerraWorld;
|
import com.dfsek.terra.world.TerraWorld;
|
||||||
import com.dfsek.terra.world.population.CavePopulator;
|
|
||||||
import com.dfsek.terra.world.population.FloraPopulator;
|
|
||||||
import com.dfsek.terra.world.population.OrePopulator;
|
|
||||||
import com.dfsek.terra.world.population.StructurePopulator;
|
|
||||||
import com.dfsek.terra.world.population.TreePopulator;
|
|
||||||
import org.bukkit.World;
|
import org.bukkit.World;
|
||||||
import org.bukkit.generator.BlockPopulator;
|
import org.bukkit.generator.BlockPopulator;
|
||||||
import org.bukkit.generator.ChunkGenerator;
|
import org.bukkit.generator.ChunkGenerator;
|
||||||
@ -24,13 +16,10 @@ import org.jetbrains.annotations.NotNull;
|
|||||||
import java.io.FileNotFoundException;
|
import java.io.FileNotFoundException;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
import java.util.Collections;
|
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
import java.util.LinkedList;
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.Random;
|
import java.util.Random;
|
||||||
import java.util.stream.Collectors;
|
|
||||||
|
|
||||||
public class BukkitChunkGeneratorWrapper extends ChunkGenerator implements GeneratorWrapper {
|
public class BukkitChunkGeneratorWrapper extends ChunkGenerator implements GeneratorWrapper {
|
||||||
|
|
||||||
@ -76,8 +65,6 @@ public class BukkitChunkGeneratorWrapper extends ChunkGenerator implements Gener
|
|||||||
e.printStackTrace();
|
e.printStackTrace();
|
||||||
}
|
}
|
||||||
popMap.put(w, popMan);
|
popMap.put(w, popMan);
|
||||||
main.getWorld(w).getProfiler().addMeasurement(new Measurement(15000000, DataType.PERIOD_MILLISECONDS), "PopulationManagerTime");
|
|
||||||
popMan.attachProfiler(main.getWorld(w).getProfiler());
|
|
||||||
needsLoad = false;
|
needsLoad = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -5,12 +5,10 @@ import com.dfsek.terra.api.platform.world.Chunk;
|
|||||||
import com.dfsek.terra.api.platform.world.World;
|
import com.dfsek.terra.api.platform.world.World;
|
||||||
import com.dfsek.terra.api.util.FastRandom;
|
import com.dfsek.terra.api.util.FastRandom;
|
||||||
import com.dfsek.terra.api.world.generation.Chunkified;
|
import com.dfsek.terra.api.world.generation.Chunkified;
|
||||||
import com.dfsek.terra.api.world.generation.TerraBlockPopulator;
|
|
||||||
import com.dfsek.terra.api.world.generation.TerraChunkGenerator;
|
import com.dfsek.terra.api.world.generation.TerraChunkGenerator;
|
||||||
import com.dfsek.terra.bukkit.TerraBukkitPlugin;
|
import com.dfsek.terra.bukkit.TerraBukkitPlugin;
|
||||||
import com.dfsek.terra.bukkit.world.BukkitAdapter;
|
import com.dfsek.terra.bukkit.world.BukkitAdapter;
|
||||||
import com.dfsek.terra.profiler.ProfileFuture;
|
import com.dfsek.terra.profiler.ProfileFrame;
|
||||||
import com.dfsek.terra.profiler.WorldProfiler;
|
|
||||||
import org.bukkit.generator.BlockPopulator;
|
import org.bukkit.generator.BlockPopulator;
|
||||||
import org.jetbrains.annotations.NotNull;
|
import org.jetbrains.annotations.NotNull;
|
||||||
|
|
||||||
@ -26,22 +24,12 @@ public class PopulationManager extends BlockPopulator {
|
|||||||
private final TerraChunkGenerator generator;
|
private final TerraChunkGenerator generator;
|
||||||
private final HashSet<ChunkCoordinate> needsPop = new HashSet<>();
|
private final HashSet<ChunkCoordinate> needsPop = new HashSet<>();
|
||||||
private final TerraPlugin main;
|
private final TerraPlugin main;
|
||||||
private WorldProfiler profiler;
|
|
||||||
|
|
||||||
public PopulationManager(TerraChunkGenerator generator, TerraPlugin main) {
|
public PopulationManager(TerraChunkGenerator generator, TerraPlugin main) {
|
||||||
this.generator = generator;
|
this.generator = generator;
|
||||||
this.main = main;
|
this.main = main;
|
||||||
}
|
}
|
||||||
|
|
||||||
private ProfileFuture measure() {
|
|
||||||
if(profiler != null) return profiler.measure("PopulationManagerTime");
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void attachProfiler(WorldProfiler p) {
|
|
||||||
this.profiler = p;
|
|
||||||
}
|
|
||||||
|
|
||||||
@SuppressWarnings("unchecked")
|
@SuppressWarnings("unchecked")
|
||||||
public synchronized void saveBlocks(World w) throws IOException {
|
public synchronized void saveBlocks(World w) throws IOException {
|
||||||
File f = new File(Gaea.getGaeaFolder(w), "chunks.bin");
|
File f = new File(Gaea.getGaeaFolder(w), "chunks.bin");
|
||||||
@ -79,7 +67,7 @@ public class PopulationManager extends BlockPopulator {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void populate(org.bukkit.@NotNull World world, @NotNull Random random, org.bukkit.@NotNull Chunk source) {
|
public void populate(org.bukkit.@NotNull World world, @NotNull Random random, org.bukkit.@NotNull Chunk source) {
|
||||||
try(ProfileFuture ignored = measure()) {
|
try(ProfileFrame ignore = main.getProfiler().profile("popman")) {
|
||||||
Chunk chunk = BukkitAdapter.adapt(source);
|
Chunk chunk = BukkitAdapter.adapt(source);
|
||||||
needsPop.add(new ChunkCoordinate(chunk));
|
needsPop.add(new ChunkCoordinate(chunk));
|
||||||
int x = chunk.getX();
|
int x = chunk.getX();
|
||||||
|
Loading…
x
Reference in New Issue
Block a user