From b85918161670eb16a4d8b10500ba5731485737aa Mon Sep 17 00:00:00 2001 From: Julian Chang Date: Tue, 29 Sep 2026 09:17:45 -0400 Subject: [PATCH] improve sign caching --- .../mixin/blockentity/sign/SignTextMixin.java | 27 +++++++++++++++++++ .../SpecialBlockEntityRenderingManager.java | 8 +++++- .../renderer/blockentity/ext/SignTextExt.java | 5 ++++ src/client/resources/obe.client.mixins.json | 1 + 4 files changed, 40 insertions(+), 1 deletion(-) create mode 100644 src/client/java/fr/madu59/obe/client/mixin/blockentity/sign/SignTextMixin.java create mode 100644 src/client/java/fr/madu59/obe/client/renderer/blockentity/ext/SignTextExt.java diff --git a/src/client/java/fr/madu59/obe/client/mixin/blockentity/sign/SignTextMixin.java b/src/client/java/fr/madu59/obe/client/mixin/blockentity/sign/SignTextMixin.java new file mode 100644 index 00000000..09ca702f --- /dev/null +++ b/src/client/java/fr/madu59/obe/client/mixin/blockentity/sign/SignTextMixin.java @@ -0,0 +1,27 @@ +package fr.madu59.obe.client.mixin.blockentity.sign; + +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.Unique; + +import fr.madu59.obe.client.renderer.blockentity.ext.SignTextExt; +import net.minecraft.world.level.block.entity.SignText; + +// SignText is immutable (edits return a new instance), so hasMessage can be computed once per instance +// instead of streaming and stringifying every line on every frame +@Mixin(SignText.class) +public abstract class SignTextMixin implements SignTextExt { + @Unique private static final byte UNKNOWN = 0, EMPTY = 1, PRESENT = 2; + @Unique private byte hasMessage = UNKNOWN; + @Unique private byte hasFilteredMessage = UNKNOWN; + + @Override + public boolean obe$hasMessage(boolean filtered) { + byte cached = filtered ? hasFilteredMessage : hasMessage; + if (cached == UNKNOWN) { + cached = ((SignText) (Object) this).hasMessage(filtered) ? PRESENT : EMPTY; + if (filtered) hasFilteredMessage = cached; + else hasMessage = cached; + } + return cached == PRESENT; + } +} diff --git a/src/client/java/fr/madu59/obe/client/renderer/blockentity/SpecialBlockEntityRenderingManager.java b/src/client/java/fr/madu59/obe/client/renderer/blockentity/SpecialBlockEntityRenderingManager.java index 5bfbe5e2..6f754fa2 100644 --- a/src/client/java/fr/madu59/obe/client/renderer/blockentity/SpecialBlockEntityRenderingManager.java +++ b/src/client/java/fr/madu59/obe/client/renderer/blockentity/SpecialBlockEntityRenderingManager.java @@ -3,6 +3,7 @@ import java.util.List; import fr.madu59.obe.client.config.SettingsManager; +import fr.madu59.obe.client.renderer.blockentity.ext.SignTextExt; import net.minecraft.client.Minecraft; import net.minecraft.world.item.ItemStack; import net.minecraft.world.level.block.entity.BeaconBlockEntity; @@ -10,6 +11,7 @@ import net.minecraft.world.level.block.entity.CampfireBlockEntity; import net.minecraft.world.level.block.entity.ShelfBlockEntity; import net.minecraft.world.level.block.entity.SignBlockEntity; +import net.minecraft.world.level.block.entity.SignText; import net.minecraft.world.level.block.entity.SignTextSlot; public class SpecialBlockEntityRenderingManager { @@ -41,6 +43,10 @@ private static boolean isContainerEmpty(List items) { private static boolean isEmpty(SignBlockEntity be){ boolean shouldFilter = Minecraft.getInstance().isTextFilteringEnabled(); - return (be.getText(SignTextSlot.FRONT) == null || !be.getText(SignTextSlot.FRONT).hasMessage(shouldFilter)) && (be.getText(SignTextSlot.BACK) == null || !be.getText(SignTextSlot.BACK).hasMessage(shouldFilter)); + return !hasMessage(be.getText(SignTextSlot.FRONT), shouldFilter) && !hasMessage(be.getText(SignTextSlot.BACK), shouldFilter); + } + + private static boolean hasMessage(SignText text, boolean filtered){ + return text != null && ((SignTextExt) text).obe$hasMessage(filtered); } } diff --git a/src/client/java/fr/madu59/obe/client/renderer/blockentity/ext/SignTextExt.java b/src/client/java/fr/madu59/obe/client/renderer/blockentity/ext/SignTextExt.java new file mode 100644 index 00000000..78a93f96 --- /dev/null +++ b/src/client/java/fr/madu59/obe/client/renderer/blockentity/ext/SignTextExt.java @@ -0,0 +1,5 @@ +package fr.madu59.obe.client.renderer.blockentity.ext; + +public interface SignTextExt { + boolean obe$hasMessage(boolean filtered); +} diff --git a/src/client/resources/obe.client.mixins.json b/src/client/resources/obe.client.mixins.json index 751543e8..6bb9aea1 100644 --- a/src/client/resources/obe.client.mixins.json +++ b/src/client/resources/obe.client.mixins.json @@ -12,6 +12,7 @@ "blockentity.decoratedpot.DecoratedPotBlockEntityMixin", "blockentity.shulkerbox.ShulkerBoxBlockEntityMixin", "blockentity.lectern.LecternBlockEntityMixin", + "blockentity.sign.SignTextMixin", "blockentity.compat.lootr.LootrChestBlockEntityMixin", "blockentity.compat.lootr.LootrShulkerBoxBlockEntityMixin", "blockentity.BlockEntityMixin",