remove a concurrent modification exception when changing effects

This commit is contained in:
Ellpeck 2018-11-18 19:49:30 +01:00
parent b59245aa3c
commit a54ea5b989
3 changed files with 32 additions and 23 deletions

View file

@ -19,10 +19,7 @@ import org.apache.commons.lang3.mutable.MutableInt;
import javax.annotation.Nonnull; import javax.annotation.Nonnull;
import javax.annotation.Nullable; import javax.annotation.Nullable;
import java.util.ArrayList; import java.util.*;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.function.BiConsumer; import java.util.function.BiConsumer;
import java.util.function.Supplier; import java.util.function.Supplier;
@ -57,19 +54,17 @@ public class AuraChunk implements IAuraChunk {
@Override @Override
public void drainAura(BlockPos pos, int amount) { public void drainAura(BlockPos pos, int amount) {
MutableInt spot = this.getDrainSpot(pos); if (amount <= 0)
spot.subtract(amount); return;
if (spot.intValue() == 0) this.getDrainSpot(pos).subtract(amount);
this.drainSpots.remove(pos);
this.markDirty(); this.markDirty();
} }
@Override @Override
public void storeAura(BlockPos pos, int amount) { public void storeAura(BlockPos pos, int amount) {
MutableInt spot = this.getDrainSpot(pos); if (amount <= 0)
spot.add(amount); return;
if (spot.intValue() == 0) this.getDrainSpot(pos).add(amount);
this.drainSpots.remove(pos);
this.markDirty(); this.markDirty();
} }
@ -100,20 +95,34 @@ public class AuraChunk implements IAuraChunk {
public void update() { public void update() {
World world = this.chunk.getWorld(); World world = this.chunk.getWorld();
Set<BlockPos> toClear = null;
for (Map.Entry<BlockPos, MutableInt> entry : this.drainSpots.entrySet()) {
BlockPos pos = entry.getKey();
MutableInt amount = entry.getValue();
for (IDrainSpotEffect effect : this.effects) {
world.profiler.func_194340_a(() -> effect.getName().toString());
effect.update(world, this.chunk, this, pos, amount);
world.profiler.endSection();
}
if (amount.intValue() == 0) {
if (toClear == null)
toClear = new HashSet<>();
toClear.add(pos);
}
}
if (toClear != null) {
for (BlockPos spot : toClear)
this.drainSpots.remove(spot);
this.markDirty();
}
if (this.needsSync) { if (this.needsSync) {
PacketHandler.sendToAllLoaded(world, PacketHandler.sendToAllLoaded(world,
new BlockPos(this.chunk.x * 16, 0, this.chunk.z * 16), new BlockPos(this.chunk.x * 16, 0, this.chunk.z * 16),
this.makePacket()); this.makePacket());
this.needsSync = false; this.needsSync = false;
} }
for (Map.Entry<BlockPos, MutableInt> entry : this.drainSpots.entrySet()) {
for (IDrainSpotEffect effect : this.effects) {
world.profiler.func_194340_a(() -> effect.getName().toString());
effect.update(world, this.chunk, this, entry.getKey(), entry.getValue());
world.profiler.endSection();
}
}
} }
public IMessage makePacket() { public IMessage makePacket() {

View file

@ -10,9 +10,9 @@ import net.minecraft.world.World;
import net.minecraft.world.chunk.Chunk; import net.minecraft.world.chunk.Chunk;
import org.apache.commons.lang3.mutable.MutableInt; import org.apache.commons.lang3.mutable.MutableInt;
public class MigrationEffect implements IDrainSpotEffect { public class BalanceEffect implements IDrainSpotEffect {
public static final ResourceLocation NAME = new ResourceLocation(NaturesAura.MOD_ID, "migration"); public static final ResourceLocation NAME = new ResourceLocation(NaturesAura.MOD_ID, "balance");
@Override @Override
public void update(World world, Chunk chunk, IAuraChunk auraChunk, BlockPos pos, MutableInt spot) { public void update(World world, Chunk chunk, IAuraChunk auraChunk, BlockPos pos, MutableInt spot) {

View file

@ -8,6 +8,6 @@ public final class DrainSpotEffects {
NaturesAuraAPI.DRAIN_SPOT_EFFECTS.put(GrassDieEffect.NAME, GrassDieEffect::new); NaturesAuraAPI.DRAIN_SPOT_EFFECTS.put(GrassDieEffect.NAME, GrassDieEffect::new);
NaturesAuraAPI.DRAIN_SPOT_EFFECTS.put(PlantBoostEffect.NAME, PlantBoostEffect::new); NaturesAuraAPI.DRAIN_SPOT_EFFECTS.put(PlantBoostEffect.NAME, PlantBoostEffect::new);
NaturesAuraAPI.DRAIN_SPOT_EFFECTS.put(ReplenishingEffect.NAME, ReplenishingEffect::new); NaturesAuraAPI.DRAIN_SPOT_EFFECTS.put(ReplenishingEffect.NAME, ReplenishingEffect::new);
NaturesAuraAPI.DRAIN_SPOT_EFFECTS.put(MigrationEffect.NAME, MigrationEffect::new); NaturesAuraAPI.DRAIN_SPOT_EFFECTS.put(BalanceEffect.NAME, BalanceEffect::new);
} }
} }