From 7b9c2ae6ad16efc6f22861f7d2427cfe69f5818a Mon Sep 17 00:00:00 2001 From: Julian Krings Date: Wed, 27 Aug 2025 12:34:52 +0200 Subject: [PATCH] minor optimizations --- .../iris/engine/mantle/EngineMantle.java | 83 +++++++------------ .../iris/engine/mantle/MantleWriter.java | 41 ++++++++- .../iris/util/parallel/StreamUtils.java | 34 ++++++++ 3 files changed, 100 insertions(+), 58 deletions(-) create mode 100644 core/src/main/java/com/volmit/iris/util/parallel/StreamUtils.java diff --git a/core/src/main/java/com/volmit/iris/engine/mantle/EngineMantle.java b/core/src/main/java/com/volmit/iris/engine/mantle/EngineMantle.java index 617eeb49b..f45fe8787 100644 --- a/core/src/main/java/com/volmit/iris/engine/mantle/EngineMantle.java +++ b/core/src/main/java/com/volmit/iris/engine/mantle/EngineMantle.java @@ -26,31 +26,30 @@ import com.volmit.iris.engine.framework.Engine; import com.volmit.iris.engine.framework.EngineTarget; import com.volmit.iris.engine.mantle.components.MantleJigsawComponent; import com.volmit.iris.engine.mantle.components.MantleObjectComponent; -import com.volmit.iris.engine.object.IObjectPlacer; import com.volmit.iris.engine.object.IrisDimension; import com.volmit.iris.engine.object.IrisPosition; -import com.volmit.iris.engine.object.TileData; import com.volmit.iris.util.collection.KList; import com.volmit.iris.util.context.ChunkContext; import com.volmit.iris.util.context.IrisContext; import com.volmit.iris.util.data.B; -import com.volmit.iris.util.data.IrisCustomData; import com.volmit.iris.util.documentation.BlockCoordinates; import com.volmit.iris.util.documentation.ChunkCoordinates; import com.volmit.iris.util.hunk.Hunk; import com.volmit.iris.util.mantle.Mantle; import com.volmit.iris.util.mantle.MantleChunk; import com.volmit.iris.util.mantle.MantleFlag; +import com.volmit.iris.util.math.Position2; import com.volmit.iris.util.matter.*; import com.volmit.iris.util.matter.slices.UpdateMatter; -import com.volmit.iris.util.parallel.BurstExecutor; import com.volmit.iris.util.parallel.MultiBurst; import org.bukkit.block.data.BlockData; import java.util.concurrent.TimeUnit; -// TODO: MOVE PLACER OUT OF MATTER INTO ITS OWN THING -public interface EngineMantle extends IObjectPlacer { +import static com.volmit.iris.util.parallel.StreamUtils.forEach; +import static com.volmit.iris.util.parallel.StreamUtils.streamRadius; + +public interface EngineMantle { BlockData AIR = B.get("AIR"); Mantle getMantle(); @@ -87,12 +86,10 @@ public interface EngineMantle extends IObjectPlacer { return getHighest(x, z, getData(), ignoreFluid); } - @Override default int getHighest(int x, int z, IrisData data) { return getHighest(x, z, data, false); } - @Override default int getHighest(int x, int z, IrisData data, boolean ignoreFluid) { return ignoreFluid ? trueHeight(x, z) : Math.max(trueHeight(x, z), getEngine().getDimension().getFluidHeight()); } @@ -101,24 +98,12 @@ public interface EngineMantle extends IObjectPlacer { return getComplex().getRoundedHeighteightStream().get(x, z); } + @Deprecated(forRemoval = true) default boolean isCarved(int x, int h, int z) { return getMantle().get(x, h, z, MatterCavern.class) != null; } - @Override - default void set(int x, int y, int z, BlockData d) { - if (d instanceof IrisCustomData data) { - getMantle().set(x, y, z, data.getBase()); - getMantle().set(x, y, z, data.getCustom()); - } else getMantle().set(x, y, z, d == null ? AIR : d); - } - - @Override - default void setTile(int x, int y, int z, TileData d) { - getMantle().set(x, y, z, new TileWrapper(d)); - } - - @Override + @Deprecated(forRemoval = true) default BlockData get(int x, int y, int z) { BlockData block = getMantle().get(x, y, z, BlockData.class); if (block == null) @@ -126,27 +111,18 @@ public interface EngineMantle extends IObjectPlacer { return block; } - @Override default boolean isPreventingDecay() { return getEngine().getDimension().isPreventLeafDecay(); } - @Override - default boolean isSolid(int x, int y, int z) { - return B.isSolid(get(x, y, z)); - } - - @Override default boolean isUnderwater(int x, int z) { return getHighest(x, z, true) <= getFluidHeight(); } - @Override default int getFluidHeight() { return getEngine().getDimension().getFluidHeight(); } - @Override default boolean isDebugSmartBore() { return getEngine().getDimension().isDebugSmartBore(); } @@ -206,32 +182,31 @@ public interface EngineMantle extends IObjectPlacer { var pair = iterator.next(); int radius = pair.getB(); boolean last = !iterator.hasNext(); - BurstExecutor burst = burst().burst((radius * 2 + 1) * pair.getA().size()); - burst.setMulticore(multicore); - - for (int i = -radius; i <= radius; i++) { - for (int j = -radius; j <= radius; j++) { - int xx = x + i; - int zz = z + j; - MantleChunk mc = getMantle().getChunk(xx, zz).use(); - for (MantleComponent c : pair.getA()) { - burst.queue(() -> { + forEach(streamRadius(x, z, radius), + pos -> pair.getA() + .stream() + .map(c -> new Pair<>(c, pos)), + p -> { + MantleComponent c = p.getA(); + Position2 pos = p.getB(); + int xx = pos.getX(); + int zz = pos.getZ(); + MantleChunk mc = getMantle().getChunk(xx, zz).use(); + try { IrisContext.getOr(getEngine()).setChunkContext(context); generateMantleComponent(writer, xx, zz, c, mc, context); - }); - } - } - } + } finally { + mc.release(); + } + }, + multicore ? burst() : null + ); - burst.complete(); - - for (int i = -radius; i <= radius; i++) { - for (int j = -radius; j <= radius; j++) { - var chunk = getMantle().getChunk(x + i, z + j); - if (last) chunk.flag(MantleFlag.PLANNED, true); - chunk.release(); - } - } + if (!last) continue; + forEach(streamRadius(x, z, radius), + p -> getMantle().flag(p.getX(), p.getZ(), MantleFlag.PLANNED, true), + multicore ? burst() : null + ); } } } diff --git a/core/src/main/java/com/volmit/iris/engine/mantle/MantleWriter.java b/core/src/main/java/com/volmit/iris/engine/mantle/MantleWriter.java index ee2c9bf2d..d9f39c9c2 100644 --- a/core/src/main/java/com/volmit/iris/engine/mantle/MantleWriter.java +++ b/core/src/main/java/com/volmit/iris/engine/mantle/MantleWriter.java @@ -29,12 +29,15 @@ import com.volmit.iris.engine.object.IrisPosition; import com.volmit.iris.engine.object.TileData; import com.volmit.iris.util.collection.KMap; import com.volmit.iris.util.collection.KSet; +import com.volmit.iris.util.data.B; import com.volmit.iris.util.data.IrisCustomData; import com.volmit.iris.util.function.Function3; import com.volmit.iris.util.mantle.Mantle; import com.volmit.iris.util.mantle.MantleChunk; import com.volmit.iris.util.math.RNG; import com.volmit.iris.util.matter.Matter; +import com.volmit.iris.util.matter.MatterCavern; +import com.volmit.iris.util.matter.TileWrapper; import com.volmit.iris.util.noise.CNG; import lombok.Data; import org.bukkit.block.data.BlockData; @@ -44,6 +47,8 @@ import java.util.HashSet; import java.util.List; import java.util.Set; +import static com.volmit.iris.engine.mantle.EngineMantle.AIR; + @Data public class MantleWriter implements IObjectPlacer, AutoCloseable { private final EngineMantle engineMantle; @@ -160,6 +165,31 @@ public class MantleWriter implements IObjectPlacer, AutoCloseable { } } + public T getData(int x, int y, int z, Class type) { + int cx = x >> 4; + int cz = z >> 4; + + if (y < 0 || y >= mantle.getWorldHeight()) { + return null; + } + + if (cx < this.x - radius || cx > this.x + radius + || cz < this.z - radius || cz > this.z + radius) { + Iris.error("Mantle Writer Accessed chunk out of bounds" + cx + "," + cz); + return null; + } + MantleChunk chunk = cachedChunks.computeIfAbsent(Cache.key(cx, cz), k -> mantle.getChunk(cx, cz).use()); + + if (chunk == null) { + Iris.error("Mantle Writer Accessed " + cx + "," + cz + " and came up null (and yet within bounds!)"); + return null; + } + + return chunk.getOrCreate(y >> 4) + .slice(type) + .get(x & 15, y & 15, z & 15); + } + @Override public int getHighest(int x, int z, IrisData data) { return engineMantle.getHighest(x, z, data); @@ -180,7 +210,10 @@ public class MantleWriter implements IObjectPlacer, AutoCloseable { @Override public BlockData get(int x, int y, int z) { - return getEngineMantle().get(x, y, z); + BlockData block = getData(x, y, z, BlockData.class); + if (block == null) + return AIR; + return block; } @Override @@ -190,12 +223,12 @@ public class MantleWriter implements IObjectPlacer, AutoCloseable { @Override public boolean isCarved(int x, int y, int z) { - return getEngineMantle().isCarved(x, y, z); + return getData(x, y, z, MatterCavern.class) != null; } @Override public boolean isSolid(int x, int y, int z) { - return getEngineMantle().isSolid(x, y, z); + return B.isSolid(get(x, y, z)); } @Override @@ -215,7 +248,7 @@ public class MantleWriter implements IObjectPlacer, AutoCloseable { @Override public void setTile(int xx, int yy, int zz, TileData tile) { - getEngineMantle().setTile(xx, yy, zz, tile); + setData(xx, yy, zz, new TileWrapper(tile)); } @Override diff --git a/core/src/main/java/com/volmit/iris/util/parallel/StreamUtils.java b/core/src/main/java/com/volmit/iris/util/parallel/StreamUtils.java new file mode 100644 index 000000000..0c88d0d35 --- /dev/null +++ b/core/src/main/java/com/volmit/iris/util/parallel/StreamUtils.java @@ -0,0 +1,34 @@ +package com.volmit.iris.util.parallel; + +import com.volmit.iris.util.math.Position2; +import lombok.SneakyThrows; +import org.jetbrains.annotations.Nullable; + +import java.util.function.Consumer; +import java.util.function.Function; +import java.util.stream.IntStream; +import java.util.stream.Stream; + +public class StreamUtils { + + public static Stream streamRadius(int x, int z, int radius) { + return streamRadius(x, z, radius, radius); + } + + public static Stream streamRadius(int x, int z, int radiusX, int radiusZ) { + return IntStream.rangeClosed(-radiusX, radiusX) + .mapToObj(xx -> IntStream.rangeClosed(-radiusZ, radiusZ) + .mapToObj(zz -> new Position2(x + xx, z + zz))) + .flatMap(Function.identity()); + } + + public static void forEach(Stream stream, Function> mapper, Consumer consumer, @Nullable MultiBurst burst) { + forEach(stream.flatMap(mapper), consumer, burst); + } + + @SneakyThrows + public static void forEach(Stream stream, Consumer task, @Nullable MultiBurst burst) { + if (burst == null) stream.forEach(task); + else burst.submit(() -> stream.parallel().forEach(task)).get(); + } +}