diff --git a/common/addons/chunk-generator-noise-3d/src/main/java/com/dfsek/terra/addons/chunkgenerator/generation/NoiseChunkGenerator3D.java b/common/addons/chunk-generator-noise-3d/src/main/java/com/dfsek/terra/addons/chunkgenerator/generation/NoiseChunkGenerator3D.java index 2c2062d0c..514ccd36a 100644 --- a/common/addons/chunk-generator-noise-3d/src/main/java/com/dfsek/terra/addons/chunkgenerator/generation/NoiseChunkGenerator3D.java +++ b/common/addons/chunk-generator-noise-3d/src/main/java/com/dfsek/terra/addons/chunkgenerator/generation/NoiseChunkGenerator3D.java @@ -18,7 +18,6 @@ import com.dfsek.terra.addons.chunkgenerator.generation.math.samplers.Sampler3D; import com.dfsek.terra.addons.chunkgenerator.generation.math.samplers.SamplerProvider; import com.dfsek.terra.api.Platform; import com.dfsek.terra.api.block.state.BlockState; -import com.dfsek.terra.api.profiler.ProfileFrame; import com.dfsek.terra.api.world.biome.Biome; import com.dfsek.terra.api.world.biome.generation.BiomeProvider; import com.dfsek.terra.api.world.chunk.generation.ChunkGenerator; @@ -51,56 +50,56 @@ public class NoiseChunkGenerator3D implements ChunkGenerator { public void generateChunkData(@NotNull ProtoChunk chunk, @NotNull WorldProperties world, @NotNull BiomeProvider biomeProvider, int chunkX, int chunkZ) { - try(ProfileFrame ignore = platform.getProfiler().profile("chunk_base_3d")) { - int xOrig = (chunkX << 4); - int zOrig = (chunkZ << 4); - - Sampler3D sampler = samplerCache.getChunk(chunkX, chunkZ, world, biomeProvider); - - long seed = world.getSeed(); - - LazilyEvaluatedInterpolator carver = new LazilyEvaluatedInterpolator(biomeProvider, - chunkX, - chunkZ, - world.getMaxHeight(), - world.getMinHeight(), - carverHorizontalResolution, - carverVerticalResolution, - seed); - for(int x = 0; x < 16; x++) { - for(int z = 0; z < 16; z++) { - int paletteLevel = 0; - - int cx = xOrig + x; - int cz = zOrig + z; - - Biome biome = biomeProvider.getBiome(cx, cz, seed); - - PaletteInfo paletteInfo = biome.getContext().get(PaletteInfo.class); - - int sea = paletteInfo.seaLevel(); - Palette seaPalette = paletteInfo.ocean(); - - BlockState data; - for(int y = world.getMaxHeight() - 1; y >= world.getMinHeight(); y--) { - if(sampler.sample(x, y, z) > 0) { - if(carver.sample(x, y, z) <= 0) { - data = PaletteUtil.getPalette(x, y, z, sampler, paletteInfo, paletteLevel).get(paletteLevel, cx, y, cz, - seed); - chunk.setBlock(x, y, z, data); - } - - paletteLevel++; - } else if(y <= sea) { - chunk.setBlock(x, y, z, seaPalette.get(sea - y, x + xOrig, y, z + zOrig, seed)); - paletteLevel = 0; - } else { - paletteLevel = 0; + platform.getProfiler().push("chunk_base_3d"); + int xOrig = (chunkX << 4); + int zOrig = (chunkZ << 4); + + Sampler3D sampler = samplerCache.getChunk(chunkX, chunkZ, world, biomeProvider); + + long seed = world.getSeed(); + + LazilyEvaluatedInterpolator carver = new LazilyEvaluatedInterpolator(biomeProvider, + chunkX, + chunkZ, + world.getMaxHeight(), + world.getMinHeight(), + carverHorizontalResolution, + carverVerticalResolution, + seed); + for(int x = 0; x < 16; x++) { + for(int z = 0; z < 16; z++) { + int paletteLevel = 0; + + int cx = xOrig + x; + int cz = zOrig + z; + + Biome biome = biomeProvider.getBiome(cx, cz, seed); + + PaletteInfo paletteInfo = biome.getContext().get(PaletteInfo.class); + + int sea = paletteInfo.seaLevel(); + Palette seaPalette = paletteInfo.ocean(); + + BlockState data; + for(int y = world.getMaxHeight() - 1; y >= world.getMinHeight(); y--) { + if(sampler.sample(x, y, z) > 0) { + if(carver.sample(x, y, z) <= 0) { + data = PaletteUtil.getPalette(x, y, z, sampler, paletteInfo, paletteLevel).get(paletteLevel, cx, y, cz, + seed); + chunk.setBlock(x, y, z, data); } + + paletteLevel++; + } else if(y <= sea) { + chunk.setBlock(x, y, z, seaPalette.get(sea - y, x + xOrig, y, z + zOrig, seed)); + paletteLevel = 0; + } else { + paletteLevel = 0; } } } } + platform.getProfiler().pop("chunk_base_3d"); } @Override diff --git a/common/addons/generation-stage-feature/src/main/java/com/dfsek/terra/addons/generation/feature/FeatureGenerationStage.java b/common/addons/generation-stage-feature/src/main/java/com/dfsek/terra/addons/generation/feature/FeatureGenerationStage.java index e2b6e25f3..ccbd7f97b 100644 --- a/common/addons/generation-stage-feature/src/main/java/com/dfsek/terra/addons/generation/feature/FeatureGenerationStage.java +++ b/common/addons/generation-stage-feature/src/main/java/com/dfsek/terra/addons/generation/feature/FeatureGenerationStage.java @@ -12,7 +12,6 @@ import java.util.Random; import com.dfsek.terra.addons.generation.feature.config.BiomeFeatures; import com.dfsek.terra.api.Platform; -import com.dfsek.terra.api.profiler.ProfileFrame; import com.dfsek.terra.api.registry.key.StringIdentifiable; import com.dfsek.terra.api.util.Rotation; import com.dfsek.terra.api.util.vector.Vector3Int; @@ -27,49 +26,52 @@ public class FeatureGenerationStage implements GenerationStage, StringIdentifiab private final String id; + private final String profile; + public FeatureGenerationStage(Platform platform, String id) { this.platform = platform; this.id = id; + this.profile = "feature_stage:" + id; } @Override @SuppressWarnings("try") public void populate(ProtoWorld world) { - try(ProfileFrame ignore = platform.getProfiler().profile("feature_stage:" + id)) { - int cx = world.centerChunkX() << 4; - int cz = world.centerChunkZ() << 4; - long seed = world.getSeed(); - for(int x = 0; x < 16; x++) { - for(int z = 0; z < 16; z++) { - int tx = cx + x; - int tz = cz + z; - Column column = world.column(tx, tz); - long coordinateSeed = (seed * 31 + tx) * 31 + tz; - - world.getBiomeProvider() - .getBiome(tx, tz, seed) - .getContext() - .get(BiomeFeatures.class) - .getFeatures() - .getOrDefault(this, Collections.emptyList()) - .forEach(feature -> { - try(ProfileFrame ignored = platform.getProfiler().profile(feature.getID())) { - if(feature.getDistributor().matches(tx, tz, seed)) { - feature.getLocator() - .getSuitableCoordinates(column) - .forEach(y -> - feature.getStructure(world, tx, y, tz) - .generate(Vector3Int.of(tx, y, tz), - world, - new Random(coordinateSeed * 31 + y), - Rotation.NONE) - ); - } - } - }); - } + platform.getProfiler().push(profile); + int cx = world.centerChunkX() << 4; + int cz = world.centerChunkZ() << 4; + long seed = world.getSeed(); + for(int x = 0; x < 16; x++) { + for(int z = 0; z < 16; z++) { + int tx = cx + x; + int tz = cz + z; + Column column = world.column(tx, tz); + long coordinateSeed = (seed * 31 + tx) * 31 + tz; + + world.getBiomeProvider() + .getBiome(tx, tz, seed) + .getContext() + .get(BiomeFeatures.class) + .getFeatures() + .getOrDefault(this, Collections.emptyList()) + .forEach(feature -> { + platform.getProfiler().push(feature.getID()); + if(feature.getDistributor().matches(tx, tz, seed)) { + feature.getLocator() + .getSuitableCoordinates(column) + .forEach(y -> + feature.getStructure(world, tx, y, tz) + .generate(Vector3Int.of(tx, y, tz), + world, + new Random(coordinateSeed * 31 + y), + Rotation.NONE) + ); + } + platform.getProfiler().pop(feature.getID()); + }); } } + platform.getProfiler().pop(profile); } @Override diff --git a/common/addons/structure-terrascript-loader/src/main/java/com/dfsek/terra/addons/terrascript/script/StructureScript.java b/common/addons/structure-terrascript-loader/src/main/java/com/dfsek/terra/addons/terrascript/script/StructureScript.java index 3a98b0b2f..363fc47ca 100644 --- a/common/addons/structure-terrascript-loader/src/main/java/com/dfsek/terra/addons/terrascript/script/StructureScript.java +++ b/common/addons/structure-terrascript-loader/src/main/java/com/dfsek/terra/addons/terrascript/script/StructureScript.java @@ -39,7 +39,6 @@ import com.dfsek.terra.addons.terrascript.script.builders.UnaryNumberFunctionBui import com.dfsek.terra.addons.terrascript.script.builders.UnaryStringFunctionBuilder; import com.dfsek.terra.addons.terrascript.script.builders.ZeroArgFunctionBuilder; import com.dfsek.terra.api.Platform; -import com.dfsek.terra.api.profiler.ProfileFrame; import com.dfsek.terra.api.registry.Registry; import com.dfsek.terra.api.registry.key.Keyed; import com.dfsek.terra.api.registry.key.RegistryKey; @@ -54,6 +53,8 @@ public class StructureScript implements Structure, Keyed { private static final Logger LOGGER = LoggerFactory.getLogger(StructureScript.class); private final Block block; private final RegistryKey id; + + private final String profile; private final Platform platform; @SuppressWarnings("rawtypes") @@ -67,7 +68,8 @@ public class StructureScript implements Structure, Keyed { throw new RuntimeException(e); } this.id = id; - + this.profile = "terrascript_direct:" + id; + //noinspection unchecked functionRegistry.forEach((key, function) -> parser.registerFunction(key.getID(), function)); // Register registry functions. @@ -129,15 +131,17 @@ public class StructureScript implements Structure, Keyed { @Override @SuppressWarnings("try") public boolean generate(Vector3Int location, WritableWorld world, Random random, Rotation rotation) { - try(ProfileFrame ignore = platform.getProfiler().profile("terrascript_direct:" + id)) { - return applyBlock(new TerraImplementationArguments(location, rotation, random, world, 0)); - } + platform.getProfiler().push(profile); + boolean result = applyBlock(new TerraImplementationArguments(location, rotation, random, world, 0)); + platform.getProfiler().pop(profile); + return result; } public boolean generate(Vector3Int location, WritableWorld world, Random random, Rotation rotation, int recursions) { - try(ProfileFrame ignore = platform.getProfiler().profile("terrascript_direct:" + id)) { - return applyBlock(new TerraImplementationArguments(location, rotation, random, world, recursions)); - } + platform.getProfiler().push(profile); + boolean result = applyBlock(new TerraImplementationArguments(location, rotation, random, world, recursions)); + platform.getProfiler().pop(profile); + return result; } private boolean applyBlock(TerraImplementationArguments arguments) { diff --git a/common/api/src/main/java/com/dfsek/terra/api/profiler/ProfileFrame.java b/common/api/src/main/java/com/dfsek/terra/api/profiler/ProfileFrame.java deleted file mode 100644 index 5a910c5b5..000000000 --- a/common/api/src/main/java/com/dfsek/terra/api/profiler/ProfileFrame.java +++ /dev/null @@ -1,21 +0,0 @@ -/* - * Copyright (c) 2020-2021 Polyhedral Development - * - * The Terra API is licensed under the terms of the MIT License. For more details, - * reference the LICENSE file in the common/api directory. - */ - -package com.dfsek.terra.api.profiler; - -public class ProfileFrame implements AutoCloseable { - private final Runnable action; - - public ProfileFrame(Runnable action) { - this.action = action; - } - - @Override - public void close() { - action.run(); - } -} diff --git a/common/api/src/main/java/com/dfsek/terra/api/profiler/Profiler.java b/common/api/src/main/java/com/dfsek/terra/api/profiler/Profiler.java index af52b324c..15d610a63 100644 --- a/common/api/src/main/java/com/dfsek/terra/api/profiler/Profiler.java +++ b/common/api/src/main/java/com/dfsek/terra/api/profiler/Profiler.java @@ -36,21 +36,6 @@ public interface Profiler { */ void stop(); - /** - * Return a {@link AutoCloseable} implementation that - * may be used in a try-with-resources statement for - * more intuitive profiling, with auto-push/pop. - * - * @param frame ID of frame. - * - * @return {@link AutoCloseable} implementation for use - * in try-with-resources. - */ - default ProfileFrame profile(String frame) { - push(frame); - return new ProfileFrame(() -> pop(frame)); - } - /** * Clear the profiler data. */ diff --git a/common/implementation/base/src/main/java/com/dfsek/terra/profiler/ProfilerImpl.java b/common/implementation/base/src/main/java/com/dfsek/terra/profiler/ProfilerImpl.java index 0345b5c7d..d022d31e0 100644 --- a/common/implementation/base/src/main/java/com/dfsek/terra/profiler/ProfilerImpl.java +++ b/common/implementation/base/src/main/java/com/dfsek/terra/profiler/ProfilerImpl.java @@ -51,38 +51,42 @@ public class ProfilerImpl implements Profiler { @Override public void push(String frame) { - STACK_SIZE.get().increment(); - if(running && SAFE.get()) { - Stack stack = THREAD_STACK.get(); - stack.push(new Frame(stack.isEmpty() ? frame : stack.peek().getId() + "." + frame)); + if(running) { + STACK_SIZE.get().increment(); + if(SAFE.get()) { + Stack stack = THREAD_STACK.get(); + stack.push(new Frame(stack.isEmpty() ? frame : stack.peek().getId() + "." + frame)); + } else SAFE.set(false); } else SAFE.set(false); } @Override public void pop(String frame) { - MutableInteger size = STACK_SIZE.get(); - size.decrement(); - if(running && SAFE.get()) { - long time = System.nanoTime(); - Stack stack = THREAD_STACK.get(); - - Map> timingsMap = TIMINGS.get(); - - if(timingsMap.isEmpty()) { - synchronized(accessibleThreadMaps) { - accessibleThreadMaps.add(timingsMap); + if(running) { + MutableInteger size = STACK_SIZE.get(); + size.decrement(); + if(SAFE.get()) { + long time = System.nanoTime(); + Stack stack = THREAD_STACK.get(); + + Map> timingsMap = TIMINGS.get(); + + if(timingsMap.isEmpty()) { + synchronized(accessibleThreadMaps) { + accessibleThreadMaps.add(timingsMap); + } } + + Frame top = stack.pop(); + if(!stack.isEmpty() ? !top.getId().endsWith("." + frame) : !top.getId().equals(frame)) + throw new MalformedStackException("Expected " + frame + ", found " + top); + + List timings = timingsMap.computeIfAbsent(top.getId(), id -> new ArrayList<>()); + + timings.add(time - top.getStart()); } - - Frame top = stack.pop(); - if(!stack.isEmpty() ? !top.getId().endsWith("." + frame) : !top.getId().equals(frame)) - throw new MalformedStackException("Expected " + frame + ", found " + top); - - List timings = timingsMap.computeIfAbsent(top.getId(), id -> new ArrayList<>()); - - timings.add(time - top.getStart()); + if(size.get() == 0) SAFE.set(true); } - if(size.get() == 0) SAFE.set(true); } @Override