From dbf1c8f10fe235f16f3c7b66b617ab6bd35bd655 Mon Sep 17 00:00:00 2001 From: Dennis C Date: Thu, 30 Jun 2022 14:21:18 +0200 Subject: [PATCH] [1.18.x] Allow safely registering RenderType predicates at any time (#8671) * Allow safely registering RenderType predicates at any time * Requested changes --- .../renderer/ItemBlockRenderTypes.java.patch | 69 +++++++++++++++---- 1 file changed, 55 insertions(+), 14 deletions(-) diff --git a/patches/minecraft/net/minecraft/client/renderer/ItemBlockRenderTypes.java.patch b/patches/minecraft/net/minecraft/client/renderer/ItemBlockRenderTypes.java.patch index e68d1475ce..6a724cb2e0 100644 --- a/patches/minecraft/net/minecraft/client/renderer/ItemBlockRenderTypes.java.patch +++ b/patches/minecraft/net/minecraft/client/renderer/ItemBlockRenderTypes.java.patch @@ -42,7 +42,7 @@ if (!Minecraft.m_91085_()) { return Sheets.m_110792_(); } else { -@@ -340,9 +_,70 @@ +@@ -340,9 +_,111 @@ } } @@ -55,8 +55,11 @@ + // FORGE START + + private static final java.util.function.Predicate SOLID_PREDICATE = type -> type == RenderType.m_110451_(); ++ // Access to the two following editable maps is guarded by synchronization and they are lazily copied to the "readonly" maps on first read after modification + private static final Map, java.util.function.Predicate> blockRenderChecks = createRenderCheckMap(f_109275_); + private static final Map, java.util.function.Predicate> fluidRenderChecks = createRenderCheckMap(f_109276_); ++ @org.jetbrains.annotations.Nullable private static volatile Map, java.util.function.Predicate> blockRenderChecksReadOnly = null; ++ @org.jetbrains.annotations.Nullable private static volatile Map, java.util.function.Predicate> fluidRenderChecksReadOnly = null; + + private static > Map, java.util.function.Predicate> createRenderCheckMap( + Map vanillaMap @@ -74,37 +77,75 @@ + if (block instanceof LeavesBlock) { + return f_109277_ ? type == RenderType.m_110457_() : type == RenderType.m_110451_(); + } else { -+ return blockRenderChecks.get(block.delegate).test(type); ++ return getBlockLayerPredicates().get(block.delegate).test(type); + } + } + + public static boolean canRenderInLayer(FluidState fluid, RenderType type) { -+ return fluidRenderChecks.get(fluid.m_76152_().delegate).test(type); ++ return getFluidLayerPredicates().get(fluid.m_76152_().delegate).test(type); + } + + public static void setRenderLayer(Block block, RenderType type) { + setRenderLayer(block, createMatchingLayerPredicate(type)); + } + -+ public static synchronized void setRenderLayer(Block block, java.util.function.Predicate predicate) { -+ checkClientLoading(); -+ blockRenderChecks.put(block.delegate, predicate); ++ public static void setRenderLayer(Block block, java.util.function.Predicate predicate) { ++ synchronized (blockRenderChecks) { ++ blockRenderChecks.put(block.delegate, predicate); ++ blockRenderChecksReadOnly = null; ++ } + } + + public static void setRenderLayer(Fluid fluid, RenderType type) { + setRenderLayer(fluid, createMatchingLayerPredicate(type)); + } + -+ public static synchronized void setRenderLayer(Fluid fluid, java.util.function.Predicate predicate) { -+ checkClientLoading(); -+ fluidRenderChecks.put(fluid.delegate, predicate); ++ public static void setRenderLayer(Fluid fluid, java.util.function.Predicate predicate) { ++ synchronized (fluidRenderChecks) { ++ fluidRenderChecks.put(fluid.delegate, predicate); ++ fluidRenderChecksReadOnly = null; ++ } + } + -+ private static void checkClientLoading() { -+ com.google.common.base.Preconditions.checkState(net.minecraftforge.client.loading.ClientModLoader.isLoading(), -+ "Render layers can only be set during client loading! " + -+ "This might ideally be done from `FMLClientSetupEvent`." -+ ); ++ public static Map, java.util.function.Predicate> getBlockLayerPredicatesView() { ++ return java.util.Collections.unmodifiableMap(getBlockLayerPredicates()); ++ } ++ ++ private static Map, java.util.function.Predicate> getBlockLayerPredicates() { ++ Map, java.util.function.Predicate> map = blockRenderChecksReadOnly; ++ if (map == null) { ++ synchronized (blockRenderChecks) { ++ map = blockRenderChecksReadOnly; ++ if (map == null) { ++ blockRenderChecksReadOnly = map = copy(blockRenderChecks); ++ } ++ } ++ } ++ return map; ++ } ++ ++ ++ public static Map, java.util.function.Predicate> getFluidLayerPredicatesView() { ++ return java.util.Collections.unmodifiableMap(getFluidLayerPredicates()); ++ } ++ ++ private static Map, java.util.function.Predicate> getFluidLayerPredicates() { ++ Map, java.util.function.Predicate> map = fluidRenderChecksReadOnly; ++ if (map == null) { ++ synchronized (fluidRenderChecks) { ++ map = fluidRenderChecksReadOnly; ++ if (map == null) { ++ fluidRenderChecksReadOnly = map = copy(fluidRenderChecks); ++ } ++ } ++ } ++ return map; ++ } ++ ++ private static Map, java.util.function.Predicate> copy(Map, java.util.function.Predicate> map) { ++ var newMap = new it.unimi.dsi.fastutil.objects.Object2ObjectOpenHashMap<>(map); ++ newMap.defaultReturnValue(SOLID_PREDICATE); ++ return newMap; + } + + private static java.util.function.Predicate createMatchingLayerPredicate(RenderType type) {