From b6b26d9dac517bdfcca29c885de0bf706c125345 Mon Sep 17 00:00:00 2001 From: Julian Chang Date: Tue, 29 Sep 2026 09:18:06 -0400 Subject: [PATCH] improve sign caching --- .../mixin/blockentity/sign/SignTextMixin.java | 34 +++++++++++++++++++ .../SpecialBlockEntityRenderingManager.java | 9 ++++- .../renderer/blockentity/ext/SignTextExt.java | 5 +++ src/client/resources/obe.client.mixins.json | 1 + 4 files changed, 48 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..ccc219ad --- /dev/null +++ b/src/client/java/fr/madu59/obe/client/mixin/blockentity/sign/SignTextMixin.java @@ -0,0 +1,34 @@ +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.network.chat.Component; +import net.minecraft.world.level.block.entity.SignText; + +// SignText is immutable (edits return a new instance), so whether it has a message 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 = EMPTY; + for (Component line : ((SignText) (Object) this).getMessages(filtered)) { + if (!line.getString().isEmpty()) { + cached = PRESENT; + break; + } + } + 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 f143b8db..2fc32aa1 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 @@ -12,6 +12,8 @@ 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 fr.madu59.obe.client.renderer.blockentity.ext.SignTextExt; +import net.minecraft.world.level.block.entity.SignText; public class SpecialBlockEntityRenderingManager { public static boolean shouldSkipRendering(BlockEntity be) { @@ -42,6 +44,11 @@ private static boolean isContainerEmpty(List items) { private static boolean isEmpty(SignBlockEntity be){ LocalPlayer player = Minecraft.getInstance().player; - return (be.getText(true) == null || !be.getText(true).hasMessage(player)) && (be.getText(false) == null || !be.getText(false).hasMessage(player)); + boolean shouldFilter = player.isTextFilteringEnabled(); + return !hasMessage(be.getText(true), shouldFilter) && !hasMessage(be.getText(false), 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 2497c908..a33af6e4 100644 --- a/src/client/resources/obe.client.mixins.json +++ b/src/client/resources/obe.client.mixins.json @@ -14,6 +14,7 @@ "blockentity.decoratedpot.DecoratedPotBlockEntityMixin", "blockentity.shulkerbox.ShulkerBoxBlockEntityMixin", "blockentity.lectern.LecternBlockEntityMixin", + "blockentity.sign.SignTextMixin", "blockentity.compat.lootr.LootrChestBlockEntityMixin", "blockentity.compat.lootr.LootrShulkerBoxBlockEntityMixin", "blockentity.BlockEntityMixin",