Improved Thread safety (may help with #394)

This commit is contained in:
Frank 2022-01-28 17:13:34 +01:00
parent 2ef8fd08af
commit 755a0ad7ab
14 changed files with 46 additions and 19 deletions

View file

@ -17,12 +17,12 @@ import ru.betterend.interfaces.FallFlyingItem;
import ru.betterend.registry.EndBlockEntities;
import ru.betterend.registry.EndBlocks;
import ru.betterend.registry.EndParticles;
import ru.betterend.util.GlobalState;
import java.util.List;
public class BlockEntityHydrothermalVent extends BlockEntity {
private final static Vec3 POSITIVE_Y = new Vec3(0.0f, 1.0f, 0.0f);
private static final MutableBlockPos POS = new MutableBlockPos();
public BlockEntityHydrothermalVent(BlockPos blockPos, BlockState blockState) {
super(EndBlockEntities.HYDROTHERMAL_VENT, blockPos, blockState);
@ -51,6 +51,7 @@ public class BlockEntityHydrothermalVent extends BlockEntity {
}
private static void serverTick(Level level, BlockPos worldPosition, BlockState state, BlockEntityHydrothermalVent blockEntity) {
final MutableBlockPos POS = GlobalState.stateForThread().POS;
boolean active = state.getValue(HydrothermalVentBlock.ACTIVATED);
POS.set(worldPosition).move(Direction.UP);
int height = active ? 85 : 25;

View file

@ -40,6 +40,7 @@ import ru.bclib.util.MHelper;
import ru.bclib.world.biomes.BCLBiome;
import ru.betterend.interfaces.ISlime;
import ru.betterend.registry.EndBiomes;
import ru.betterend.util.GlobalState;
import java.util.EnumSet;
import java.util.Random;
@ -49,7 +50,6 @@ public class EndSlimeEntity extends Slime {
EndSlimeEntity.class,
EntityDataSerializers.BYTE
);
private static final MutableBlockPos POS = new MutableBlockPos();
public EndSlimeEntity(EntityType<EndSlimeEntity> entityType, Level world) {
super(entityType, world);
@ -227,6 +227,8 @@ public class EndSlimeEntity extends Slime {
}
private static boolean isWaterNear(LevelAccessor world, BlockPos pos) {
final MutableBlockPos POS = GlobalState.stateForThread().POS;
for (int x = pos.getX() - 32; x <= pos.getX() + 32; x++) {
POS.setX(x);
for (int z = pos.getZ() - 32; z <= pos.getZ() + 32; z++) {

View file

@ -0,0 +1,15 @@
package ru.betterend.util;
import net.minecraft.core.BlockPos.MutableBlockPos;
import java.util.concurrent.ConcurrentHashMap;
public class GlobalState {
private static final ConcurrentHashMap<Thread, GlobalState> statePool = new ConcurrentHashMap<>();
public static void clearStatePool(){
statePool.clear();
}
public static GlobalState stateForThread() { return statePool.computeIfAbsent(Thread.currentThread(), t-> new GlobalState()); }
public final MutableBlockPos POS = new MutableBlockPos();
}

View file

@ -9,11 +9,11 @@ import net.minecraft.world.level.levelgen.feature.configurations.NoneFeatureConf
import ru.bclib.util.BlocksHelper;
import ru.bclib.util.MHelper;
import ru.bclib.world.features.DefaultFeature;
import ru.betterend.util.GlobalState;
import java.util.Random;
public abstract class FullHeightScatterFeature extends DefaultFeature {
private static final MutableBlockPos POS = new MutableBlockPos();
private final int radius;
public FullHeightScatterFeature(int radius) {
@ -26,6 +26,7 @@ public abstract class FullHeightScatterFeature extends DefaultFeature {
@Override
public boolean place(FeaturePlaceContext<NoneFeatureConfiguration> featureConfig) {
final MutableBlockPos POS = GlobalState.stateForThread().POS;
final Random random = featureConfig.random();
final BlockPos center = featureConfig.origin();
final WorldGenLevel world = featureConfig.level();

View file

@ -9,11 +9,11 @@ import net.minecraft.world.level.levelgen.feature.configurations.NoneFeatureConf
import ru.bclib.util.BlocksHelper;
import ru.bclib.util.MHelper;
import ru.bclib.world.features.DefaultFeature;
import ru.betterend.util.GlobalState;
import java.util.Random;
public abstract class InvertedScatterFeature extends DefaultFeature {
private static final MutableBlockPos POS = new MutableBlockPos();
private final int radius;
public InvertedScatterFeature(int radius) {
@ -26,6 +26,7 @@ public abstract class InvertedScatterFeature extends DefaultFeature {
@Override
public boolean place(FeaturePlaceContext<NoneFeatureConfiguration> featureConfig) {
final MutableBlockPos POS = GlobalState.stateForThread().POS;
final Random random = featureConfig.random();
final BlockPos center = featureConfig.origin();
final WorldGenLevel world = featureConfig.level();

View file

@ -9,11 +9,11 @@ import ru.bclib.api.tag.CommonBlockTags;
import ru.bclib.util.BlocksHelper;
import ru.bclib.util.MHelper;
import ru.bclib.world.features.DefaultFeature;
import ru.betterend.util.GlobalState;
import java.util.Random;
public abstract class ScatterFeature extends DefaultFeature {
private static final MutableBlockPos POS = new MutableBlockPos();
private final int radius;
public ScatterFeature(int radius) {
@ -57,6 +57,7 @@ public abstract class ScatterFeature extends DefaultFeature {
@Override
public boolean place(FeaturePlaceContext<NoneFeatureConfiguration> featureConfig) {
final MutableBlockPos POS = GlobalState.stateForThread().POS;
final Random random = featureConfig.random();
BlockPos center = featureConfig.origin();
final WorldGenLevel world = featureConfig.level();

View file

@ -14,12 +14,11 @@ import ru.bclib.blocks.BlockProperties;
import ru.bclib.util.BlocksHelper;
import ru.bclib.world.features.DefaultFeature;
import ru.betterend.registry.EndBlocks;
import ru.betterend.util.GlobalState;
import java.util.Random;
public class SilkMothNestFeature extends DefaultFeature {
private static final MutableBlockPos POS = new MutableBlockPos();
private boolean canGenerate(WorldGenLevel world, BlockPos pos) {
BlockState state = world.getBlockState(pos.above());
if (state.is(BlockTags.LEAVES) || state.is(BlockTags.LOGS)) {
@ -35,6 +34,7 @@ public class SilkMothNestFeature extends DefaultFeature {
@Override
public boolean place(FeaturePlaceContext<NoneFeatureConfiguration> featureConfig) {
final MutableBlockPos POS = GlobalState.stateForThread().POS;
final Random random = featureConfig.random();
final BlockPos center = featureConfig.origin();
final WorldGenLevel world = featureConfig.level();

View file

@ -4,18 +4,18 @@ import net.minecraft.core.BlockPos;
import net.minecraft.core.BlockPos.MutableBlockPos;
import net.minecraft.world.level.WorldGenLevel;
import net.minecraft.world.level.block.Blocks;
import ru.betterend.util.GlobalState;
import java.util.Random;
public abstract class UnderwaterPlantScatter extends ScatterFeature {
private static final MutableBlockPos POS = new MutableBlockPos();
public UnderwaterPlantScatter(int radius) {
super(radius);
}
@Override
protected BlockPos getCenterGround(WorldGenLevel world, BlockPos pos) {
final MutableBlockPos POS = GlobalState.stateForThread().POS;
POS.setX(pos.getX());
POS.setZ(pos.getZ());
POS.setY(0);

View file

@ -16,6 +16,7 @@ import ru.bclib.world.features.DefaultFeature;
import ru.betterend.noise.OpenSimplexNoise;
import ru.betterend.registry.EndBlocks;
import ru.betterend.util.BlockFixer;
import ru.betterend.util.GlobalState;
import ru.betterend.world.biome.EndBiome;
import java.util.Random;
@ -23,10 +24,11 @@ import java.util.Random;
public class DesertLakeFeature extends DefaultFeature {
private static final BlockState END_STONE = Blocks.END_STONE.defaultBlockState();
private static final OpenSimplexNoise NOISE = new OpenSimplexNoise(15152);
private static final MutableBlockPos POS = new MutableBlockPos();
@Override
public boolean place(FeaturePlaceContext<NoneFeatureConfiguration> featureConfig) {
final MutableBlockPos POS = GlobalState.stateForThread().POS;
final Random random = featureConfig.random();
BlockPos blockPos = featureConfig.origin();
final WorldGenLevel world = featureConfig.level();

View file

@ -16,6 +16,7 @@ import ru.bclib.world.features.DefaultFeature;
import ru.betterend.noise.OpenSimplexNoise;
import ru.betterend.registry.EndBlocks;
import ru.betterend.util.BlockFixer;
import ru.betterend.util.GlobalState;
import ru.betterend.world.biome.EndBiome;
import java.util.Random;
@ -23,14 +24,13 @@ import java.util.Random;
public class EndLakeFeature extends DefaultFeature {
private static final BlockState END_STONE = Blocks.END_STONE.defaultBlockState();
private static final OpenSimplexNoise NOISE = new OpenSimplexNoise(15152);
private static final MutableBlockPos POS = new MutableBlockPos();
public EndLakeFeature(){
}
@Override
public boolean place(FeaturePlaceContext<NoneFeatureConfiguration> featureConfig) {
final MutableBlockPos POS = GlobalState.stateForThread().POS;
final Random random = featureConfig.random();
BlockPos blockPos = featureConfig.origin();
final WorldGenLevel world = featureConfig.level();

View file

@ -18,17 +18,16 @@ import ru.betterend.blocks.EndBlockProperties;
import ru.betterend.blocks.SulphurCrystalBlock;
import ru.betterend.noise.OpenSimplexNoise;
import ru.betterend.registry.EndBlocks;
import ru.betterend.util.GlobalState;
import java.util.Random;
import java.util.Set;
public class SulphuricLakeFeature extends DefaultFeature {
private static final OpenSimplexNoise NOISE = new OpenSimplexNoise(15152);
private static final MutableBlockPos POS = new MutableBlockPos();
@Override
public boolean place(FeaturePlaceContext<NoneFeatureConfiguration> featureConfig) {
final Random random = featureConfig.random();
BlockPos blockPos = featureConfig.origin();
final WorldGenLevel world = featureConfig.level();
blockPos = getPosOnSurfaceWG(world, blockPos);
@ -37,6 +36,8 @@ public class SulphuricLakeFeature extends DefaultFeature {
return false;
}
final Random random = featureConfig.random();
final MutableBlockPos POS = GlobalState.stateForThread().POS;
double radius = MHelper.randRange(10.0, 20.0, random);
int dist2 = MHelper.floor(radius * 1.5);
@ -75,6 +76,7 @@ public class SulphuricLakeFeature extends DefaultFeature {
else {
if (!isAbsoluteBorder(world, POS)) {
BlocksHelper.setWithoutUpdate(world, POS, Blocks.WATER);
//world.setBlock(blockPos, Blocks.WATER.defaultBlockState(), 2);
world.scheduleTick(POS, Fluids.WATER, 0);
brimstone.add(POS.below());
if (random.nextBoolean()) {

View file

@ -16,6 +16,7 @@ import ru.bclib.util.BlocksHelper;
import ru.bclib.util.MHelper;
import ru.betterend.noise.OpenSimplexNoise;
import ru.betterend.registry.EndStructures;
import ru.betterend.util.GlobalState;
import java.util.Random;
@ -49,7 +50,7 @@ public class CavePiece extends BasePiece {
double hr = radius * 0.75;
double nr = radius * 0.25;
MutableBlockPos pos = new MutableBlockPos();
final MutableBlockPos pos = GlobalState.stateForThread().POS;
for (int x = x1; x <= x2; x++) {
int xsq = x - center.getX();
xsq *= xsq;

View file

@ -16,12 +16,12 @@ import net.minecraft.world.level.levelgen.Heightmap;
import net.minecraft.world.level.levelgen.Heightmap.Types;
import net.minecraft.world.level.levelgen.structure.BoundingBox;
import net.minecraft.world.level.levelgen.structure.pieces.StructurePieceSerializationContext;
import ru.bclib.api.tag.CommonBlockTags;
import ru.bclib.api.tag.TagAPI;
import ru.bclib.api.biomes.BiomeAPI;
import ru.bclib.api.tag.CommonBlockTags;
import ru.bclib.util.MHelper;
import ru.betterend.registry.EndBlocks;
import ru.betterend.registry.EndStructures;
import ru.betterend.util.GlobalState;
import ru.betterend.world.biome.EndBiome;
import java.util.Random;
@ -48,7 +48,7 @@ public class CrystalMountainPiece extends MountainPiece {
public void postProcess(WorldGenLevel world, StructureFeatureManager arg, ChunkGenerator chunkGenerator, Random random, BoundingBox blockBox, ChunkPos chunkPos, BlockPos blockPos) {
int sx = chunkPos.getMinBlockX();
int sz = chunkPos.getMinBlockZ();
MutableBlockPos pos = new MutableBlockPos();
final MutableBlockPos pos = GlobalState.stateForThread().POS;
ChunkAccess chunk = world.getChunk(chunkPos.x, chunkPos.z);
Heightmap map = chunk.getOrCreateHeightmapUnprimed(Types.WORLD_SURFACE);
Heightmap map2 = chunk.getOrCreateHeightmapUnprimed(Types.WORLD_SURFACE_WG);

View file

@ -18,6 +18,7 @@ import net.minecraft.world.level.levelgen.structure.BoundingBox;
import net.minecraft.world.level.levelgen.structure.pieces.StructurePieceSerializationContext;
import ru.bclib.util.MHelper;
import ru.betterend.registry.EndStructures;
import ru.betterend.util.GlobalState;
import java.util.Random;
@ -57,7 +58,7 @@ public class PaintedMountainPiece extends MountainPiece {
public void postProcess(WorldGenLevel world, StructureFeatureManager arg, ChunkGenerator chunkGenerator, Random random, BoundingBox blockBox, ChunkPos chunkPos, BlockPos blockPos) {
int sx = chunkPos.getMinBlockX();
int sz = chunkPos.getMinBlockZ();
MutableBlockPos pos = new MutableBlockPos();
final MutableBlockPos pos = GlobalState.stateForThread().POS;
ChunkAccess chunk = world.getChunk(chunkPos.x, chunkPos.z);
Heightmap map = chunk.getOrCreateHeightmapUnprimed(Types.WORLD_SURFACE);
Heightmap map2 = chunk.getOrCreateHeightmapUnprimed(Types.WORLD_SURFACE_WG);