[1.16] Fix possible crash when using rendering regionCache (#7207)

This commit is contained in:
Nightenom 2020-09-22 20:58:19 +02:00 committed by GitHub
parent 91dda36b08
commit b1247df4dc
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
2 changed files with 15 additions and 6 deletions

View file

@ -23,10 +23,12 @@ import java.io.IOException;
import java.util.BitSet; import java.util.BitSet;
import java.util.HashMap; import java.util.HashMap;
import java.util.Locale; import java.util.Locale;
import java.util.Optional;
import java.util.concurrent.TimeUnit; import java.util.concurrent.TimeUnit;
import java.util.function.Supplier; import java.util.function.Supplier;
import javax.annotation.Nonnull; import javax.annotation.Nonnull;
import javax.annotation.Nullable;
import net.minecraft.client.renderer.RenderType; import net.minecraft.client.renderer.RenderType;
import org.apache.commons.lang3.tuple.Pair; import org.apache.commons.lang3.tuple.Pair;
@ -97,16 +99,16 @@ public class MinecraftForgeClient
} }
} }
private static final LoadingCache<Pair<World, BlockPos>, ChunkRenderCache> regionCache = CacheBuilder.newBuilder() private static final LoadingCache<Pair<World, BlockPos>, Optional<ChunkRenderCache>> regionCache = CacheBuilder.newBuilder()
.maximumSize(500) .maximumSize(500)
.concurrencyLevel(5) .concurrencyLevel(5)
.expireAfterAccess(1, TimeUnit.SECONDS) .expireAfterAccess(1, TimeUnit.SECONDS)
.build(new CacheLoader<Pair<World, BlockPos>, ChunkRenderCache>() .build(new CacheLoader<Pair<World, BlockPos>, Optional<ChunkRenderCache>>()
{ {
@Override @Override
public ChunkRenderCache load(Pair<World, BlockPos> key) public Optional<ChunkRenderCache> load(Pair<World, BlockPos> key)
{ {
return ChunkRenderCache.generateCache(key.getLeft(), key.getRight().add(-1, -1, -1), key.getRight().add(16, 16, 16), 1); return Optional.ofNullable(ChunkRenderCache.generateCache(key.getLeft(), key.getRight().add(-1, -1, -1), key.getRight().add(16, 16, 16), 1));
} }
}); });
@ -115,10 +117,16 @@ public class MinecraftForgeClient
if (cache == null) if (cache == null)
regionCache.invalidate(Pair.of(world, position)); regionCache.invalidate(Pair.of(world, position));
else else
regionCache.put(Pair.of(world, position), cache); regionCache.put(Pair.of(world, position), Optional.of(cache));
} }
@Nullable
public static ChunkRenderCache getRegionRenderCache(World world, BlockPos pos) public static ChunkRenderCache getRegionRenderCache(World world, BlockPos pos)
{
return getRegionRenderCacheOptional(world, pos).orElse(null);
}
public static Optional<ChunkRenderCache> getRegionRenderCacheOptional(World world, BlockPos pos)
{ {
int x = pos.getX() & ~0xF; int x = pos.getX() & ~0xF;
int y = pos.getY() & ~0xF; int y = pos.getY() & ~0xF;

View file

@ -66,7 +66,8 @@ public class TileEntityRendererAnimation<T extends TileEntity> extends TileEntit
} }
if(blockRenderer == null) blockRenderer = Minecraft.getInstance().getBlockRendererDispatcher(); if(blockRenderer == null) blockRenderer = Minecraft.getInstance().getBlockRendererDispatcher();
BlockPos pos = te.getPos(); BlockPos pos = te.getPos();
IBlockDisplayReader world = MinecraftForgeClient.getRegionRenderCache(te.getWorld(), pos); IBlockDisplayReader world = MinecraftForgeClient.getRegionRenderCacheOptional(te.getWorld(), pos)
.map(IBlockDisplayReader.class::cast).orElseGet(() -> te.getWorld());
BlockState state = world.getBlockState(pos); BlockState state = world.getBlockState(pos);
IBakedModel model = blockRenderer.getBlockModelShapes().getModel(state); IBakedModel model = blockRenderer.getBlockModelShapes().getModel(state);
IModelData data = model.getModelData(world, pos, state, ModelDataManager.getModelData(te.getWorld(), pos)); IModelData data = model.getModelData(world, pos, state, ModelDataManager.getModelData(te.getWorld(), pos));