From 7599f727b7525b49446ec8e6170a1ebf79d38888 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tr=E1=BA=A7n=20Nguy=E1=BB=85n=20Ng=E1=BB=8Dc=20Quang?= <3d7777456@gmail.com> Date: Wed, 2 Oct 2024 05:13:54 +0700 Subject: [PATCH] Count fluids by their type to avoid uncessary reads in Entity#updateFluidHeightAndDoFluidPushing We can take fluid counts in a chunk section into account to avoid unnecessary searches as we were only checking for non empty blocks. --- .../fabric/mixin/collisions/EntityMixin.java | 17 ++++++ .../mixin/collisions/EntityMixin.java | 9 ++++ .../LevelChunkSectionMixin.java | 53 +++++++++++++++++++ .../BlockCountingChunkSection.java | 4 ++ 4 files changed, 83 insertions(+) diff --git a/fabric/src/main/java/ca/spottedleaf/moonrise/fabric/mixin/collisions/EntityMixin.java b/fabric/src/main/java/ca/spottedleaf/moonrise/fabric/mixin/collisions/EntityMixin.java index bc489da3..47c47f73 100644 --- a/fabric/src/main/java/ca/spottedleaf/moonrise/fabric/mixin/collisions/EntityMixin.java +++ b/fabric/src/main/java/ca/spottedleaf/moonrise/fabric/mixin/collisions/EntityMixin.java @@ -1,8 +1,10 @@ package ca.spottedleaf.moonrise.fabric.mixin.collisions; +import ca.spottedleaf.moonrise.patches.block_counting.BlockCountingChunkSection; import ca.spottedleaf.moonrise.patches.getblock.GetBlockLevel; import it.unimi.dsi.fastutil.objects.Object2DoubleMap; import net.minecraft.core.BlockPos; +import net.minecraft.tags.FluidTags; import net.minecraft.tags.TagKey; import net.minecraft.util.Mth; import net.minecraft.world.entity.Entity; @@ -107,6 +109,21 @@ public boolean updateFluidHeightAndDoFluidPushing(final TagKey fluid, fin continue; } + final BlockCountingChunkSection blockCountingSection = (BlockCountingChunkSection)section; + final boolean hasFluids; + if (fluid == FluidTags.LAVA) { + hasFluids = blockCountingSection.moonrise$hasLavaFluids(); + } else if (fluid == FluidTags.WATER) { + hasFluids = blockCountingSection.moonrise$hasWaterFluids(); + } else { + hasFluids = false; + } + + if (!hasFluids) { + // also empty + continue; + } + final PalettedContainer blocks = section.states; final int minXIterate = currChunkX == minChunkX ? (minBlockX & 15) : 0; diff --git a/neoforge/src/main/java/ca/spottedleaf/moonrise/neoforge/mixin/collisions/EntityMixin.java b/neoforge/src/main/java/ca/spottedleaf/moonrise/neoforge/mixin/collisions/EntityMixin.java index 6e10f2f5..3576eaa0 100644 --- a/neoforge/src/main/java/ca/spottedleaf/moonrise/neoforge/mixin/collisions/EntityMixin.java +++ b/neoforge/src/main/java/ca/spottedleaf/moonrise/neoforge/mixin/collisions/EntityMixin.java @@ -1,6 +1,7 @@ package ca.spottedleaf.moonrise.neoforge.mixin.collisions; import ca.spottedleaf.moonrise.neoforge.patches.collisions.FluidPushCalculation; +import ca.spottedleaf.moonrise.patches.block_counting.BlockCountingChunkSection; import ca.spottedleaf.moonrise.patches.getblock.GetBlockLevel; import it.unimi.dsi.fastutil.objects.Reference2ReferenceArrayMap; import it.unimi.dsi.fastutil.objects.Reference2ReferenceMap; @@ -101,6 +102,14 @@ public void updateFluidHeightAndDoFluidPushing() { continue; } + final BlockCountingChunkSection blockCountingSection = (BlockCountingChunkSection)section; + final boolean hasFluids = blockCountingSection.moonrise$hasLavaFluids() || blockCountingSection.moonrise$hasWaterFluids(); + + if (!hasFluids) { + // also empty + continue; + } + final PalettedContainer blocks = section.states; final int minXIterate = currChunkX == minChunkX ? (minBlockX & 15) : 0; diff --git a/src/main/java/ca/spottedleaf/moonrise/mixin/block_counting/LevelChunkSectionMixin.java b/src/main/java/ca/spottedleaf/moonrise/mixin/block_counting/LevelChunkSectionMixin.java index 990bd8f5..73232039 100644 --- a/src/main/java/ca/spottedleaf/moonrise/mixin/block_counting/LevelChunkSectionMixin.java +++ b/src/main/java/ca/spottedleaf/moonrise/mixin/block_counting/LevelChunkSectionMixin.java @@ -9,6 +9,7 @@ import it.unimi.dsi.fastutil.ints.Int2ObjectOpenHashMap; import it.unimi.dsi.fastutil.shorts.ShortArrayList; import net.minecraft.util.BitStorage; +import net.minecraft.tags.FluidTags; import net.minecraft.world.level.block.state.BlockState; import net.minecraft.world.level.chunk.LevelChunkSection; import net.minecraft.world.level.chunk.Palette; @@ -64,6 +65,12 @@ abstract class LevelChunkSectionMixin implements BlockCountingChunkSection { @Unique private short specialCollidingBlocks; + @Unique + private short lavaFluids; + + @Unique + private short waterFluids; + @Unique private final ShortList tickingBlocks = new ShortList(); @@ -77,6 +84,16 @@ abstract class LevelChunkSectionMixin implements BlockCountingChunkSection { return this.tickingBlocks; } + @Override + public final boolean moonrise$hasLavaFluids() { + return this.lavaFluids != 0; + } + + @Override + public final boolean moonrise$hasWaterFluids() { + return this.waterFluids != 0; + } + /** * @reason Callback used to update block counts on block change. * @author Spottedleaf @@ -122,6 +139,34 @@ private void updateBlockCallback(final int x, final int y, final int z, final Bl tickingBlocks.add(position); } } + + if (!oldState.getFluidState().isEmpty() || !newState.getFluidState().isEmpty()) { + boolean fluidChecked = false; + final boolean isOldLava = oldState.getFluidState().is(FluidTags.LAVA); + final boolean isNewLava = newState.getFluidState().is(FluidTags.LAVA); + + if (isOldLava != isNewLava) { + if (isOldLava) { + --this.lavaFluids; + } else { + ++this.lavaFluids; + } + fluidChecked = true; + } + + if (!fluidChecked) { + final boolean isOldWater = oldState.getFluidState().is(FluidTags.WATER); + final boolean isNewWater = newState.getFluidState().is(FluidTags.WATER); + + if (isOldWater != isNewWater) { + if (isOldWater) { + --this.waterFluids; + } else { + ++this.waterFluids; + } + } + } + } } /** @@ -150,6 +195,8 @@ public void recalcBlockCounts() { this.tickingBlockCount = (short)0; this.tickingFluidCount = (short)0; this.specialCollidingBlocks = (short)0; + this.lavaFluids = (short)0; + this.waterFluids = (short)0; this.tickingBlocks.clear(); if (this.maybeHas((final BlockState state) -> !state.isAir())) { @@ -204,6 +251,12 @@ public void recalcBlockCounts() { if (fluid.isRandomlyTicking()) { this.tickingFluidCount += (short)paletteCount; } + + if (fluid.is(FluidTags.LAVA)) { + this.lavaFluids += (short)paletteCount; + } else if (fluid.is(FluidTags.WATER)) { + this.waterFluids += (short)paletteCount; + } } } } diff --git a/src/main/java/ca/spottedleaf/moonrise/patches/block_counting/BlockCountingChunkSection.java b/src/main/java/ca/spottedleaf/moonrise/patches/block_counting/BlockCountingChunkSection.java index 0d1443a1..b3035773 100644 --- a/src/main/java/ca/spottedleaf/moonrise/patches/block_counting/BlockCountingChunkSection.java +++ b/src/main/java/ca/spottedleaf/moonrise/patches/block_counting/BlockCountingChunkSection.java @@ -8,4 +8,8 @@ public interface BlockCountingChunkSection { public ShortList moonrise$getTickingBlockList(); + public boolean moonrise$hasLavaFluids(); + + public boolean moonrise$hasWaterFluids(); + }