From 97130d1535915be95fe80baedd9118397f4f7077 Mon Sep 17 00:00:00 2001 From: James Seibel Date: Tue, 28 Oct 2025 07:35:26 -0500 Subject: [PATCH] minor optimization to tint getting --- .../wrappers/block/AbstractDhTintGetter.java | 123 ++++++++++++++---- .../block/ClientBlockStateColorCache.java | 96 +++++++------- .../wrappers/block/TintGetterOverride.java | 10 +- .../block/TintWithoutLevelOverrider.java | 5 +- .../wrappers/world/ClientLevelWrapper.java | 12 +- coreSubProjects | 2 +- 6 files changed, 164 insertions(+), 84 deletions(-) diff --git a/common/src/main/java/com/seibel/distanthorizons/common/wrappers/block/AbstractDhTintGetter.java b/common/src/main/java/com/seibel/distanthorizons/common/wrappers/block/AbstractDhTintGetter.java index a088fd5b4..aaddc1ec3 100644 --- a/common/src/main/java/com/seibel/distanthorizons/common/wrappers/block/AbstractDhTintGetter.java +++ b/common/src/main/java/com/seibel/distanthorizons/common/wrappers/block/AbstractDhTintGetter.java @@ -18,9 +18,12 @@ import net.minecraft.world.level.biome.Biome; import java.io.IOException; import java.util.concurrent.ConcurrentHashMap; -import java.util.concurrent.ConcurrentMap; + import com.seibel.distanthorizons.core.logging.DhLogger; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; + #if MC_VER >= MC_1_18_2 import net.minecraft.core.Holder; #endif @@ -30,26 +33,36 @@ public abstract class AbstractDhTintGetter implements BlockAndTintGetter { private static final DhLogger LOGGER = new DhLoggerBuilder().build(); - - protected final BiomeWrapper biomeWrapper; - - protected final int smoothingRadiusInBlocks; - protected final FullDataSourceV2 fullDataSource; - protected final IClientLevelWrapper clientLevelWrapper; - #if MC_VER < MC_1_18_2 - public static final ConcurrentMap BIOME_BY_RESOURCE_STRING = new ConcurrentHashMap<>(); + private static final ConcurrentHashMap BIOME_BY_RESOURCE_STRING = new ConcurrentHashMap<>(); #else - public static final ConcurrentMap> BIOME_BY_RESOURCE_STRING = new ConcurrentHashMap<>(); + private static final ConcurrentHashMap> BIOME_BY_RESOURCE_STRING = new ConcurrentHashMap<>(); #endif + private static final ConcurrentHashMap COLOR_BY_BIOME = new ConcurrentHashMap<>(); + + /** returned if the color cache is incomplete */ + public static final int INVALID_COLOR = Integer.MIN_VALUE; + + + protected BiomeWrapper biomeWrapper; + protected FullDataSourceV2 fullDataSource; + protected int smoothingRadiusInBlocks; + protected IClientLevelWrapper clientLevelWrapper; + //=============// // constructor // //=============// - public AbstractDhTintGetter(BiomeWrapper biomeWrapper, FullDataSourceV2 fullDataSource, IClientLevelWrapper clientLevelWrapper) + public AbstractDhTintGetter() { } + + /** + * Mutates this getter so we can access the necessary + * variables for tint getting. + */ + public void update(BiomeWrapper biomeWrapper, FullDataSourceV2 fullDataSource, IClientLevelWrapper clientLevelWrapper) { this.biomeWrapper = biomeWrapper; this.fullDataSource = fullDataSource; @@ -63,8 +76,27 @@ public abstract class AbstractDhTintGetter implements BlockAndTintGetter // shared methods // //================// + /** Called by MC's tint getter */ @Override - public int getBlockTint(BlockPos blockPos, ColorResolver colorResolver) + public int getBlockTint(@NotNull BlockPos blockPos, @NotNull ColorResolver colorResolver) + { + DhBlockPosMutable mutableBlockPos = new DhBlockPosMutable(blockPos.getX(), blockPos.getY(), blockPos.getZ()); + return this.tryGetBlockTint(mutableBlockPos, colorResolver); + } + + /** + * Can be called by DH directly, skipping some of MC's logic + * to speed up tint getting slightly. + * + * @return {@link AbstractDhTintGetter#INVALID_COLOR} if any of the biomes needed for this position + * were not cached. In that case calling {@link AbstractDhTintGetter#getBlockTint(BlockPos, ColorResolver)} + * will need to be called by MC's ColorResolver so we can + * populate the color cache. + */ + public int tryGetBlockTint(DhBlockPosMutable mutableBlockPos) + { return this.tryGetBlockTint(mutableBlockPos, null); } + + private int tryGetBlockTint(DhBlockPosMutable mutableBlockPos, @Nullable ColorResolver colorResolver) { // determine how wide this data source is so we can determine // if blending should be used @@ -78,7 +110,7 @@ public abstract class AbstractDhTintGetter implements BlockAndTintGetter if (this.smoothingRadiusInBlocks == 0 || dataSourceLodWidthInBlocks > this.smoothingRadiusInBlocks) { - return colorResolver.getColor(unwrapClientBiome(this.biomeWrapper.biome, this.clientLevelWrapper), blockPos.getX(), blockPos.getZ()); + return this.tryGetClientBiomeColor(colorResolver, this.biomeWrapper); } @@ -88,13 +120,13 @@ public abstract class AbstractDhTintGetter implements BlockAndTintGetter int rollingGreen = 0; int rollingBlue = 0; - int xMin = blockPos.getX() - this.smoothingRadiusInBlocks; - int xMax = blockPos.getX() + this.smoothingRadiusInBlocks; + int xMin = mutableBlockPos.getX() - this.smoothingRadiusInBlocks; + int xMax = mutableBlockPos.getX() + this.smoothingRadiusInBlocks; + + int zMin = mutableBlockPos.getZ() - this.smoothingRadiusInBlocks; + int zMax = mutableBlockPos.getZ() + this.smoothingRadiusInBlocks; - int zMin = blockPos.getZ() - this.smoothingRadiusInBlocks; - int zMax = blockPos.getZ() + this.smoothingRadiusInBlocks; - DhBlockPosMutable mutableBlockPos = new DhBlockPosMutable(0, blockPos.getY(), 0); for (int x = xMin; x < xMax; x++) { for (int z = zMin; z < zMax; z++) @@ -114,7 +146,11 @@ public abstract class AbstractDhTintGetter implements BlockAndTintGetter // get the color for this nearby position int id = FullDataPointUtil.getId(dataPoint); BiomeWrapper biomeWrapper = (BiomeWrapper) this.fullDataSource.mapping.getBiomeWrapper(id); - int color = colorResolver.getColor(unwrapClientBiome(biomeWrapper.biome, this.clientLevelWrapper), mutableBlockPos.getX(), mutableBlockPos.getZ()); + int color = this.tryGetClientBiomeColor(colorResolver, biomeWrapper); + if (color == INVALID_COLOR) + { + return INVALID_COLOR; + } // rolling average @@ -131,7 +167,7 @@ public abstract class AbstractDhTintGetter implements BlockAndTintGetter // just use the default center's color if (dataPointCount == 0) { - return colorResolver.getColor(unwrapClientBiome(this.biomeWrapper.biome, this.clientLevelWrapper), blockPos.getX(), blockPos.getZ()); + return this.tryGetClientBiomeColor(colorResolver, this.biomeWrapper); } int colorInt = ColorUtil.argbToInt( @@ -142,14 +178,38 @@ public abstract class AbstractDhTintGetter implements BlockAndTintGetter return colorInt; } - protected static Biome unwrapClientBiome(#if MC_VER >= MC_1_18_2 Holder #else Biome #endif biome, IClientLevelWrapper clientLevelWrapper) + /** + * If given a ColorResolver this will always succeed.
+ * If not it will attempt to use the cached color. + */ + private int tryGetClientBiomeColor(@Nullable ColorResolver colorResolver, BiomeWrapper biomeWrapper) { - BiomeWrapper biomeWrapper = (BiomeWrapper)BiomeWrapper.getBiomeWrapper(biome, clientLevelWrapper); + // use the cached color if possible + int cachedColor = COLOR_BY_BIOME.getOrDefault(unwrapClientBiome(biomeWrapper), INVALID_COLOR); + if (cachedColor != INVALID_COLOR) + { + return cachedColor; + } + if (colorResolver == null) + { + // no color resolver is present, + // the cache needs to be populated before + // we can use the fast path + return INVALID_COLOR; + } + + return COLOR_BY_BIOME.computeIfAbsent(unwrapClientBiome(biomeWrapper), + // in James' testing the block position isn't needed so we can just default to (0,0) + (unwrappedBiome) -> colorResolver.getColor(unwrappedBiome, 0, 0)); + } + + protected static Biome unwrapClientBiome(BiomeWrapper biomeWrapper) + { String biomeString = biomeWrapper.getSerialString(); if (biomeString == null - || biomeString.isEmpty() - || biomeString.equals(BiomeWrapper.EMPTY_BIOME_STRING)) + || biomeString.isEmpty() + || biomeString.equals(BiomeWrapper.EMPTY_BIOME_STRING)) { // default to "plains" for empty/invalid biomes biomeString = "minecraft:plains"; @@ -203,6 +263,21 @@ public abstract class AbstractDhTintGetter implements BlockAndTintGetter */ private static #if MC_VER < MC_1_18_2 Biome #else Holder #endif getClientBiome(String biomeResourceString) { + #if MC_VER < MC_1_18_2 + Biome biome; + #else + Holder biome; + #endif + + // calling get instead of compute is slightly faster for already + // computed values + biome = BIOME_BY_RESOURCE_STRING.get(biomeResourceString); + if (biome != null) + { + return biome; + } + + // cache the client biomes so we don't have to re-parse the resource location every time return BIOME_BY_RESOURCE_STRING.compute(biomeResourceString, (resourceString, existingBiome) -> diff --git a/common/src/main/java/com/seibel/distanthorizons/common/wrappers/block/ClientBlockStateColorCache.java b/common/src/main/java/com/seibel/distanthorizons/common/wrappers/block/ClientBlockStateColorCache.java index 7978e6c17..2118b5f67 100644 --- a/common/src/main/java/com/seibel/distanthorizons/common/wrappers/block/ClientBlockStateColorCache.java +++ b/common/src/main/java/com/seibel/distanthorizons/common/wrappers/block/ClientBlockStateColorCache.java @@ -23,13 +23,13 @@ import com.seibel.distanthorizons.common.wrappers.McObjectConverter; import com.seibel.distanthorizons.core.dataObjects.fullData.sources.FullDataSourceV2; import com.seibel.distanthorizons.core.logging.DhLoggerBuilder; import com.seibel.distanthorizons.core.pos.blockPos.DhBlockPos; +import com.seibel.distanthorizons.core.pos.blockPos.DhBlockPosMutable; import com.seibel.distanthorizons.core.util.ColorUtil; import com.seibel.distanthorizons.core.wrapperInterfaces.world.IClientLevelWrapper; import net.minecraft.client.Minecraft; import net.minecraft.client.renderer.block.model.BakedQuad; import net.minecraft.client.renderer.texture.TextureAtlasSprite; import net.minecraft.core.Direction; -import net.minecraft.world.level.LevelReader; import net.minecraft.world.level.block.Block; import net.minecraft.world.level.block.FlowerBlock; import net.minecraft.world.level.block.LeavesBlock; @@ -64,8 +64,6 @@ public class ClientBlockStateColorCache { private static final DhLogger LOGGER = new DhLoggerBuilder().build(); - // TODO it isn't that we need the level, but that we need the adjacent data - // maybe we can pass in the full data source? private static final HashSet BLOCK_STATES_THAT_NEED_LEVEL = new HashSet<>(); private static final HashSet BROKEN_BLOCK_STATES = new HashSet<>(); @@ -95,14 +93,10 @@ public class ClientBlockStateColorCache #endif private final IClientLevelWrapper clientLevelWrapper; - private final BlockStateWrapper blockStateWrapper; - private final BlockState blockState; - private final LevelReader level; private boolean isColorResolved = false; private int baseColor = 0; - private boolean needShade = true; private boolean needPostTinting = false; private int tintIndex = 0; @@ -170,6 +164,9 @@ public class ClientBlockStateColorCache 0.93011117f, 0.9386859f, 0.9473069f, 0.9559735f, 0.9646866f, 0.9734455f, 0.98225087f, 0.9911022f, 1.0f }; + private static final ThreadLocal TintWithoutLevelOverrideGetter = ThreadLocal.withInitial(() -> new TintWithoutLevelOverrider()); + private static final ThreadLocal TintOverrideGetter = ThreadLocal.withInitial(() -> new TintGetterOverride()); + //=============// @@ -180,8 +177,6 @@ public class ClientBlockStateColorCache { this.blockState = blockState; this.clientLevelWrapper = samplingLevel; - this.level = (LevelReader) samplingLevel.getWrappedMcObject(); - this.blockStateWrapper = BlockStateWrapper.fromBlockState(this.blockState, this.clientLevelWrapper); this.resolveColors(); } @@ -235,32 +230,29 @@ public class ClientBlockStateColorCache this.needPostTinting = firstQuad.isTinted(); #if MC_VER <= MC_1_21_4 - this.needShade = firstQuad.isShade(); this.tintIndex = firstQuad.getTintIndex(); #else - this.needShade = firstQuad.shade(); this.tintIndex = firstQuad.tintIndex(); #endif #if MC_VER < MC_1_17_1 this.baseColor = calculateColorFromTexture( firstQuad.sprite, - ColorMode.getColorMode(this.blockState.getBlock())); + EColorMode.getColorMode(this.blockState.getBlock())); #elif MC_VER < MC_1_21_5 this.baseColor = calculateColorFromTexture( firstQuad.getSprite(), - ColorMode.getColorMode(this.blockState.getBlock())); + EColorMode.getColorMode(this.blockState.getBlock())); #else this.baseColor = calculateColorFromTexture( firstQuad.sprite(), - ColorMode.getColorMode(this.blockState.getBlock())); + EColorMode.getColorMode(this.blockState.getBlock())); #endif } else { // Backup method. this.needPostTinting = false; - this.needShade = false; this.tintIndex = 0; this.baseColor = this.getParticleIconColor(); } @@ -269,19 +261,11 @@ public class ClientBlockStateColorCache { // Liquid Block this.needPostTinting = true; - this.needShade = false; this.tintIndex = 0; this.baseColor = this.getParticleIconColor(); } - //String serialString = this.blockStateWrapper.getSerialString(); - //if (serialString.contains("minecraft:water") - // || serialString.contains("grass")) - //{ - // BLOCK_STATES_THAT_NEED_LEVEL.add(this.blockState); - //} - this.isColorResolved = true; } finally @@ -319,7 +303,7 @@ public class ClientBlockStateColorCache } //TODO: Perhaps make this not just use the first frame? - private static int calculateColorFromTexture(TextureAtlasSprite texture, ColorMode colorMode) + private static int calculateColorFromTexture(TextureAtlasSprite texture, EColorMode colorMode) { int count = 0; int alpha = 0; @@ -329,8 +313,8 @@ public class ClientBlockStateColorCache int tempColor; // don't render Chiseled blocks. - // Since ColorMode is set per block, you only need to check this once. - if (colorMode != ColorMode.Chisel) + // Since EColorMode is set per block, you only need to check this once. + if (colorMode != EColorMode.Chisel) { // textures normally use u and v instead of x and y for (int v = 0; v < getTextureHeight(texture); v++) @@ -348,7 +332,7 @@ public class ClientBlockStateColorCache int b = (tempColor & 0x00FF0000) >>> 16; int a = (tempColor & 0xFF000000) >>> 24; int scale = 1; - if (colorMode == ColorMode.Leaves) + if (colorMode == EColorMode.Leaves) { //switch (//FIXME add config option) // case BLACK: @@ -367,11 +351,11 @@ public class ClientBlockStateColorCache // break; //do nothing, let it count towards transparency } - else if (a == 0 && colorMode != ColorMode.Glass) + else if (a == 0 && colorMode != EColorMode.Glass) { continue; } - else if (colorMode == ColorMode.Flower && (g + 25 < b || g + 25 < r)) + else if (colorMode == EColorMode.Flower && (g + 25 < b || g + 25 < r)) { scale = FLOWER_COLOR_SCALE; } @@ -454,7 +438,7 @@ public class ClientBlockStateColorCache { return calculateColorFromTexture( Minecraft.getInstance().getModelManager().getBlockModelShaper().getParticleIcon(this.blockState), - ColorMode.getColorMode(this.blockState.getBlock())); + EColorMode.getColorMode(this.blockState.getBlock())); } @@ -463,7 +447,7 @@ public class ClientBlockStateColorCache // public getter // //===============// - public int getColor(BiomeWrapper biomeWrapper, FullDataSourceV2 fullDataSource, DhBlockPos pos) + public int getColor(BiomeWrapper biomeWrapper, FullDataSourceV2 fullDataSource, DhBlockPos blockPos) { // only get the tint if the block needs to be tinted if (!this.needPostTinting) @@ -487,16 +471,27 @@ public class ClientBlockStateColorCache { try { - tintColor = Minecraft.getInstance().getBlockColors() - .getColor(this.blockState, - new TintWithoutLevelOverrider(biomeWrapper, fullDataSource, this.clientLevelWrapper), // TODO can this object be cached? - McObjectConverter.Convert(pos), - this.tintIndex); + TintWithoutLevelOverrider tintOverride = TintWithoutLevelOverrideGetter.get(); + tintOverride.update(biomeWrapper, fullDataSource, this.clientLevelWrapper); + + // try using DH's cached tint values first if possible + tintColor = tintOverride.tryGetBlockTint(new DhBlockPosMutable(blockPos)); + if (tintColor == AbstractDhTintGetter.INVALID_COLOR) + { + // one or more tint values weren't calculated, + // we need MC's color resolver + tintColor = Minecraft.getInstance() + .getBlockColors() + .getColor(this.blockState, + tintOverride, + McObjectConverter.Convert(blockPos), + this.tintIndex); + } } catch (UnsupportedOperationException e) { // this exception generally occurs if the tint requires other blocks besides itself - LOGGER.debug("Unable to use ["+ TintWithoutLevelOverrider.class.getSimpleName()+"] to get the block tint for block: [" + this.blockState + "] and biome: [" + biomeWrapper + "] at pos: " + pos + ". Error: [" + e.getMessage() + "]. Attempting to use backup method...", e); + LOGGER.debug("Unable to use ["+ TintWithoutLevelOverrider.class.getSimpleName()+"] to get the block tint for block: [" + this.blockState + "] and biome: [" + biomeWrapper + "] at pos: " + blockPos + ". Error: [" + e.getMessage() + "]. Attempting to use backup method...", e); BLOCK_STATES_THAT_NEED_LEVEL.add(this.blockState); } } @@ -504,13 +499,22 @@ public class ClientBlockStateColorCache // use the level logic only if requested if (BLOCK_STATES_THAT_NEED_LEVEL.contains(this.blockState)) { - // this logic can't be used all the time due to it breaking some blocks tinting + // the level shouldn't be used all the time due to it breaking some blocks tinting // specifically oceans don't render correctly - tintColor = Minecraft.getInstance().getBlockColors() - .getColor(this.blockState, - new TintGetterOverride(this.level, biomeWrapper, fullDataSource, this.clientLevelWrapper), // TODO can this object be cached? - McObjectConverter.Convert(pos), - this.tintIndex); + + TintGetterOverride tintOverride = TintOverrideGetter.get(); + tintOverride.update(biomeWrapper, fullDataSource, this.clientLevelWrapper); + + tintColor = tintOverride.tryGetBlockTint(new DhBlockPosMutable(blockPos)); + if (tintColor == AbstractDhTintGetter.INVALID_COLOR) + { + tintColor = Minecraft.getInstance() + .getBlockColors() + .getColor(this.blockState, + tintOverride, + McObjectConverter.Convert(blockPos), + this.tintIndex); + } } } catch (Exception e) @@ -518,7 +522,7 @@ public class ClientBlockStateColorCache // only display the error once per block/biome type to reduce log spam if (!BROKEN_BLOCK_STATES.contains(this.blockState)) { - LOGGER.warn("Failed to get block color for block: [" + this.blockState + "] and biome: [" + biomeWrapper + "] at pos: " + pos + ". Error: ["+e.getMessage() + "]. Note: future errors for this block/biome will be ignored.", e); + LOGGER.warn("Failed to get block color for block: [" + this.blockState + "] and biome: [" + biomeWrapper + "] at pos: " + blockPos + ". Error: ["+e.getMessage() + "]. Note: future errors for this block/biome will be ignored.", e); BROKEN_BLOCK_STATES.add(this.blockState); } } @@ -542,7 +546,7 @@ public class ClientBlockStateColorCache // helper classes // //================// - enum ColorMode + private enum EColorMode { Default, Flower, @@ -550,7 +554,7 @@ public class ClientBlockStateColorCache Chisel, Glass; - static ColorMode getColorMode(Block block) + static EColorMode getColorMode(Block block) { if (block instanceof LeavesBlock) return Leaves; if (block instanceof FlowerBlock) return Flower; diff --git a/common/src/main/java/com/seibel/distanthorizons/common/wrappers/block/TintGetterOverride.java b/common/src/main/java/com/seibel/distanthorizons/common/wrappers/block/TintGetterOverride.java index b7fa2437b..3a26bdf62 100644 --- a/common/src/main/java/com/seibel/distanthorizons/common/wrappers/block/TintGetterOverride.java +++ b/common/src/main/java/com/seibel/distanthorizons/common/wrappers/block/TintGetterOverride.java @@ -41,7 +41,7 @@ import java.util.stream.Stream; public class TintGetterOverride extends AbstractDhTintGetter { - private final LevelReader parent; + private LevelReader parent; @@ -49,9 +49,11 @@ public class TintGetterOverride extends AbstractDhTintGetter // constructor // //=============// - public TintGetterOverride(LevelReader parent, BiomeWrapper biomeWrapper, FullDataSourceV2 fullDataSource, IClientLevelWrapper clientLevelWrapper) - { - super(biomeWrapper, fullDataSource, clientLevelWrapper); + public TintGetterOverride() { } + + public void update(LevelReader parent, BiomeWrapper biomeWrapper, FullDataSourceV2 fullDataSource, IClientLevelWrapper clientLevelWrapper) + { + super.update(biomeWrapper, fullDataSource, clientLevelWrapper); this.parent = parent; } diff --git a/common/src/main/java/com/seibel/distanthorizons/common/wrappers/block/TintWithoutLevelOverrider.java b/common/src/main/java/com/seibel/distanthorizons/common/wrappers/block/TintWithoutLevelOverrider.java index 1172b5fcd..a613bed4f 100644 --- a/common/src/main/java/com/seibel/distanthorizons/common/wrappers/block/TintWithoutLevelOverrider.java +++ b/common/src/main/java/com/seibel/distanthorizons/common/wrappers/block/TintWithoutLevelOverrider.java @@ -23,6 +23,7 @@ import com.seibel.distanthorizons.core.dataObjects.fullData.sources.FullDataSour import com.seibel.distanthorizons.core.wrapperInterfaces.world.IClientLevelWrapper; import net.minecraft.core.BlockPos; import net.minecraft.core.Direction; +import net.minecraft.world.level.LevelReader; import net.minecraft.world.level.block.entity.BlockEntity; import net.minecraft.world.level.block.state.BlockState; import net.minecraft.world.level.lighting.LevelLightEngine; @@ -36,8 +37,8 @@ public class TintWithoutLevelOverrider extends AbstractDhTintGetter // constructor // //=============// - public TintWithoutLevelOverrider(BiomeWrapper biomeWrapper, FullDataSourceV2 fullDataSource, IClientLevelWrapper clientLevelWrapper) - { super(biomeWrapper, fullDataSource, clientLevelWrapper); } + public TintWithoutLevelOverrider() + { } diff --git a/common/src/main/java/com/seibel/distanthorizons/common/wrappers/world/ClientLevelWrapper.java b/common/src/main/java/com/seibel/distanthorizons/common/wrappers/world/ClientLevelWrapper.java index 9847c05d6..e734fa846 100644 --- a/common/src/main/java/com/seibel/distanthorizons/common/wrappers/world/ClientLevelWrapper.java +++ b/common/src/main/java/com/seibel/distanthorizons/common/wrappers/world/ClientLevelWrapper.java @@ -64,10 +64,10 @@ public class ClientLevelWrapper implements IClientLevelWrapper private static final Minecraft MINECRAFT = Minecraft.getInstance(); private final ClientLevel level; - private final ConcurrentHashMap blockCache = new ConcurrentHashMap<>(); + private final ConcurrentHashMap blockColorCacheByBlockState = new ConcurrentHashMap<>(); /** cached method reference to reduce GC overhead */ - private final Function cachedBlockColorCacheFunction = (blockState) -> this.createBlockColorCache(blockState); + private final Function createCachedBlockColorCacheFunc = (blockState) -> new ClientBlockStateColorCache(blockState, this); private BlockStateWrapper dirtBlockWrapper; @@ -201,14 +201,12 @@ public class ClientLevelWrapper implements IClientLevelWrapper @Override public int getBlockColor(DhBlockPos pos, IBiomeWrapper biome, FullDataSourceV2 fullDataSource, IBlockStateWrapper blockWrapper) { - ClientBlockStateColorCache blockColorCache = this.blockCache.computeIfAbsent( + ClientBlockStateColorCache blockColorCache = this.blockColorCacheByBlockState.computeIfAbsent( ((BlockStateWrapper) blockWrapper).blockState, - this.cachedBlockColorCacheFunction); + this.createCachedBlockColorCacheFunc); return blockColorCache.getColor((BiomeWrapper) biome, fullDataSource, pos); } - /** used by {@link ClientLevelWrapper#cachedBlockColorCacheFunction} */ - private ClientBlockStateColorCache createBlockColorCache(BlockState block) { return new ClientBlockStateColorCache(block, this); } @Override @@ -232,7 +230,7 @@ public class ClientLevelWrapper implements IClientLevelWrapper } @Override - public void clearBlockColorCache() { this.blockCache.clear(); } + public void clearBlockColorCache() { this.blockColorCacheByBlockState.clear(); } @Override public IDimensionTypeWrapper getDimensionType() { return DimensionTypeWrapper.getDimensionTypeWrapper(this.level.dimensionType()); } diff --git a/coreSubProjects b/coreSubProjects index 3e7f160fc..0d5c454dd 160000 --- a/coreSubProjects +++ b/coreSubProjects @@ -1 +1 @@ -Subproject commit 3e7f160fcd2641f179fca386e457491bbbfbb370 +Subproject commit 0d5c454dd4d8d941b9ae21b4ec9d2bdadeac273a